web-dev-qa-db-fra.com

PHP détection de l'heure d'été

Je dois envoyer un e-mail aux utilisateurs basés partout dans le monde à 9h00, heure locale. Le serveur est au Royaume-Uni. Ce que je peux faire, c'est configurer un décalage horaire entre chaque utilisateur et l'heure du serveur, qui fonctionnerait alors parfaitement si l'heure d'été n'existait pas.

Voici un exemple pour l'illustrer:

  • John travaille à New York, à -5 heures de l'heure du serveur (Royaume-Uni)
  • Richard travaille à Londres, au Royaume-Uni, donc 0 heure de différence avec le serveur.

Lorsque le serveur passe de GMT à GMT +1 (BST) à 2h00 du matin un certain dimanche, cela signifie que John a maintenant un décalage horaire de -6H.

Ce scénario, je peux toujours le gérer en mettant à jour tous les utilisateurs en dehors de l'heure locale du serveur, mais une fois que j'ai avancé/reculé l'heure de tous les autres utilisateurs, j'ai toujours besoin d'un moyen de détecter quand ( date et heure), les utilisateurs résidant en dehors du Royaume-Uni changeront (ou ne changeront pas) leur heure locale en heure DST probable.

J'ai besoin d'une méthode PHP pour savoir/détecter quand d'autres parties du monde entreront/sortiront de l'heure d'été).

28
Nicolas

Avez-vous besoin de connaître vous-même tous les détails de la transition à l'heure d'été? ou avez-vous simplement besoin de savoir quand il est 9 h 00 dans un fuseau horaire donné?

Si c'est le dernier, PHP peut utiliser la base de données de fuseau horaire de votre système d'exploitation pour le faire pour vous. La fonction strtotime () est remarquablement bonne pour "comprendre" ce que vous signifier:

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

Assurez-vous simplement que vous utilisez l'un des fuseaux horaires pris en charge par PHP .

26
squirrel

Comme le souligne Jimmy, vous pouvez utiliser des transitions de fuseau horaire, mais cela n'est pas disponible sur PHP <5.3. Car dateTimeZone () est PHP> = 5.2.2 mais getTransitions () avec des arguments ne l'est pas! ce cas ici est une fonction qui peut vous donner des données de fuseau horaire, y compris si en DST ou non.

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;
}

Cela dit, il existe une méthode plus simple utilisant date () si vous avez juste besoin de savoir si un fuseau horaire est en DST. Par exemple, si vous voulez savoir si le Royaume-Uni est en DST, vous pouvez le faire:

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

... ou fournissez un horodatage comme deuxième argument à ce jour () si vous souhaitez spécifier une date/heure autre que l'heure actuelle de votre serveur.

21
Owen

Changer un peu ma réponse: DateTimeZone :: getTransitions on dirait qu'il fera ce dont vous avez besoin, à condition d'avoir PHP> = 5.2.

D'un commentaire dans la documentation:

<?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']; 
?>

Donc, ici, tout ce que nous devons faire est de passer dans le fuseau horaire que nous voulons vérifier et nous pouvons savoir si ce fuseau horaire est en DST/quel est le décalage. Vous devrez ensuite vérifier le décalage par rapport à GMT pour voir si vous souhaitez envoyer votre e-mail maintenant ou pas maintenant.

13
Jimmy Sawczuk