web-dev-qa-db-fra.com

Comment obtenir un horodatage UTC en JavaScript?

Lors de l'écriture d'une application Web, il est judicieux de stocker (côté serveur) tout les dates/heures dans la base de données sous forme d'horodatages UTC.

J'ai été étonné quand j'ai remarqué que vous ne pouviez pas faire grand-chose en termes de manipulation du timezone en JavaScript.

J'ai prolongé un peu l'objet Date. Cette fonction a-t-elle un sens? En gros, chaque fois que j'envoie quelque chose au serveur, il s'agira d'un horodatage formaté avec cette fonction ...

Pouvez-vous voir des problèmes majeurs ici? Ou peut-être une solution sous un angle différent?

Date.prototype.getUTCTime = function(){ 
  return new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime(); 
}

Cela me semble un peu compliqué. Et je ne suis pas si sûr de la performance non plus.

131
Merc
  1. Les dates construites de cette manière utilisent le fuseau horaire local, rendant la date construite incorrecte. Pour définir le fuseau horaire d'un objet de date donné, vous devez le construire à partir d'une chaîne de date incluant le fuseau horaire. (J'ai eu de la difficulté à faire en sorte que cela fonctionne dans un navigateur Android plus ancien.)

  2. Notez que getTime() renvoie des millisecondes et non des secondes.

Pour un horodatage UTC/Unix, les éléments suivants devraient suffire:

Math.floor((new Date()).getTime() / 1000)

Il factorisera le décalage horaire actuel dans le résultat. Pour une représentation sous forme de chaîne, David Ellis ' answer fonctionne.

Clarifier:

new Date(Y, M, D, h, m, s)

Cette entrée est traitée comme heure locale. Si UTC time est passé, les résultats seront différents. Observez (je suis en GMT +02: 00 pour le moment et il est 07h50):

> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834 

> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634

Notez également que getUTCDate() ne peut pas être remplacé par getUTCDay(). En effet, getUTCDate() renvoie le jour du mois ; alors que getUTCDay() renvoie le jour de la semaine .

128
DCoder

Vous pouvez également le faire en utilisant getTimezoneOffset et getTime,

x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;

console.log("UTCseconds", UTCseconds)

47
Shiplu Mokaddim

Oui, vous n'avez pas besoin de faire beaucoup de choses. en supposant que je vous ai bien compris, vous voulez juste utiliser la méthode toUTCString .

var UTCstring = (new Date()).toUTCString();

console.log('UTCstring', UTCstring);
  

Cependant, rappelez-vous que les valeurs de date que vous obtenez sont basées sur l'horloge de la machine du client, pas sur votre serveur. Si vous avez besoin de valeurs précises pour ces dates (par exemple, pour ordonner correctement quand telle ou telle action a été effectuée par rapport à celle d'un autre utilisateur), vous ne pouvez pas compter sur la bibliothèque de dates côté client, devez calculer les dates côté serveur en fonction du moment où le client vous a contacté.

N'oubliez pas non plus que, fondamentalement, tout votre code côté client peut être modifié par le client et que des valeurs malveillantes sont renvoyées, vous pouvez uniquement garantir le code côté serveur - traitez le côté client comme un attaquant possible.

38
David Ellis

En règle générale, vous n'avez pas besoin de faire beaucoup de "manipulation de fuseau horaire" côté client. En règle générale, j'essaie de stocker et de travailler avec les dates UTC sous la forme ticks ou "nombre de millisecondes depuis le 1er janvier 1970 à minuit}." Cela simplifie vraiment le stockage, le tri, le calcul des décalages et, surtout, vous évite les maux de tête liés aux réglages de "l'heure d'été". Voici un petit code JavaScript que j'utilise.

Pour obtenir l'heure UTC actuelle:

function getCurrentTimeUTC()
{
    //RETURN:
    //      = number of milliseconds between current UTC time and midnight of January 1, 1970
    var tmLoc = new Date();
    //The offset is in minutes -- convert it to ms
    return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}

Ensuite, vous avez généralement besoin de formater la date et l'heure de l'utilisateur final pour son fuseau horaire et son format local. Les éléments suivants traitent de toutes les complexités des formats de date et d’heure sur l’ordinateur client:

function formatDateTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date/time
    return new Date(nTicks).toLocaleString();
}

function formatDateFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date
    return new Date(nTicks).toLocaleDateString();
}

function formatTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted time
    return new Date(nTicks).toLocaleTimeString();
}

Donc, l'exemple suivant:

var ticks = getCurrentTimeUTC();  //Or get it from the server

var __s = "ticks=" + ticks + 
    ", DateTime=" + formatDateTimeFromTicks(ticks) +
    ", Date=" + formatDateFromTicks(ticks) +
    ", Time=" + formatTimeFromTicks(ticks);

document.write("<span>" + __s + "</span>");

Renvoie ce qui suit (pour mes paramètres régionaux anglais):

ticks = 1409103400661, DateTime = 8/26/2014 18:36:40, Date = 8/26/2014, Heure = 18: 36: 40 heures

13
ahmd0

En fait, je pense que les valeurs de date dans js sont bien meilleures que les objets DateTime C #. Les objets C # DateTime ont une propriété Kind, mais pas de fuseau horaire strict sous-jacent, et les conversions de fuseau horaire sont difficiles à suivre si vous effectuez une conversion entre deux heures non UTC et non locales. En js, toutes les valeurs de date ont une valeur UTC sous-jacente qui est transmise et connue indépendamment des conversions de décalage horaire ou de décalage horaire que vous effectuez. Ma plus grande plainte à propos de l'objet Date est la quantité de comportement indéfini que les développeurs de navigateur ont choisi d'inclure, ce qui peut dérouter les personnes qui attaquent les dates dans js avec des essais et des erreurs plutôt qu'en lisant les spécifications. L'utilisation de quelque chose comme iso8601.js résout ce problème en définissant une implémentation unique de l'objet Date.

Par défaut, la spécification indique que vous pouvez créer des dates avec un format de date ISO 8601 étendu tel que

var someDate = new Date('2010-12-12T12:00Z');

Vous pouvez ainsi déduire l'heure UTC exacte de cette façon. 

Lorsque vous souhaitez renvoyer la valeur Date au serveur, vous appelez

someDate.toISOString();

ou si vous préférez travailler avec un horodatage de la milliseconde (nombre de millisecondes à partir du 1er janvier 1970 UTC)

someDate.getTime();

ISO 8601 est une norme. Vous ne pouvez pas vous tromper sur la signification d'une chaîne de date si vous incluez le décalage de date. Cela signifie pour vous, en tant que développeur, que vous n’avez jamais à traiter vous-même des conversions d’heure locale . Les valeurs d'heure locale existent uniquement pour le bénéfice de l'utilisateur et les valeurs de date s'affichent par défaut dans leur heure locale. Toutes les manipulations de l'heure locale vous permettent d'afficher quelque chose de sensible pour l'utilisateur et de convertir des chaînes à partir d'une entrée utilisateur. C'est une bonne pratique de convertir au format UTC dès que vous le pouvez, et l'objet js Date rend cela assez simple.

En revanche, il n’ya pas beaucoup de possibilités de forcer le fuseau horaire ou les paramètres régionaux pour le client (à ma connaissance), ce qui peut être gênant pour les paramètres spécifiques au site Web, mais je suppose que le raisonnement derrière cela est que c’est un utilisateur. configuration qui ne devrait pas être touché.

En bref, la raison pour laquelle il n’ya pas beaucoup de prise en charge native de la manipulation de fuseau horaire est simplement parce que vous ne voulez pas le faire.

11
Matt Esch

Le moyen le plus simple d'obtenir l'heure UTC dans un format conventionnel est le suivant:

new Date().toISOString()
"2016-06-03T23:15:33.008Z"
10
Tahsin Turkoz

Je pense que c'est une meilleure solution

// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()

// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
4
koalex

J'utilise les éléments suivants:

Date.prototype.getUTCTime = function(){ 
  return this.getTime()-(this.getTimezoneOffset()*60000); 
};

Une fois cette méthode définie, vous pouvez faire:

var utcTime = new Date().getUTCTime();
4
jlbofh

Si vous voulez un liner one, l’horodatage Unix UTC peut être créé en JavaScript en tant que:

var currentUnixTimestap = ~~(+new Date() / 1000);

Cela prendra en compte le fuseau horaire du système. C'est fondamentalement le temps écoulé en secondes depuis l'époque.

Comment ça marche:

  • Créer un objet de date: new Date().
  • Convertissez-le en horodatage en ajoutant unary + avant la création de l'objet pour le convertir en timestamp integer. : +new Date().
  • Convertissez des millisecondes en secondes: +new Date() / 1000
  • Utilisez double tildes pour arrondir la valeur à un entier. : ~~(+new Date())
3
Kushal Likhi

Puisque new Date().toUTCString() renvoie une chaîne comme "Wed, 11 Oct 2017 09:24:41 GMT", vous pouvez découper les 3 derniers caractères et transmettre la chaîne découpée à new Date():

new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)

new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)
2
Maurice

EDIT: Le code ci-dessous ne fonctionne pas. Je supposais toujours que la nouvelle Date (). GetTime () renvoyait le nombre de secondes depuis le 1er janvier 1970 DANS LE FUSEAU HORAIRE ACTUEL. Ce n'est pas le cas: getTime () renvoie le nombre de secondes en UTC. Ainsi, le code ci-dessous ne permet pas un ajustement excessif. Merci tout le monde!]

Tout d’abord, merci pour vos idées fantastiques… Je suppose que ma question avait un titre erroné… elle aurait dû être «Obtenez le timestamp Unix UTC pour une date existante».

Donc, si j'ai un objet de date:

var d = new Date(2009,01,31)

Je cherchais une fonction qui me disait "Le timestamp Unix UTC".

Cette fonction semble être le vrai truc:

Date.prototype.getUTCUnixTime =  function (){
  return Math.floor( new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime() / 1000); 
}

Notez que cela fonctionne sur "ceci" Cela signifie que je peux faire:

var n = new Date(2008,10,10)
...
...

n.getUTCUnixTime();

Et obtenez le nombre de secondes depuis le 1er janvier 1970 en temps Unix .

Pour moi, il est un peu fou que Javascript stocke tout dans les heures UTC, mais pour obtenir ce numéro, je dois créer un nouvel objet Date en passant par les différents getters UTC, puis enfin appeler getTime ().

Merc.

1
Merc

Je suis stupéfait de la complexité de cette question.

Ce sont tous identiques, et leurs valeurs entières toutes === Epoch time: D

console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);

Ne me crois pas, checkout: http://www.epochconverter.com/

1
fliptopbox

Je tiens à préciser que new Date (). GetTime () renvoie effectivement une valeur UTC. Il s'agit donc d'un moyen très utile de stocker et de gérer les dates de manière agnostique par rapport aux heures localisées.

En d'autres termes, ne vous embêtez pas avec toutes les fonctions javascript de l'UTC. Au lieu de cela, utilisez simplement Date.getTime ().

Plus d'infos sur l'explication est ici: Si javascript "(nouvelle Date ()). GetTime ()" est exécuté à partir de 2 fuseaux horaires différents.

1
Stan Lin

Je pense que c'est ce que tu attends ...

var currTimestamp = Date.now(), //1482905176396
    utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"

À présent,

new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript
0
Kapilrc