2016-09-03 1 views
0

Lassen Sie uns dieses Problem als eine Scheduling-Anwendung einrahmen. Benutzer geben eine Mindestzeit in ihrer Zeitzone ("8am" in "America/New_York") an, nach der sie bereit sind, Termine zu nehmen. (Wir haben auch eine ähnliche Beschränkung für die maximale Zeit)Ermitteln, ob ein UTC-Zeitstempel innerhalb eines Zeitbereichs in einer Zeitzone liegt?

Angesichts einer eingehenden Terminanfrage (sagen wir für 2016-09-07 03:00:00 in UTC-Zeit), müssen wir ermitteln, welche Benutzer den Termin nehmen können.

Wie können wir feststellen, ob ein UTC-Zeitstempel zwischen zwei Zeitzonen-angepassten Zeiten liegt?

Mein Ansatz war, den eingehenden Zeitstempel des Benutzers Zeitzone zu konvertieren, den Zeitanteil zu extrahieren und zu dem Zeitdruck vergleichen:

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_time und latest_stop_time von time without time zone Typ sind; timezone ist ein Olson TZ String)

Es gibt alle Arten von seltsamen Verhalten als Zeitzone Offsets Ursachen Tage zu überrollen und ich bin nur allgemein sehr verwirrt und verschwommen über dies.

+1

Sie können nicht unbedingt, weil ein lokaler Zeitstempel mehrdeutig sein kann. Angenommen, Ihr Benutzer gibt Ihnen einen lokalen Bereich mit der Endung 2016-11-06T01: 30 New Yorker Zeit. Jetzt ist 2016-11-05T21: 45 davor oder danach? Es ist nach dem * ersten * Vorfall von 1:30 Uhr in New York am 6. November, aber es ist vor dem * zweiten * Vorkommen von 1:30 Uhr morgens ... Grundsätzlich müssen Sie wissen, ob die "1:30 Uhr" vom Benutzer gegeben wird ist das erste oder zweite Vorkommen ... und bewältigen die andere Situation, wo der Benutzer 1:30 Uhr sagt, aber das wurde übersprungen ... –

+0

Was ist der Typ von 'früheste_Start_Zeit' und' neueste_Stopp_Zeit'? Enthält es Datumsinformationen oder ist es nur eine Tageszeit? – redneb

+0

Ah. Ich denke ich verstehe. In Anbetracht der Tatsache, dass ich eine minimale und maximale Einschränkung habe, müsste ich irgendwie in der Abfrage die Annahme kodieren, dass ich meine, dass die Bandbreite die Nacht durchläuft? –

Antwort

2

Um den folgenden Code lesbarer zu machen, nehmen Sie an, dass der Platzhalter $1 einen Wert vom Typ timestamp with time zone enthält. Dann wird die folgende Abfrage alle Nutzer finden, die zu diesem Zeitpunkt zur Verfügung stehen:

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; 

Erklärung: wir $1 nehmen, die eine timestamp with time zone ist und wir halten nur das Datum Teil nach Typ in ein date Gießen. Dann nehmen wir earliest_start_time, was eine Zeit ist und kombinieren sie mit dem vorherigen Datum und wir erhalten Vollzeitstempel, der (noch) keine Zeitzoneninformation hat. Dann geben wir die Zeitzone an, um diese in eine timestamp with time zone umzuwandeln. Wir machen das gleiche für latest_stop_time. Nun, da wir diese 2 timestamp with time zone Werte gefunden haben, können wir sie einfach mit $1 vergleichen, die denselben Typ haben.

Dies wird jedoch ein Problem mit mehrdeutigen Zeitstempeln haben (d. H. Im Übergang von DST zu Standardzeit), aber Sie können das nicht vermeiden. Wenn Sie es nur für typische Geschäftszeiten verwenden, könnte es in Ordnung sein.

Verwandte Themen