70 votes

PHP - strtotime, spécifier le fuseau horaire

J'ai une chaîne de date, disons ' 2008-09-11 '. Je veux obtenir un horodatage à partir de cela, mais je dois spécifier un fuseau horaire dynamiquement (plutôt que le fuseau par défaut de PHP).

Donc pour résumer, j'ai deux cordes :

$dateStr = '2008-09-11';
$timezone = 'Americas/New_York';

Comment puis-je obtenir l'horodatage pour cela ?

EDIT : L'heure de la journée sera le minuit de ce jour.... $dateStr = '2008-09-11 00:00:00' ;

1 votes

Pourquoi prendre en compte le fuseau horaire quand il n'y a pas d'heure spécifiée ?

0 votes

Désolé pour la confusion. Ce sera le minuit de ce jour (début du jour spécifié).

0 votes

Si vous prenez minuit comme heure par défaut, cela compte...

104voto

salathe Points 26305
$date = new DateTime($dateStr, new DateTimeZone($timezone));

$timestamp = $date->format('U');

2 votes

N'ai-je pas besoin de préciser le fuseau horaire à partir duquel je convertis ? Ou est-ce qu'il convertit simplement le fuseau horaire par défaut de PHP ?

6 votes

@whydna tu ne l'es pas conversion de quoi que ce soit (à moins que je n'interprète mal). Le code crée une représentation de cette date dans le fuseau horaire spécifié.

0 votes

Je pense que vous vous convertissez. Parce que le fuseau horaire d'origine de $dateStr est important. Vous devez donc préciser le fuseau horaire vers lequel vous convertissez et le fuseau horaire à partir duquel vous convertissez. Mais votre exemple fonctionnera parce que le fuseau horaire à partir duquel il est converti est le fuseau horaire par défaut de php.

41voto

krowe Points 1994

La réponse acceptée est excellente si vous utilisez PHP > 5.2 (je pense que c'est la version qui a ajouté la classe DateTime). Si vous voulez prendre en charge une version plus ancienne, si vous ne voulez pas taper autant, ou si vous préférez simplement l'approche fonctionnelle, il existe un autre moyen qui ne modifie pas non plus les paramètres globaux :

$dateStr = '2008-09-11 00:00:00';
$timezone = 'America/New_York';
$dtUtcDate = strtotime($dateStr. ' '. $timezone);

1 votes

Je ne vois pas comment la réponse acceptée modifie les paramètres globaux.

2 votes

Ce n'est pas le cas. Il utilise des classes et nécessite PHP > 5.2. C'est la réponse de Jonahs qui a modifié les paramètres globaux.

0 votes

Si vous ajoutez l'heure à la $dateStr., la sortie sera erronée.

21voto

Jonah Points 5434

Cela fonctionnera si pour une raison quelconque vous utilisez <5.2 (Dieu nous en préserve).

$reset = date_default_timezone_get();
date_default_timezone_set('America/New_York');
$stamp = strtotime($dateStr);
date_default_timezone_set($reset);

Mais pour tout ce qui est 5.2 et plus, je vous recommande fortement d'opter pour la réponse de @salathe.

0 votes

Cela fonctionne mais n'oubliez pas de le changer à nouveau ! je pense que la solution de salathes est meilleure

0 votes

Que voulez-vous dire par "changer en arrière" ? Ouais, 1 ligne contre 4 lignes. Hmmm. :D

0 votes

Cette solution (qui n'est pas tout à fait ce que le PO veut, c'est pourquoi j'en ai fait un commentaire) est excellente si l'application entière doit fonctionner sur un fuseau horaire particulier pour ce processus - mais pas aussi élégante pour un besoin unique.

6voto

Philippe Gilbert Points 185

Si vous souhaitez utiliser les fuseaux horaires, je vous propose d'utiliser la classe DateTime, et dans ce cas la fonction DateTime::createFromFormat() qui vous permettra de faire quelque chose comme ceci :

$start = "2015-01-14 11:59:43";
$timezone = "America/Montreal";

$tz = new DateTimeZone($timezone);
$dt = DateTime::createFromFormat('Y-m-d H:i:s', $start, $tz);

Lorsque vous placez $tz dans la fonction DateTime::createFromFormat, vous lui indiquez dans quel fuseau horaire se trouve la date que vous avez donnée, de sorte que lorsque vous devez la convertir dans un autre fuseau horaire, il vous suffit de faire quelque chose comme ceci :

$start = $dt->setTimeZone(new DateTimeZone('UTC'));

4voto

Charu Points 31

Chaque fois que vous vous référez à un moment précis dans le temps, conservez l'heure selon une norme unifiée qui n'est pas affectée par l'heure d'été. (GMT et UTC sont équivalents à cet égard, mais il est préférable d'utiliser le terme UTC. Notez que l'UTC est également connu sous le nom de temps Zulu ou Z).

Si vous choisissez plutôt de conserver une heure en utilisant une valeur d'heure locale, incluez le décalage de l'heure locale par rapport à UTC, afin que l'horodatage puisse être interprété ultérieurement sans ambiguïté.

Dans certains cas, vous pouvez avoir besoin de stocker à la fois l'heure UTC et l'heure locale équivalente. Cela se fait souvent au moyen de deux champs distincts, mais certaines plates-formes prennent en charge un type datetimeoffset qui permet de stocker les deux dans un seul champ.

Lorsque vous stockez des horodatages sous forme de valeur numérique, utilisez le temps Unix - qui est le nombre de secondes entières depuis 1970-01-01T00:00:00Z (à l'exclusion des secondes intercalaires). Si vous avez besoin d'une plus grande précision, utilisez plutôt les millisecondes. Cette valeur doit toujours être basée sur UTC, sans ajustement de fuseau horaire.

Si vous devez ultérieurement modifier l'horodatage, incluez l'identifiant du fuseau horaire d'origine afin de pouvoir déterminer si le décalage a pu changer par rapport à la valeur enregistrée à l'origine.

Lors de la programmation d'événements futurs, l'heure locale est généralement préférée à l'heure UTC, car il est fréquent que le décalage change. Voir la réponse, et le billet de blog.

N'oubliez pas que le décalage des fuseaux horaires n'est pas toujours un nombre entier d'heures (par exemple, l'heure normale indienne est UTC+05:30, et le Népal utilise UTC+05:45).

Si vous utilisez Java, utilisez java.time pour Java 8, ou utilisez Joda Time pour Java 7 ou inférieur. Si vous utilisez .NET, envisagez d'utiliser Noda Time. Si vous utilisez .NET sans Noda Time, sachez que DateTimeOffset est souvent un meilleur choix que DateTime. Si vous utilisez Perl, utilisez DateTime. Si vous utilisez Python, utilisez pytz ou dateutil. Si vous utilisez JavaScript, utilisez moment.js avec l'extension moment-timezone. Si vous utilisez PHP > 5.2, utilisez les conversions de fuseaux horaires natives fournies par les classes DateTime et DateTimeZone. Soyez prudent lorsque vous utilisez.

DateTimeZone::listAbbreviations() - voir la réponse. Pour que PHP ait des données Olson à jour, installez périodiquement le paquet PECL timezonedb ; voir la réponse.

Si vous utilisez le langage C++, veillez à utiliser une bibliothèque qui met correctement en œuvre la base de données des fuseaux horaires de l'IANA. Ces bibliothèques comprennent cctz, ICU et la bibliothèque "tz" de Howard Hinnant.

N'utilisez pas Boost pour les conversions de fuseaux horaires. Bien que son API prétende prendre en charge les identifiants IANA standard (alias "zoneinfo"), elle les convertit grossièrement en décalages fixes sans tenir compte de la riche histoire des changements que chaque zone a pu connaître.

(De plus, le fichier n'est plus entretenu).

La plupart des règles commerciales utilisent l'heure civile, plutôt que l'UTC ou l'GMT. Par conséquent, prévoyez de convertir les horodatages UTC en fuseau horaire local avant d'appliquer la logique applicative.

N'oubliez pas que les fuseaux horaires et les décalages ne sont pas fixes et peuvent changer. Par exemple, historiquement, les États-Unis et le Royaume-Uni utilisaient les mêmes dates pour le "printemps avant" et le "printemps arrière".

Toutefois, en 2007, les États-Unis ont modifié les dates de changement d'heure. Cela signifie désormais que pendant 48 semaines de l'année, la différence entre l'heure de Londres et l'heure de New York est de 5 heures et pendant 4 semaines (3 au printemps, 1 en automne), elle est de 4 heures. Tenez compte de ce genre d'éléments dans tout calcul impliquant plusieurs fuseaux horaires.

Considérez le type de temps (temps réel, temps de diffusion, temps relatif, temps historique, temps récurrent) et les éléments (horodatage, décalage de fuseau horaire et nom de fuseau horaire) que vous devez stocker pour une récupération correcte - voir "Types de temps" dans la réponse.

Maintenez la synchronisation de votre système d'exploitation, de vos bases de données et des fichiers de données de vos applications, entre eux et le reste du monde.

Sur les serveurs, réglez les horloges matérielles et les horloges du système d'exploitation sur UTC plutôt que sur un fuseau horaire local.

Indépendamment du point précédent, le code côté serveur, y compris les sites web, ne doit jamais s'attendre à ce que le fuseau horaire local du serveur soit quelque chose de particulier. voir la réponse.

Utilisez les services NTP sur tous les serveurs.

Si vous utilisez FAT32, n'oubliez pas que les horodatages sont stockés en heure locale, et non en UTC.

Lorsqu'il s'agit d'événements récurrents (émission télévisée hebdomadaire, par exemple), n'oubliez pas que l'heure change avec l'heure d'été et qu'elle sera différente selon les fuseaux horaires.

Toujours interroger les valeurs de date-heure en tant que limite inférieure inclusive, limite supérieure exclusive (>=, <).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X