Я хотел знать, есть ли способ получить смещение часового пояса для заданного диапазона дат между двумя часовыми поясами для заданной продолжительности.
getTimezoneOffset(startDate,endDate,timezone1,timezone2){ ...missing magic to go here... }
должен вернуть смещение часового пояса, которое действует для данной продолжительности. Однако, если смещение изменяется, оно должно вернуть диапазон дат, для которого он действителен.
Поэтому я смотрю на что-то вроде этого:
getTimezoneOFfset("march 9 12 am", "march 15 12 am", "UTC", "US/NEW_YORK")
вернуть значение примерно так
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
Я просто не хочу вычислять смещения часовой пояс для каждого запланированного элемента для заданного диапазона. Посмотрел, есть ли способ получить прямой поиск смещений, если он изменится.
Я работаю с PHP, но решение на любом языке будет оценено.
Решение MySQL также будет работать, поскольку оно будет более оптимизировано для этого в MySQL.
Предполагая, что у вас есть более новая версия php (5.2.0+), класс DateTimeZone является частью ядра PHP и позволит вам использовать функцию getOffset()
для выполнения этих вычислений. Он позволит вам передать объект dateTime и указать часовой пояс. Если вы сделаете это для обеих дат, вы сможете рассчитать все части, которые вы хотите захватить. Чтобы использовать пример из 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));
Я думаю, DateTimeZone::getTransitions
метод DateTimeZone::getTransitions
PHP может получить вас там. Он имеет процедурный псевдоним, timezone_transitions_get()
.
public array DateTimeZone::getTransitions ( [ int $timestamp_begin [, int $timestamp_end ]] )
Этот метод возвращает все «переходы» из одного значения смещения часового пояса в другое для этого временного пояса в заданный временной диапазон.
Для ваших целей вам нужно создать объекты DateTimeZone
для каждого из ваших часовых поясов, вызвать DateTimeZone::getTransitions
для вашего диапазона дат, чтобы получить массив переходов для этого часового пояса, затем слить и отсортировать два массива переходов. Это даст вам эквивалент массива timezoneoffset[]
вы ищете.
Что-то вроде:
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) }
Формат массива переходов плохо документирован. В документации по методу показаны некоторые примеры:
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 ) ... )
Я предполагаю, что: ts
ссылается на time()
метку PHP в секундах эпохи, возвращенную time()
, давая момент времени, при котором смещение изменяется на значение в этой записи. time
относится к тому же time
, что и форматированная строка даты-времени. offset
– offset
часового пояса в секундах от UTC, с момента time
/ ts
, переход к следующему переходу. isdst
равно 1, если смещение относится к смещению на летнее время, 0 в противном случае. abbr
– это аббревиатура строки для часового пояса. Если у кого-то есть достоверная информация об этой структуре данных, было бы приятно добавить ее в документацию .