2016-09-03 7 views
0

この問題をスケジューリングアプリケーションとしましょう。ユーザーは、時間帯の時間帯(「America/New_York」の「8am」)を指定してから、予約を取ります。 (最大時間に関しても同様の制約があります)UTCタイムスタンプがタイムゾーン内の時間範囲内にあるかどうかを確認しますか?

到着予定の要求(UTC時間では2016-09-07 03:00:00)がある場合、どのユーザーが予定を取ることができるかを判断する必要があります。

UTCタイムスタンプが2つのタイムゾーンを調整した時間の間にあるかどうかを確認するにはどうすればよいですか?

私のアプローチは、時間部分を抽出し、時間的制約と比較し、ユーザのタイムゾーンに入ってくるタイムスタンプを変換することであった:

SELECT * FROM users u WHERE 
    ('2016-09-07 03:00:00' AT TIME ZONE u.timezone)::time >= u.earliest_start_time AND 
    ('2016-09-07 03:00:00' AT TIME ZONE u.timezone)::time <= u.latest_stop_time 

earliest_start_timelatest_stop_timetime without time zoneである; timezoneでありますOlson tz string)

タイムゾーンのオフセットによって日が引き継がれるため、あらゆる種類の奇妙な動作がありますが、私はこれを一般的に非常に混乱させています。

+1

ローカルタイムスタンプがあいまいである可能性があるため、必ずしもそうである必要はありません。たとえば、ユーザーが2016-11-06T01:30ニューヨーク時間で終了するローカル範囲を与えたとします。その前か後に2016-11-05T21:45がありますか? 11月6日にニューヨークで午前1時30分に発生したのですが、午前1時30分に発生します。最初の出現であるか、2番目の出現です...そして、ユーザーが午前1時30分に言うが、スキップされた他の状況に対処してください... –

+0

'earliest_start_time'と' latest_stop_time'のタイプは何ですか?それは日付情報を含んでいますか、それともちょうど時刻ですか? – redneb

+0

ああ。分かったと思います。最小と最大の制約があることを考えれば、私は夜間に範囲を意味するという仮定をクエリにエンコードしなければならないでしょうか? –

答えて

2

下位のコードを作成するには、プレースホルダー$1には、タイプtimestamp with time zoneの値が格納されているとします。

SELECT * FROM users u WHERE 
    $1 BETWEEN 
     ($1::date || ' ' || u.earliest_start_time)::timestamp without time zone AT TIME ZONE u.timezone 
    AND 
     ($1::date || ' ' || u.latest_stop_time)::timestamp without time zone AT TIME ZONE u.timezone; 

説明:そして、次のクエリでは、その時点で利用可能なすべてのユーザーを検索します、我々はtimestamp with time zoneであり、我々はdateにそれをキャストタイプによってのみ、日付部分を保つた$1を取ります。それから、時間であるearliest_start_timeを取り、前の日付と組み合わせると、(まだ)タイムゾーン情報を持たないフルタイムスタンプが取得されます。次に、それを変換するタイムゾーンをtimestamp with time zoneに指定します。 latest_stop_timeについても同じことを行います。だから我々はこれらの値を見つけたので、同じタイプの$1と比較することができます。

これはあいまいなタイムスタンプで問題が発生します(つまり、DSTから標準時への移行時)。ただし、回避することはできません。あなたが典型的な営業時間だけにそれを使用する場合、それは大丈夫かもしれません。

関連する問題