Convertir une heure UTC en date locale

275

Je me bats avec ça depuis un petit moment maintenant. J'essaie de convertir epoch en objet date. L'époque m'est envoyée en UTC. Chaque fois que vous passez new Date()une époque, cela suppose que c'est une époque locale. J'ai essayé de créer un objet UTC, puis setTime()de l'ajuster à l'époque appropriée, mais la seule méthode qui semble utile est toUTCString()que les chaînes ne m'aident pas. Si je passe cette chaîne à une nouvelle date, il devrait remarquer que c'est UTC, mais ce n'est pas le cas.

new Date( new Date().toUTCString() ).toLocaleString()

Ma prochaine tentative a été d'essayer de faire la différence entre l'époque actuelle locale et l'époque actuelle UTC, mais je n'ai pas pu l'obtenir non plus.

new Date( new Date().toUTCString() ).getTime() - new Date().getTime()

Cela ne me donne que de très petites différences, inférieures à 1000, ce qui est en millisecondes.

Aucune suggestion?

Shane Reustle
la source
11
Le temps d'époque est défini comme les millisecondes écoulées depuis la date de 1970 en UTC . L'époque locale n'existe pas! Je ne suis pas sûr de comprendre votre problème.
Chetan S
Peut-être que le fuseau horaire de l'ordinateur est incorrect, ce qui entraîne une valeur UTC différente?
kijin
2
Vous devez régler votre horloge sur l'heure UTC, si vous voulez «voir» l'heure UTC lorsque vous utilisez toLocaleString (). Minuit UTC est 19 h HNE. Si vous utilisez new Date (). ToString () au lieu de localeString, vous obtiendrez quelque chose comme: 'Fri Jan 07 2011 07:00:00 GMT-0500', qui comprend le décalage.
kennebec

Réponses:

467

Je pense que j'ai une solution plus simple - définir la date initiale à l'époque et ajouter des unités UTC. Supposons que vous ayez une variable d'époque UTC stockée en quelques secondes. Que diriez-vous 1234567890. Pour convertir cela en une date correcte dans le fuseau horaire local:

var utcSeconds = 1234567890;
var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
d.setUTCSeconds(utcSeconds);

d est maintenant une date (dans mon fuseau horaire) définie sur Fri Feb 13 2009 18:31:30 GMT-0500 (EST)

user1030503
la source
190
FWIW, les objets Date peuvent être initialisés en millisecondes. Donc, var d = new Date(utcSeconds * 1000)devrait donner le même résultat.
kurttheviking
54
var d = new Date(1234567890000)retourne le même résultat
Matjaz Lipus
11
pensait que peut-être d'autres pourraient obtenir une certaine clarté à partir de quelques points: l'objet de date n'est pas défini avec un fuseau horaire "tamponné". n'y voir qu'un chiffre. ce nombre est le nombre de millisecondes depuis le 1er janvier 1970 UTC, jusqu'à maintenant (maintenant en UTC également). Ainsi, chaque fois que vous créez un objet date, il est vraiment en UTC dans les coulisses. 2. Pour afficher cette date, vous pouvez l'afficher comme paramètre local (toLocaleString () ou, en UTC (toUTCString ()). Vous n'avez pas besoin de convertir quoi que ce soit vous-même. Construire avec utc millisec, tout va bien. Construire avec chaîne - tant qu'elle est dans le fuseau horaire local.
da Bich
2
1234567890000 est traité de la même manière que 1234567890, alias le problème Y39K ...
muttonUp
1
@muttonUp, avec 1000 mulitplication cela a fonctionné. Mais, «problème Y39K», google ne donne aucun résultat valide. Toute URL sera utile
P Satish Patro
239

C'est facile, cela new Date()prend juste des millisecondes, par exemple

new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)
Djechlin
la source
6
Joli! Cela devrait être considéré comme la réponse acceptée vraiment.
Nizar B.8
Celui-ci n'a pas fonctionné pour moi, il fonctionne lorsque vous avez un horodatage mais avec utc epoch vous devez définir les utcsecondes manuellement, la réponse d'acceptation est la bonne réponse
sameerali
12
Ceci est une réponse appropriée. Nouvelle date peut prendre millisecondes, donc tout multiplier par 1000: const d = new Date(epoch * 1000).
vinyll
@sameerali Vous avez peut-être eu un problème différent avec votre système ou vous vous êtes trompé. Cette réponse est la bonne réponse. La définition de l'époque Unix: nombre de secondes écoulées depuis le 1er janvier minuit UTC . Multipliez simplement par 1000 pour obtenir le nombre de millisecondes écoulées.
2017 à 9h26
32

Et juste pour les journaux, je l'ai fait en utilisant la bibliothèque Moment.js , que j'utilisais pour le formatage de toute façon.

moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)
Gus
la source
1
Le moment est agréable, mais il est insensé d'utiliser une bibliothèque de 1,3 Mo pour convertir simplement une époque en une date. Pas étonnant qu'il existe autant d'applications de nœuds gonflés.
not2qubit
20

L'époque est en secondes à partir du 1er janvier 1970. date.getTime()renvoie les millisecondes à partir du 1er janvier 1970, donc .. si vous avez un horodatage d'époque, convertissez-le en horodatage javascript en multipliant par 1000.

   function epochToJsDate(ts){
        // ts = epoch timestamp
        // returns date obj
        return new Date(ts*1000);
   }

   function jsDateToEpoch(d){
        // d = javascript date obj
        // returns epoch timestamp
        return (d.getTime()-d.getMilliseconds())/1000;
   }
logic8
la source
Je me demandais ce qui se passait. Très bon de savoir que epochTime! == javascriptTime quand il s'agit d'analyser les dates. Merci!
GrayedFox
16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}
chris
la source
1
Tu as fait ma journée. TY. Je viens de remplacer le signe moins par un signe plus pour mon travail.
Ludovic Kuty
5

Pour convertir l'heure actuelle en [ms] en 24 heures. Vous devrez peut-être spécifier l'option pour désactiver le format 12 heures .

$ node.exe -e "var date = new Date(Date.now()); console.log(date.toLocaleString('en-GB', { hour12:false } ));"

2/7/2018, 19:35:24

ou en tant que JS:

var date = new Date(Date.now()); 
console.log(date.toLocaleString('en-GB', { hour12:false } ));
// 2/7/2018, 19:35:24

console.log(date.toLocaleString('en-GB', { hour:'numeric', minute:'numeric', second:'numeric', hour12:false } ));
// 19:35:24

Remarque: L'utilisation d' en-GBici, n'est qu'un choix (aléatoire) d'un lieu au format 24 heures, ce n'est pas votre fuseau horaire!

not2qubit
la source
1
C'est le meilleur moyen d'obtenir tout type de conversion à partir de la méthode Date. Merci!
SeaWarrior404 du
La seule chose que je n'aime pas avec ce qui précède, c'est qu'elle renvoie la date dans un format ambigu d/m/yyyyou est-ce m/d/yyyy? Le droit ( le plus logique) façon d'afficher cela devrait être: yyyy-mm-dd. N'importe quels preneurs?
not2qubit
4

Le temps Epoch (c'est-à-dire le temps Unix) est presque toujours le nombre de secondes qui ont expiré depuis le 1er janvier 1970 à 00:00:00 (heure UTC), pas le nombre de millisecondes que certaines des réponses ici impliquent.

https://en.wikipedia.org/wiki/Unix_time

Par conséquent, si vous avez reçu une valeur de temps Epoque Unix, elle sera probablement en secondes et ressemblera à quelque chose 1547035195. Si vous souhaitez rendre cet humain lisible en JavaScript, vous devez convertir la valeur en millisecondes et transmettre cette valeur au Date(value)constructeur, par exemple:

const unixEpochTimeMS = 1547035195 * 1000;
const d = new Date(unixEpochTimeMS);
// Careful, the string output here can vary by implementation...
const strDate = d.toLocaleString();

Vous n'avez pas besoin de faire l' d.setUTCMilliseconds(0)étape de la réponse acceptée car le Date(value)constructeur JavaScript prend une valeur UTC en millisecondes (pas une heure locale).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Syntax

Notez également que vous devez éviter d'utiliser le Date(...)constructeur qui prend une représentation chaîne de données, ce n'est pas recommandé (voir le lien ci-dessus).

garryp
la source
3

Demandez-vous simplement de convertir une chaîne UTC en une chaîne "locale"? Vous pourriez faire:

var utc_string = '2011-09-05 20:05:15';
var local_string = (function(dtstr) {
    var t0 = new Date(dtstr);
    var t1 = Date.parse(t0.toUTCString().replace('GMT', ''));
    var t2 = (2 * t0) - t1;
    return new Date(t2).toString();
})(utc_string);
ZagNut
la source
3

Ajout à la réponse ci-dessus par @djechlin

d = '1394104654000';
new Date(parseInt(d));

convertit l'heure EPOCH en date lisible par l'homme. N'oubliez pas que ce type de temps EPOCH doit être un entier.

Sarvar Nishonboev
la source
3

La solution la plus simple que j'ai trouvée à ce sujet est:

var timestamp = Date.now(), // returns milliseconds since epoch time
    normalisedTime = new Date(timestamp);

Notez que cela n'a pas * 1000la fin de la new Date(timestamp)déclaration car cela (pour moi en tout cas!) Semble toujours donner la mauvaise date, c'est-à-dire qu'au lieu de donner l'année 2019, cela donne l'année comme 51015, alors gardez cela à l'esprit.

Rob P
la source
2

Si vous préférez résoudre les horodatages et les conversions de dates de et vers UTC et l'heure locale sans bibliothèques comme moment.js, jetez un œil à l'option ci-dessous.

Pour les applications qui utilisent les horodatages UTC, vous devrez peut-être afficher la date dans le navigateur en tenant compte du fuseau horaire local et de l'heure d'été, le cas échéant. Modifier une date qui se trouve à une heure d'été différente, même si dans le même fuseau horaire, peut être délicat.

Les extensions Numberet Dateci-dessous vous permettent d'afficher et d'obtenir des dates dans le fuseau horaire des horodatages. Par exemple, disons que vous êtes à Vancouver, si vous modifiez une date en juillet ou en décembre, cela peut signifier que vous modifiez une date en PST ou PDT.

Je vous recommande de vérifier l'extrait de code ci-dessous pour tester cette solution.

Conversions en millisecondes

Number.prototype.toLocalDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() + (value.getTimezoneOffset() / 60));

    return value;
};

Number.prototype.toUTCDate = function () {
    var value = new Date(this);

    value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));

    return value;
};

Conversions de dates

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

Usage

// Adds the timezone and daylight savings if applicable
(1499670000000).toLocalDate();

// Eliminates the timezone and daylight savings if applicable
new Date(2017, 6, 10).getUTCTime();

Voyez par vous-même

Darlesson
la source
Telle est la vraie réponse. A fonctionné à merveille pour moi. La définition d'une nouvelle date (0) et l'ajout de milliSecondes sont les mêmes que la nouvelle date (milliSecondes)
Jersey_Guy
1

ÉDITER

var utcDate = new Date(incomingUTCepoch);
var date = new Date();
date.setUTCDate(utcDate.getDate());
date.setUTCHours(utcDate.getHours());
date.setUTCMonth(utcDate.getMonth());
date.setUTCMinutes(utcDate.getMinutes());
date.setUTCSeconds(utcDate.getSeconds());
date.setUTCMilliseconds(utcDate.getMilliseconds());

EDIT fixe

Amjad Masad
la source
Je suis passé par là dans mon deuxième exemple. Les différences qu'il me donne se situent entre 50 et 900, ce qui est en millisecondes (indiquant le temps pendant le traitement du calcul, pas la différence réelle)
Shane Reustle
Aucun d'eux ne m'aide. Il leur manque une méthode setUTCTime, ce qui serait parfait: P w3schools.com/jsref/jsref_obj_date.asp
Shane Reustle
Ne fonctionne pas, du moins sur Firefox pour Ubuntu. Le code ne doit pas définir le jour / mois / année après avoir défini la date.
Simon Kozlov
@Simon Kozlov En fait, c'est une hypothèse erronée dans l'objet date, setDate et getDate se réfèrent au jour du mois, et le problème est que j'ai utilisé des fonctions comme (setUTCDay) qui n'existe pas, surpris qu'il ait été accepté !!
Amjad Masad
@AmjadMasad Votre réponse serait plus utile si vous montriez également la sortie attendue.
not2qubit
0

Considérant que vous disposez epoch_time,

// for eg. epoch_time = 1487086694.213
var date = new Date(epoch_time * 1000); // multiply by 1000 for milliseconds
var date_string = date.toLocaleString('en-GB');  // 24 hour format
apurva.nandan
la source
0

@Amjad, bonne idée, mais une meilleure implémentation serait:

Date.prototype.setUTCTime = function(UTCTimestamp) {
    var UTCDate = new Date(UTCTimestamp);
    this.setUTCFullYear(UTCDate.getFullYear(), UTCDate.getMonth(), UTCDate.getDate());
    this.setUTCHours(UTCDate.getHours(), UTCDate.getMinutes(), UTCDate.getSeconds(), UTCDate.getMilliseconds());
    return this.getTime();
}
Walf
la source
-1

Convertissez-le d'abord en chaîne, puis remplacez le texte du fuseau horaire.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Robot Boy
la source