Konwertuj epokę UTC na datę lokalną


273

Od jakiegoś czasu walczę z tym. Próbuję przekonwertować epokę na obiekt daty. Epoka jest wysyłana do mnie w UTC. Ilekroć miniesz new Date()epokę, zakłada się, że to epoka lokalna. Próbowałem utworzyć obiekt UTC, a następnie setTime()dostosować go do właściwej epoki, ale jedyną metodą, która wydaje się przydatna, jest to, że toUTCString()łańcuchy mi nie pomagają. Jeśli przekażę ten ciąg w nową datę, powinien zauważyć, że jest to UTC, ale tak nie jest.

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

Moja kolejna próba polegała na znalezieniu różnicy między bieżącą epoką lokalną a obecną epoką UTC, ale ja też nie byłem w stanie jej uzyskać.

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

Daje mi to bardzo małe różnice, poniżej 1000, co jest w milisekundach.

Jakieś sugestie?


11
Czas epoki definiuje się jako upływ milisekund od daty 1970 w UTC . Nie ma czegoś takiego jak lokalna epoka! Nie jestem pewien, czy rozumiem twój problem.
— Chetan Sastry

Może strefa czasowa na komputerze jest nieprawidłowa, co prowadzi do innej wartości UTC?
— kijin

2
Musisz ustawić swój zegar na czas UTC, jeśli chcesz „zobaczyć” czas UTC, gdy używasz toLocaleString (). Północ UTC jest 19:00 EST. Jeśli użyjesz nowego Date (). ToString () zamiast localeString, otrzymasz coś takiego: „Pt 07 stycznia 2011 07:00:00 GMT-0500”, który zawiera przesunięcie.
— kennebec

Odpowiedzi:


463

Myślę, że mam prostsze rozwiązanie - ustaw datę początkową epoki i dodaj jednostki UTC. Załóżmy, że masz zapisaną epokę var UTC w sekundach. Jak o 1234567890. Aby przekonwertować to na właściwą datę w lokalnej strefie czasowej:

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 jest teraz ustawioną datą (w mojej strefie czasowej) Fri Feb 13 2009 18:31:30 GMT-0500 (EST)


189
FWIW, Obiekty daty mogą być inicjowane w milisekundach. var d = new Date(utcSeconds * 1000)Powinien więc dać ten sam wynik.
— kurttheviking,

54
var d = new Date(1234567890000)zwraca ten sam wynik
— Matjaz Lipus

11
Pomyślałem, że może inni mogą uzyskać pewną przejrzystość z kilku punktów: obiekt daty nie jest ustawiany ze strefą czasową „wytłoczoną w nim”. myśl o tym jak o niczym innym jak o liczbie. liczba ta jest liczbą milisekund od 1970 do 1 stycznia UTC do chwili obecnej (teraz również w UTC). Tak więc, za każdym razem, gdy tworzysz obiekt daty, jest on naprawdę w UTC za kulisami. 2. Aby wyświetlić tę datę, możesz wyświetlić ją jako ustawienie regionalne (toLocaleString () lub, w UTC (toUTCString ()). Nie musisz niczego samodzielnie konwertować. Konstruuj za pomocą utc millisec, wszystko dobrze. Konstruuj za pomocą string - o ile znajduje się w lokalnej strefie czasowej
— da Bich

2
1234567890000 jest traktowany tak samo jak 1234567890, znany również jako problem Y39K ...
— baraninaUp

1
@muttonUp, przy 1000 mulitplication zadziałało. Ale Google „problem Y39K” nie daje żadnego poprawnego wyniku. Dowolny adres URL będzie pomocny
— P Satish Patro

237

To proste, new Date()zajmuje tylko milisekundy, np

new Date(1394104654000)
> Thu Mar 06 2014 06:17:34 GMT-0500 (EST)

6
Niezłe! To naprawdę należy uznać za przyjętą odpowiedź.
— Nizar B.,

Ten nie działał dla mnie, działa, gdy masz znacznik czasu, ale w epoce utc musisz ustawić utcseconds ręcznie, odpowiedź jest prawidłowa
— sameerali

12
To jest odpowiednia odpowiedź. Nowa data może podjąć milisekund, więc po prostu pomnożyć przez 1000: const d = new Date(epoch * 1000).
— vinyll,

@sameerali Być może miałeś inny problem z systemem lub się zdezorientowałeś. Ta odpowiedź jest poprawna. Definicja epoki Uniksa: liczba sekund, które upłynęły od 1 stycznia o północy UTC . Wystarczy pomnożyć przez 1000, aby uzyskać liczbę upływających milisekund.
— dokładnie

32

I tylko dla dzienników zrobiłem to przy użyciu biblioteki Moment.js , której i tak używałem do formatowania.

moment.utc(1234567890000).local()
>Fri Feb 13 2009 19:01:30 GMT-0430 (VET)

1
Moment jest przyjemny, ale szaleństwem jest użycie biblioteki 1,3 MB do konwersji jednej epoki na datę. Nic dziwnego, że istnieje tak wiele rozdętych aplikacji węzłów.
— not2qubit

20

Czas epoki jest wyrażony w sekundach od 1 stycznia 1970 r. date.getTime()Zwraca milisekundy od 1 stycznia 1970 r., Więc .. jeśli masz znacznik czasu epoki, przekonwertuj go na znacznik czasu javascript, mnożąc przez 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;
   }

Zastanawiałem się, co u licha było. Bardzo dobrze wiedzieć, że epochTime! == javascriptTime, jeśli chodzi o parsowanie daty. Dzięki!
— GrayedFox

16
 function ToLocalDate (inDate) {
    var date = new Date();
    date.setTime(inDate.valueOf() - 60000 * inDate.getTimezoneOffset());
    return date;
}

1
Zrobiłeś mi dzień. TY. Właśnie zastąpiłem znak minus znakiem plus dla mojej pracy.
— Ludovic Kuty,

5

Aby przekonwertować bieżący czas epoki w [ms] na czas 24-godzinny. Może być konieczne określenie opcji wyłączenia formatu 12-godzinnego .

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

2/7/2018, 19:35:24

lub jako 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

Uwaga: użycie en-GBtutaj jest tylko (losowym) wyborem miejsca w formacie 24-godzinnym, nie jest to twoja strefa czasowa!


1
Jest to najlepszy sposób na uzyskanie dowolnego rodzaju konwersji z metody Date. Dzięki!
— SeaWarrior404

Jedyne, co mi się nie podoba w powyższym, to to, że zwraca datę w tak dwuznacznym formacie, d/m/yyyyczy to jest m/d/yyyy? Prawo (najbardziej logiczny) sposób wyświetlania to powinno być: yyyy-mm-dd. Jacyś chętni?
— not2qubit

4

Czas Epoki (tj. Czas Epoki Uniksa) jest prawie zawsze liczbą sekund , które upłynęły od 1 stycznia 1970 r. 00:00:00 (czasu UTC), a nie liczbą milisekund, które sugerują niektóre odpowiedzi tutaj.

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

Dlatego jeśli otrzymałeś wartość czasu Epoki Uniksowej, prawdopodobnie będzie to za kilka sekund i będzie wyglądało podobnie 1547035195. Jeśli chcesz, aby ten człowiek był czytelny w JavaScript, musisz przekonwertować wartość na milisekundy i przekazać tę wartość do Date(value)konstruktora, np .:

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

Nie musisz robić d.setUTCMilliseconds(0)kroku w zaakceptowanej odpowiedzi, ponieważ Date(value)konstruktor JavaScript przyjmuje wartość UTC w milisekundach (nie w czasie lokalnym).

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

Należy również pamiętać, że należy unikać używania Date(...)konstruktora, który przyjmuje ciąg reprezentujący datę i godzinę, nie jest to zalecane (patrz link powyżej).


3

Czy chcesz tylko przekonwertować ciąg UTC na ciąg „lokalny”? Mógłbyś:

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

3

Dodatek do powyższej odpowiedzi @djechlin

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

konwertuje czas EPOCH na datę czytelną dla człowieka. Tylko nie zapomnij, że ten rodzaj czasu EPOCH musi być liczbą całkowitą.


3

Najprostszym rozwiązaniem, jakie znalazłem, jest:

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

Zauważ, że nie ma to * 1000na końcu new Date(timestamp)oświadczenia, ponieważ to (w każdym razie dla mnie!) Zawsze wydaje się podawać niewłaściwą datę, tj. Zamiast podawać rok 2019, podaje rok jako 51015, więc pamiętaj o tym.


2

Jeśli wolisz rozstrzygać konwersje znaczników czasu i dat z UTC i czasu lokalnego bez bibliotek takich jak moment.js, spójrz na opcję poniżej.

W przypadku aplikacji korzystających ze znaczników czasu UTC może być konieczne wyświetlenie daty w przeglądarce, biorąc pod uwagę lokalną strefę czasową i czas letni, jeśli dotyczy. Edycja daty, która ma inny czas letni, mimo że w tej samej strefie czasowej może być trudna.

Poniższe rozszerzenia Numberi Datepozwalają wyświetlać i uzyskiwać daty w strefie czasowej znaczników czasu. Załóżmy na przykład, że jesteś w Vancouver, jeśli edytujesz datę w lipcu lub w grudniu, może to oznaczać, że edytujesz datę w PST lub PDT.

Zalecam sprawdzenie fragmentu kodu poniżej, aby przetestować to rozwiązanie.

Konwersje z milisekund

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

Konwersje z dat

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

Stosowanie

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

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

Przekonaj się sam


To jest właściwa odpowiedź. Dla mnie zadziałało jak urok. Ustawienie nowej daty (0) i dodanie milliSeconds jest takie samo, jak nowa data (milliSeconds)
— Jersey_Guy

1

EDYTOWAĆ

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());

EDYCJA naprawiona


Przeszedłem przez to w moim drugim przykładzie. Różnice, które mi daje, mieszczą się w przedziale od 50 do 900, co jest w milisekundach (pokazuje czas podczas przetwarzania obliczeń, a nie rzeczywistą różnicę)
— Shane Reustle

Żadne z nich mi nie pomaga. Brakuje im metody setUTCTime, która byłaby idealna: P w3schools.com/jsref/jsref_obj_date.asp
— Shane Reustle

Nie działa, przynajmniej w przeglądarce Firefox dla Ubuntu. Kod nie powinien ustawiać dnia / miesiąca / roku po ustawieniu daty.
— Simon Kozlov,

@Simon Kozlov Właściwie to błędne założenie w obiekcie daty, setDate i getDate odnoszą się do dnia w miesiącu, a problem polega na tym, że użyłem funkcji takich jak (setUTCDay), które nie istnieją, zaskoczony, że został zaakceptowany !!
— Amjad Masad

@AmjadMasad Twoja odpowiedź byłaby bardziej pomocna, jeśli pokażesz również oczekiwany wynik.
— not2qubit

0

Biorąc pod uwagę, masz epoch_timedostępne,

// 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


0

@Amjad, dobry pomysł, ale lepszym rozwiązaniem byłoby:

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

-1

Najpierw przekonwertuj go na String, a następnie zamień tekst strefy czasowej.

function convertUnixTime(time) {
  return new Date(time*1000).toString().replace("GMT+0530 (Sri Lanka Standard Time)","");
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.