Обнаружение перехода PHP на летнее время

#php #dst #gmt #binary-search-tree

#php #летнее время #gmt #двоичный файл-дерево поиска

Вопрос:

Мне нужно отправить электронное письмо пользователям, находящимся в любой точке мира, в 9: 00 утра по местному времени. Сервер находится в Великобритании. Что я могу сделать, так это настроить разницу во времени между каждым пользователем и временем сервера, которая затем отлично работала бы, если бы DST не существовало.

Вот пример, иллюстрирующий это:

  • Джон работает в Нью-Йорке, в -5 часах езды от серверного времени (Великобритания)
  • Ричард работает в Лондоне, Великобритания, поэтому разница с сервером составляет 0 часов.

Когда сервер переходит с GMT на GMT 1 (BST) в 2:00 ночи в определенное воскресенье, это означает, что у Джона теперь разница во времени составляет -6 часов.

С этим сценарием я все еще могу справиться, обновив всех пользователей за пределами локального времени сервера, но как только я переместил вперед / назад время всех других пользователей, мне все еще нужен способ определить, когда (время и дата) пользователи, живущие за пределами Великобритании, изменят (или не будут) свое местное время на вероятное летнее.

Мне нужен метод PHP, чтобы знать / определять, когда другие части мира войдут в летнее время / выйдут из него.

Ответ №1:

Вам нужно знать все детали перехода на летнее время самостоятельно? или вам просто нужно знать, когда 9:00 утра в данном часовом поясе?

В последнем случае PHP может использовать базу данных часовых поясов вашей операционной системы, чтобы сделать это за вас. Функция strtotime() замечательно хороша в «выяснении» того, что вы имеете в виду:

 echo strtotime("today 9:00 am America/New_York");  // prints "1306501200"
echo strtotime("today 9:00 am Europe/London");     // prints "1306483200"
  

Просто убедитесь, что вы используете один из поддерживаемых PHP часовых поясов.

Комментарии:

1. Поскольку я уже использую strtotime в нескольких местах своего кода, я думаю, что ваш ответ является лучшим, даже если мне еще многое предстоит сделать, в частности, интегрировать это в мою работу crontab (я буду использовать TZ= тег). Приветствия

2. это не сработает, если время указано в DST, особенно когда оно равно -1.

3. @GorillaApe Ты уверен? Это должно сработать независимо от того, попадает ли указанный день на летнее время или нет, если правильно выполнить преобразование для этого города. Однако обратите внимание, что при последующем использовании date() с этой временной меткой используется часовой пояс по умолчанию, установленный с помощью date_default_timezone_set()!

Ответ №2:

Как указывает Джимми, вы можете использовать переходы часовых поясов, но это недоступно на PHP <5.3. поскольку DateTimeZone() равен PHP>=5.2.2, а getTransitions() с аргументами — нет! В таком случае вот функция, которая может предоставить вам данные о часовом поясе, в том числе о том, в DST он или нет.

 function timezonez($timezone = 'Europe/London'){
    $tz = new DateTimeZone($timezone);
    $transitions = $tz->getTransitions();
    if (is_array($transitions)){
        foreach ($transitions as $k => $t){
            // look for current year
            if (substr($t['time'],0,4) == date('Y')){
                $trans = $t;
                break;
            }
        }
    }
    return (isset($trans)) ? $trans : false;
}
  

С учетом сказанного, существует более простой метод с использованием date(), если вам просто нужно узнать, находится ли часовой пояс в DST. Например, если вы хотите узнать, находится ли Великобритания в DST, вы можете сделать это:

 date_default_timezone_set('Europe/London');
$bool = date('I'); // this will be 1 in DST or else 0
  

… или укажите временную метку в качестве второго аргумента для date(), если вы хотите указать дату и время, отличные от вашего текущего серверного времени.

Комментарии:

1. для меня, чтобы игнорировать летнее время: часовой пояс по умолчанию Европа / Париж, if (date (‘I’) ==1){ date_default_timezone_set(‘Европа / Лондон’);} потому что я хочу всегда UTC 1

2. @khaled_webdev: тогда используйте часовой пояс » 01:00 «.

3. date("I") помогло мне с соответствующим вопросом. Удобно иметь логическое

Ответ №3:

Немного меняю свой ответ: DateTimeZone::getTransitions похоже, что он будет делать то, что вам нужно, при условии, что у вас PHP> = 5.2.

Из комментария в документации:

 <?php 
$theTime = time(); // specific date/time we're checking, in epoch seconds. 

$tz = new DateTimeZone('America/Los_Angeles'); 
$transition = $tz->getTransitions($theTime, $theTime); 

// only one array should be returned into $transition. Now get the data: 
$offset = $transition[0]['offset']; 
$abbr = $transition[0]['abbr']; 
?>
  

Итак, здесь все, что нам нужно сделать, это ввести часовой пояс, который мы хотим проверить, и мы сможем узнать, находится ли этот часовой пояс в DST / каково смещение. Затем вам нужно будет проверить смещение относительно GMT, чтобы узнать, хотите ли вы отправить свое электронное письмо сейчас или не сейчас.

Комментарии:

1. Привет, Джимми, не мог бы ты быть более точным в своем ответе, а не просто указывать мне функцию PHP. На самом деле это не помогает мне решить эту проблему. Приветствую, Николас.

2. @Nicolas — вам нужно найти часовой пояс в массиве, а затем проверить поле dst для этого часового пояса.

3. @Nicolas Я немного пересмотрел свой ответ с помощью более простого метода и предложил примечание о том, что с этим делать. Надеюсь, это поможет.

4. @JimmySawczuk — пожалуйста, смотрите мой ответ ниже относительно этого решения на PHP <5.3

5. Работает как шарм ..!! спасибо, приятель ..!!

Ответ №4:

Я создал эту функцию PHP, чтобы увидеть, является ли значение времени BST или нет:

 <?php
function isBST($timestamp)
{
    $baseDate = date("m/d/Y H:i:s", $timestamp);
    $clocktime=strtotime($baseDate." Europe/London")."n";
    $utctime=strtotime($baseDate." UTC")."n";
    //echo "$a n$b n";
    if ($clocktime!=$utctime)
    {
        return true;
    }
    else
    {
        return false;
    }
}

?>