2012-02-06 8 views
5

Volevo sapere se esiste un modo per ottenere l'offset del fuso orario per un determinato intervallo di date tra due fusi orari per una determinata durata.Ottenere lo scostamento del fuso orario tra due fusi orari per una data durata

getTimezoneOffset(startDate,endDate,timezone1,timezone2){ 
    ...missing magic to go here... 
} 

deve restituire lo scostamento del fuso orario valido per una determinata durata. Tuttavia, se lo scostamento cambia, dovrebbe restituire l'intervallo di date per il quale è valido.

Così sto guardando qualcosa di simile:

getTimezoneOFfset("march 9 12 am", "march 15 12 am", "UTC", "US/NEW_YORK") 

valore di ritorno qualcosa di simile

timezoneoffset[0]["range"]=[march 9 12am to march 11 2 am] 
timezoneoffset[0]["offset"]=5 
timezoneoffset[1]["range"]=[march 9 2 am to march 15 12 am] 
timezoneoffset[1]["offset"]=4 

solo che non voglio calcolare gli offset di fuso orario per ogni elemento prevista per l'intervallo dato . Stavo cercando se c'è un modo per ottenere una ricerca diretta degli offset se sta per cambiare.

Sto lavorando con PHP, ma una soluzione in qualsiasi lingua sarà apprezzata.

La soluzione MySQL funzionerà anche in quanto sarà più ottimizzata per farlo in MySQL.

risposta

3

Supponendo di disporre di una versione più recente di php (5.2.0+) la classe DateTimeZone fa parte del core PHP e consente di utilizzare la funzione getOffset() per eseguire questi calcoli. Ti permetterà di passare in un dateTime object e specificare un fuso orario. Se lo fai per entrambe le date dovresti essere in grado di calcolare tutti i pezzi che stai cercando di afferrare. Per usare un esempio da php.net:

// Create two timezone objects, one for Taipei (Taiwan) and one for 
// Tokyo (Japan) 
$dateTimeZoneTaipei = new DateTimeZone("Asia/Taipei"); 
$dateTimeZoneJapan = new DateTimeZone("Asia/Tokyo"); 

// Create two DateTime objects that will contain the same Unix timestamp, but 
// have different timezones attached to them. 
$dateTimeTaipei = new DateTime(mktime([the date in question]), $dateTimeZoneTaipei); 
$dateTimeJapan = new DateTime(mktime([the date in question]), $dateTimeZoneJapan); 


// Calculate the GMT offset for the date/time contained in the $dateTimeTaipei 
// object, but using the timezone rules as defined for Tokyo 
// ($dateTimeZoneJapan). 
$timeOffset = $dateTimeZoneJapan->getOffset($dateTimeTaipei); 

// Should show int(32400) (for dates after Sat Sep 8 01:00:00 1951 JST). 
print("Number of seconds Japan is ahead of GMT at the specific time: "); 
var_dump($timeOffset); 

print("<br />Number of seconds Taipei is ahead of GMT at the specific time: "); 
var_dump($dateTimeZoneTaipei->getOffset($dateTimeTaipei)); 

print("<br />Number of seconds Japan is ahead of Taipei at the specific time: "); 
var_dump($dateTimeZoneJapan->getOffset($dateTimeTaipei) 
    -$dateTimeZoneTaipei->getOffset($dateTimeTaipei)); 
+0

So di ottenere offset ... ma ottenere l'offset fornisce solo l'offset per un dato tempo .. la cosa è che ho un programma con gli orari pianificati per orari diversi durante il giorno .. – user1192612

+0

Quindi se ottengo una richiesta per ottenere gli elementi del programma tra il 10 marzo 2012 9 pm tom 11 marzo 9 am l'offset sta per variare per la durata .. Non voglio calcolare gli offset per ogni volta .. E questo è solo per gli Stati Uniti .. diversi paesi avranno diversi giorni in cui l'offset cambia, .. e sto cercando di trovare l'offet tra due fusi orari per un set di durata non necessariamente UTC .. il problema è che io non so se calcolo l'offset in base all'avvio Ora sarà lo stesso in tutto ..Penso che PHP ottenga l'offset per l'offset per un dato tempo .. Spero di essere stato chiaro – user1192612

+0

Bottomline è che presumo che l'offset possa variare durante un giorno di dire 11 marzo 12 am o mrach 11 12 pm (l'offset varia alle 2 del mattino). Sto cercando di coprire questo caso d'angolo – user1192612

1

Penso di PHP DateTimeZone::getTransitions method vi possono arrivare. Ha un alias procedurale, timezone_transitions_get().

public array DateTimeZone::getTransitions (
    [ int $timestamp_begin [, int $timestamp_end ]] ) 

Questo metodo restituisce tutte le "transizioni" da un valore di fuso orario a un altro, per quel fuso orario, in un determinato intervallo di tempo.

Per i vostri scopi, si vuole creare DateTimeZone oggetti per ognuno dei vostri fusi orari, chiamare DateTimeZone::getTransitions per l'intervallo di date per ottenere una serie di transizioni per quel fuso orario, quindi unire e ordinare i due array di transizioni. Questo ti darà l'equivalente dell'array timezoneoffset[] che cerchi.

Qualcosa di simile:

getTimezoneOffset(startDate,endDate,timezone1,timezone2){ 
    DT1 = DateTimeZone(timezone1); 
    transitions1 = DT1->getTransitions(startDate,endDate); 
    DT2 = DateTimeZone(timezone2); 
    transitions1 = DT2->getTransitions(startDate,endDate); 
    timezoneoffset[] = // merge and sort (transitions1, transitions2) 
} 

Il formato della matrice transizioni non è ben documentata. La documentazione metodo mostra alcuni esempio:

Array 
(
... 
    [1] => Array 
     (
      [ts] => -1691964000 
      [time] => 1916-05-21T02:00:00+0000 
      [offset] => 3600 
      [isdst] => 1 
      [abbr] => BST 
     ) 

    [2] => Array 
     (
      [ts] => -1680472800 
      [time] => 1916-10-01T02:00:00+0000 
      [offset] => 0 
      [isdst] => 
      [abbr] => GMT 
     ) 
    ... 
) 

I ipotizzare che: ts riferisce ad un timestamp PHP in secondi epoca, restituito time(), dando l'istante temporale in cui le variazioni di correggere il valore di questo record . time fa riferimento allo stesso istante, come una stringa di data e ora formattata. offset è l'offset del fuso orario in secondi da UTC, a partire dall'istante time/ts, inoltrato alla transizione successiva. isdst è 1 se l'offset si riferisce a un offset dell'ora legale, 0 altrimenti. abbr è un'abbreviazione di stringa per il fuso orario.Se qualcuno ha informazioni solide su questa struttura di dati, sarebbe una gentilezza aggiungerlo a the documentation.

+0

Grazie Jim ... questo è esattamente quello che stavo cercando ... ho esaminato l'oggetto datetime ma questo è stato trascurato. – user1192612

Problemi correlati