Jak przekonwertować datę JavaScript na UTC?

590

Załóżmy, że użytkownik Twojej witryny wprowadza zakres dat.

2009-1-1 to 2009-1-3

Musisz wysłać tę datę do serwera w celu przetworzenia, ale serwer oczekuje, że wszystkie daty i godziny będą w UTC.

Załóżmy teraz, że użytkownik jest na Alasce, Hawajach lub Fidżi. Ponieważ znajdują się w strefie czasowej zupełnie innej niż UTC, zakres dat należy przekonwertować na coś takiego:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

Używając obiektu JavaScript Date, w jaki sposób przekonwertowałbyś pierwszy „zlokalizowany” zakres dat na coś, co serwer zrozumie?

dthrasher
źródło
10
wskrzesił to, ponieważ był to dla mnie najlepszy hit Google, a nowsze przeglądarki mają wbudowaną obsługę ciągów dat UTC.
jcomeau_ictx
4
Zaktualizowałem zaakceptowaną odpowiedź, aby podświetlić nową metodę ECMAscript 5 toISOString (). Zobacz stackoverflow.com/a/11957822/19112
dthrasher 30.01.2013
5
więc w 2015 roku mam do czynienia z terminami ustalania i analizowania? śmieszny!
Zestaw narzędzi
2
Oczywiście że masz. Nie możesz nigdy polegać na tym, że ktoś wykonuje dla ciebie pracę: - P Przynajmniej dopóki świat nie przestanie używać stref czasowych i nie zacznie ujednolicać dat i godzin.
Erenor Paz,
4
Najlepiej „gwiezdne”.
Michael Daw

Odpowiedzi:

370

toISOString()Metoda zwraca ciąg w uproszczonym formacie rozszerzonym ISO ( ISO 8601 ), który jest zawsze długość 24 lub 27 znaków ( YYYY-MM-DDTHH:mm:ss.sssZlub±YYYYYY-MM-DDTHH:mm:ss.sssZ , odpowiednio). Strefa czasowa ma zawsze zerowe przesunięcie UTC, co oznaczono przyrostkiem „ Z”.

Źródło: Dokumenty internetowe MDN

Potrzebny format jest tworzony za pomocą .toISOString() metody. W przypadku starszych przeglądarek (tj. 8 i starszych), które nie obsługują natywnie tej metody, podkładkę można znaleźć tutaj :

To da ci możliwość robienia tego, czego potrzebujesz:

var isoDate = new Date('yourdatehere').toISOString();

Strefa czasowa moment.js i moment.js są naprawdę nieocenionymi narzędziami ... szczególnie do nawigacji w strefach czasowych między javascript klienta i serwera.

Will Stern
źródło
81
właściwie to konwertuje obiekt date na ciąg, nie będzie w stanie wykonywać na nim dalszych operacji na
datach
2
@ TheRebel, podany przypadek użycia jest taki, że musi on wysłać do serwera sformatowany ciąg.
Will Stern
28
@ Cóż, masz całkowitą rację, ale - jak zakładam większość widzów tutaj - przybyłem tutaj na podstawie tytułu, szukając ogólnej daty JS do konwersji UTC, więc pomyślałem, że warto tu o tym wspomnieć :)
orszaczky
4
Zachowaj ostrożność podczas korzystania z tej metody! Nie tworzy daty UTC - formatuje istniejące dane daty tak, jak jest w formacie UTC i nadaje jej strefę czasową „Z”. To źle 99% czasu! Przed użyciem tej metody musisz przekonwertować datę na strefę czasową GMT!
user1944491,
5
@ user1944491 Nie sądzę, żeby to było poprawne. Według dokumentów MDN, toISOStringpoprawnie konwertuje na UTC. [toISOString] returns a string in simplified extended ISO format ... The timezone is always zero UTC offsetRównież w tym przykładzie pokazują, że offset jest uwzględniany, gdy wywoływane jest toISOString
FFF
560

Prosty i głupi

var date = new Date(); 
var now_utc =  Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
 date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());

 return new Date(now_utc);
DrunkCoder
źródło
85
Podobał mi się twój pomysł i zastosowałem metodę, z której korzystałem wiele razy. function convertDateToUTC(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); }
Tim
21
Najkrótszy kod, jaki wymyśliłem, aby uzyskać datę i godzinę UTC, to wykreślanie strefy czasowej:new Date(new Date().toUTCString().substr(0, 25))
joelvh
17
Zauważ, że getUTCMonth () zwraca wartości od 0 do 11. Jeśli więc potrzebujesz miesiąca według liczby zamiast ciągu, pomaga +1 do wartości.
Talvi Watia,
19
To nonsens. Nowa data będzie miała inną wartość niż faktycznie chcesz. Po prostu użyj now.toUTCSTring()zamiast (źle) now_utc.toString().
Bergi,
22
Nie użyłbym tego - używając nowej daty () otrzymujesz strefę czasową przeglądarki. w Chrome 29 i IE10 data i godzina wydają się być poprawne, ale strefa czasowa jest ustawiona na strefę czasową przeglądarki, co może powodować problemy ...
Sean
207

Oto moja metoda:

var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

Wynikowy utcobiekt nie jest tak naprawdę datą UTC, ale lokalną datą przesuniętą tak, by pasowała do godziny UTC (patrz komentarze). Jednak w praktyce spełnia swoje zadanie.

Gras Double
źródło
Patrzyłem na ten problem, kiedy zdałem sobie sprawę, że Date.now()daje on czas lokalny, a nie czas UTC, i to rozwiązanie wydaje mi się najprostsze. Przynajmniej w moim przypadku, gdy chcę czasu UNIX, a nie ładnie sformatowanego ciągu. (jedyną różnicą było to, że pomnożyłem, 60 * 1000żeby być wyjątkowo wyraźnym :))
Timothée Boucher,
18
Dodanie 60000 * Date.getTimezoneOffset () jest niepoprawne! Po pierwsze, musisz traktować wszystkie Daty / Czasy jako już UTC z modyfikatorem strefy czasowej do celów wyświetlania. Przeglądarki mogą się różnić, jednak Date.getTime () zwraca liczbę milisekund od 1970-01-01. Jeśli utworzysz nową datę przy użyciu tego numeru, np .: nowa data (Date.getTime ()); to będzie UTC , jednak kiedy go wyświetlić (np: za pomocą konsoli dev narzędzi chrom) pojawi się lokalna strefa czasowa.
Aaron Hoffman
15
W mojej przeglądarce powoduje to utworzenie godziny innej niż UTC. Jednak gdy wyświetla się w mojej przeglądarce, wyświetla on godzinę w lokalnej strefie czasowej, która byłaby poprawna w czasie UTC, jeśli informacje o strefie czasowej zostaną zignorowane.
Aaron Hoffman
Gotcha, interesujący punkt. Porównajmy now.toString()z utc.toString(): nie ma zmiany strefy czasowej, ale zmiana czasu, co jest zupełnie inną rzeczą. Jednak czystsze rozwiązanie byłoby znacznie bardziej złożone (tak mi się wydaje), a ten kod wykonuje pracę w zdecydowanej większości przypadków, o ile nie zajmujemy się dalej strefami czasowymi. Przypomniało mi to o dziurkowaniu kaczek : inna rzecz, ale zachowana tak samo. Zauważ też, że kod DrunkCoder ma ten sam problem.
Gras Double
4
Ta odpowiedź pokazuje inną powszechną implementację „przesunięcia epoki”, która jest niebezpieczna w oderwaniu, ponieważ może zawieść w pobliżu przypadków krawędziowych, takich jak przejścia DST. Niepolecane.
Matt Johnson-Pint,
25
Date.prototype.toUTCArray= function(){
    var D= this;
    return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),
    D.getUTCMinutes(), D.getUTCSeconds()];
}

Date.prototype.toISO= function(){
    var tem, A= this.toUTCArray(), i= 0;
    A[1]+= 1;
    while(i++<7){
        tem= A[i];
        if(tem<10) A[i]= '0'+tem;
    }
    return A.splice(0, 3).join('-')+'T'+A.join(':');    
}
Kennebec
źródło
To działa dobrze. Po prostu potrzebowałem zamienić „-” w moich datach źródłowych na „/”, aby utworzyć datę JavaScript, a następnie mógłbym wywołać twoją funkcję toISO (), aby uzyskać poprawne wyjście.
dthrasher
to działa świetnie. Możesz również wprowadzić wynik do jQuery $ .parseDate (...), aby odzyskać obiekt daty, który został przesunięty do UTC.
Brian Ellis,
23

Konwertuj na ISO bez zmiany daty / godziny

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time) 
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z

Konwertuj na ISO ze zmianą daty / godziny (data / godzina zostanie zmieniona)

isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z 

Link do skrzypiec

RollerCosta
źródło
więc to jest rodzaj fałszywego UTC? Zmieniam lokalną datę i udaje mi się przesłać na serwer datę i godzinę, które faktycznie widzę na zegarze komputera. Łał. W każdym razie lepsze niż rozwarstwienie i parsowanie
Zestaw narzędzi
Ponadto nie potrzebujesz .toISOString (), możesz po prostu wysłać isoDate na serwer
Toolkit
.toISOString () jest prosty i prosty, wyciągnięcie z niego daty będzie dodatkowym krokiem (isoDate nie jest funkcją).
RollerCosta
Nie musisz dodawać przesunięcia zamiast go odejmować? Patrz stackoverflow.com/a/11964609/832230
Acumenus
@ABB Jeśli bieżące przesunięcie strefy czasowej wynosi + ve, powinniśmy je odjąć (w naszym przypadku IST wynosi +5: 30), w przeciwnym razie dodaj.
RollerCosta
18

Przeglądarki mogą się różnić i należy również pamiętać, aby nie ufać żadnym informacjom generowanym przez klienta, co powiedziawszy, poniższe oświadczenie działa dla mnie (Google Chrome v24 na Mac OS X 10.8.2)

var utcDate = new Date(new Date().getTime());


edycja: „Czym to się różni od zwykłego new Date()?” patrz tutaj: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

  • Jeśli nie podano żadnych argumentów, konstruktor tworzy obiekt JavaScript Date dla bieżącej daty i godziny zgodnie z ustawieniami systemu.
  • Uwaga: W przypadku wywołania daty jako konstruktora z więcej niż jednym argumentem podane argumenty reprezentują czas lokalny. Jeśli pożądany jest UTC, użyj nowej daty ( Date.UTC (...) ) z tymi samymi argumentami. (uwaga: Date.UTC () zwraca liczbę milisekund od 1970-01-01 00:00:00 UTC)

Dodanie 60000 * Date.getTimezoneOffset (), jak stwierdzono w poprzednich odpowiedziach, jest niepoprawne. Po pierwsze, musisz traktować wszystkie Daty / Czasy jako już UTC z modyfikatorem strefy czasowej do celów wyświetlania.

Ponownie, przeglądarki mogą się różnić, jednak Date.getTime () zwraca liczbę milisekund od 1970-01-01 UTC / GMT. Jeśli utworzysz nową datę przy użyciu tego numeru, tak jak ja powyżej, będzie to UTC / GMT. Jeśli jednak wyświetlisz go, wywołując metodę .toString (), pojawi się ona w lokalnej strefie czasowej, ponieważ .toString () używa lokalnej strefy czasowej, a nie strefy czasowej obiektu Date, do którego została wywołana.

Odkryłem również, że jeśli wywołasz funkcję .getTimezoneOffset () w określonym dniu, zwróci ona lokalną strefę czasową, a nie strefę czasową obiektu daty, w którym ją wywołałeś (nie mogę jednak zweryfikować, czy jest to standard).

W mojej przeglądarce dodanie 60000 * Date.getTimezoneOffset () tworzy DateTime, który nie jest UTC . Jednak wyświetlany w mojej przeglądarce (np. .ToString ()) wyświetla DateTime w mojej lokalnej strefie czasowej, która byłaby poprawna dla czasu UTC, gdyby informacje o strefie czasowej były ignorowane.

Aaron Hoffman
źródło
11
Właśnie uruchomiłem ten kod na Fx i Chrome, wydaje się, że nie działa: wynik jest dokładnie taki sam jak od new Date(), ani znacznik czasu, ani strefa czasowa nie ulegają zmianie
Gras Double
3
To dlatego, że znaczniki czasu nie zawierają stref czasowych. new Date().getTime()zawsze zwraca znacznik czasu, który jest niezależny od strefy czasowej. Nie jest z nim powiązany żaden znacznik czasu, dopóki nie spróbujesz sformatować go w liczbie innej niż liczba milisekund od epoki Uniksa.
frontendbeauty
7
O ile mogę powiedzieć new Date(new Date().getTime())zwraca dokładnie taką samą wartość jak new Date(). Czy możesz wyjaśnić, w jakim sensie twoja odpowiedź ma wyraźną wartość new Date()?
Kirk Woll
Publikuję tę wartość na moim serwerze new Date("5/19/2014").getTime(). Konstruktor daty utworzył datę z przesunięciem +7. Na serwerze (C #) dodaję wartość księgową jako milisekundy do epoki uniksowej new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(1401087600000). Rezultatem jest 5/19/2014 7:00:00 AM. Wydaje się więc, że getTime () podaje liczbę milisekund, w tym moje przesunięcie UTC.
xr280xr
1
Wiele komentarzy narzeka, że new Date(new Date().getTime())to nie działa. Mogę potwierdzić, że new Date(Date.UTC(2019, 8, 27, 0, 0, 0))rzeczywiście generuje czas UTC. Jeśli nie użyjesz Date.UTC(...), w strefie czasowej pojawią się daty z przesunięciem UTC.
Alex Barker
15
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();
James Skidmore
źródło
1
Obiekt daty musi być ustawiony na datę. Powyżej jest tylko przykładem.
James Skidmore,
5
Teraz zwraca „czwartek, 04 czerwca 2009 04:10:56 GMT”, co nie jest formatem ISO wymaganym w OP.
nickf
4
To zamienia go w ciąg znaków, który nie jest datą
Anthony
2
nie, właściwie powinna to być ciąg znaków reprezentujący datę według OP.
jcomeau_ictx
3
Po przekonwertowaniu na UTC wraca w formacie łańcuchowym, a następnie jak uzyskać dostęp do metod takich jak getMonth (), getDate () itp.
Sandeep sandy
10

Inne rozwiązanie do konwersji na UTC i zachowania go jako obiektu daty: (Działa poprzez usunięcie części „GMT” z końca sformatowanego ciągu, a następnie ponowne umieszczenie jej w konstruktorze daty)

var now = new Date();
var now_utc = new Date(now.toUTCString().slice(0, -4));

Musiałem to zrobić, aby połączyć się z biblioteką wyboru daty i godziny. Ogólnie jednak praca z datami w ten sposób jest złym pomysłem.

Użytkownicy zazwyczaj chcą pracować z czasem danych w czasie lokalnym, więc albo zaktualizuj kod po stronie serwera, aby poprawnie przeanalizować ciągi datetime z przesunięciami, a następnie przekonwertuj na UTC (najlepsza opcja) lub przekonwertuj na ciąg znaków UTC po stronie klienta przed wysłaniem do serwer (jak w odpowiedzi Willa Sterna)

CMcClymont
źródło
7

Czy próbujesz przekonwertować datę na taki ciąg?

Zrobiłbym funkcję, aby to zrobić, i chociaż jest to nieco kontrowersyjne, dodaj go do prototypu Date. Jeśli nie czujesz się komfortowo, możesz to ustawić jako samodzielną funkcję, przekazując datę jako parametr.

Date.prototype.getISOString = function() {
    var zone = '', temp = -this.getTimezoneOffset() / 60 * 100;
    if (temp >= 0) zone += "+";
    zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;

    // "2009-6-4T14:7:32+10:00"
    return this.getFullYear()   // 2009
         + "-"
         + (this.getMonth() + 1) // 6
         + "-"
         + this.getDate()       // 4
         + "T"
         + this.getHours()      // 14
         + ":"
         + this.getMinutes()    // 7
         + ":"
         + this.getSeconds()    // 32
         + zone.substr(0, 3)    // +10
         + ":"
         + String(temp).substr(-2) // 00
    ;
};

Jeśli potrzebujesz go w czasie UTC, po prostu zamień wszystkie funkcje get * na getUTC *, np .: getUTCFullYear, getUTCMonth, getUTCHours ... a następnie po prostu dodaj „+00: 00” na końcu zamiast przesunięcia strefy czasowej użytkownika.

pseudonim
źródło
1
To pierwszy przykład, jaki widziałem, który próbuje obsłużyć przesunięcie strefy czasowej, więc +1 za to. Znalazłem jednak kilka rzeczy - temp.substr (-2) powoduje błąd, ponieważ jest liczbą, a nie ciągiem, więc musisz zrobić coś takiego jak „temp = '' + temp;” po pierwsze, aby przekształcić go w ciąg. Wolę też, aby moje daty ISO były zerowane - myślę, że to czyni je bardziej standardowymi.
Mick Sear
@Mick - Zaktualizowałem, aby naprawić ten błąd. Użyłem String(temp)ponieważ inny sposób ( "" + temp) jest zgłaszane jako błąd JSLint te dni.
nickf
Jest to teraz znormalizowane jako toISOStringmetoda
Bergi,
7
date = '2012-07-28'; stringdate = new Date(date).toISOString();

powinien działać w większości nowszych przeglądarek. powraca 2012-07-28T00:00:00.000Zw przeglądarce Firefox 6.0

jcomeau_ictx
źródło
7

Moje zalecenie podczas pracy z datami to parsowanie daty w poszczególnych polach na podstawie danych wprowadzonych przez użytkownika. Możesz użyć go jako pełnego ciągu, ale bawisz się ogniem.

JavaScript może różnie traktować dwie równe daty w różnych formatach.

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

Nigdy nie rób czegoś takiego jak:

new Date('date as text');

Po przeanalizowaniu daty w poszczególnych polach na podstawie danych wprowadzonych przez użytkownika, utwórz obiekt daty. Po utworzeniu obiektu daty przekonwertuj go na UTC, dodając przesunięcie strefy czasowej. Nie mogę podkreślić, jak ważne jest użycie przesunięcia względem obiektu daty ze względu na czas letni (to kolejna dyskusja pokazująca dlaczego).

var year = getFullYear('date as text');
var month = getMonth('date as text');
var dayOfMonth = getDate('date as text');

var date = new Date(year, month, dayOfMonth);

var offsetInMs = ((date.getTimezoneOffset() * 60)  // Seconds
                 * 1000);                          //  Milliseconds

var utcDate = new Date(date.getTime + offsetInMs);

Teraz możesz przekazać datę do serwera w czasie UTC. Ponownie odradzam używanie jakichkolwiek ciągów dat. Przekaż go do serwera w podziale na najmniejszą szczegółowość, jakiej potrzebujesz, np. Rok, miesiąc, dzień, minutę lub jako wartość taką jak milisekundy z epoki unixu.

Timothy Gonzalez
źródło
Do Twojej wiadomości getYear jest usuwany ze standardów internetowych developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ghan
6

Jeśli często masz do czynienia z datami, warto skorzystać z moment.js ( http://momentjs.com ). Metodą konwersji na UTC byłoby:

moment(yourTime).utc()

Możesz użyć formatu, aby zmienić datę na dowolny, jaki chcesz:

moment(yourTime).utc().format("YYYY-MM-DD")

Dostępne są również opcje przesunięcia, ale istnieje dodatkowa biblioteka uzupełniająca do obsługi strefy czasowej ( http://momentjs.com/timezone/ ). Konwersja czasu byłaby tak prosta:

moment.tz(yourUTCTime, "America/New_York")
Adam Boostani
źródło
Jaka jest różnica między moment(yourTime).utc()i moment.utc(yourTime)? Zwykle używam tego drugiego.
ps0604,
5

Moje rozwiązanie utrzymuje tę samą datę bez względu na strefę czasową ustawioną po stronie klienta. Może ktoś uzna to za przydatne.

Mój przypadek użycia:

Tworzę aplikację do zrobienia, w której ustawiasz datę swojego zadania. Ta data powinna pozostać stała bez względu na strefę czasową, w której się znajdujesz.

Przykład. Chcesz zadzwonić do przyjaciela o 8 rano 25 czerwca.

Utworzysz to zadanie 5 dni przed (20 czerwca) podczas pobytu w Chinach.

Następnie tego samego dnia lecisz na kilka dni do Nowego Jorku.

Następnie, 25 czerwca, gdy jesteś jeszcze w Nowym Jorku, budzisz się o 7:30 rano (co oznacza, że ​​powinieneś otrzymać powiadomienie o zadaniu za 30 minut (nawet o 13:30 już w Chinach, gdzie byłeś podczas tworzenia zadanie)

Zadanie polega więc na ignorowaniu strefy czasowej. Oznacza to: „Chcę to zrobić o 8 rano w dowolnej strefie czasowej, w której będę”.

To, co robię, to powiedzmy: „Zakładam, że zawsze jesteś w strefie czasowej Londynu - UTC”.

Oznacza to, że - gdy użytkownik wybierze datę w swojej Strefie czasowej - przekonwertuję tę datę na tę samą datę w UTC. to znaczy. Wybierasz 8 rano w Chinach, ale przeliczam go na 8 rano w UTC.

Następnie - następnym razem, gdy otworzysz aplikację - odczytam datę zapisaną w UTC i przekonwertuję ją na tę samą datę w twojej bieżącej strefie czasowej - np. Konwertuję 8 rano w UTC na 8 rano w strefie czasowej Nowego Jorku.

To rozwiązanie oznacza, że ​​data może oznaczać coś innego, w zależności od tego, gdzie jesteś podczas ustawiania i gdzie ją czytasz, ale pozostaje stała w taki sposób, że „czuje się”, jakbyś zawsze był w tej samej strefie czasowej.

Napiszmy kod:

Po pierwsze - mamy 2 główne funkcje do konwersji z / na UTC ignorujące strefę czasową:

export function convertLocalDateToUTCIgnoringTimezone(date: Date) {
  const timestamp = Date.UTC(
    date.getFullYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds(),
  );

  return new Date(timestamp);
}

export function convertUTCToLocalDateIgnoringTimezone(utcDate: Date) {
  return new Date(
    utcDate.getUTCFullYear(),
    utcDate.getUTCMonth(),
    utcDate.getUTCDate(),
    utcDate.getUTCHours(),
    utcDate.getUTCMinutes(),
    utcDate.getUTCSeconds(),
    utcDate.getUTCMilliseconds(),
  );
}

Następnie zapisuję / czytam tę datę jak:

function saveTaskDate(localDate: Date) {
  // I convert your local calendar date so it looks like you've picked it being in UTC somewhere around London
  const utcDate = convertLocalDateToUTCIgnoringTimezone(localDate);
  api.saveTaskDate(utcDate);
}

function readTaskDate(taskUtcDate: Date) {
  // I convert this UTC date to 'look in your local timezone' as if you were now in UTC somewhere around london
  const localDateWithSameDayAsUTC = convertUTCToLocalDateIgnoringTimezone(taskUtcDate);

  // this date will have the same calendar day as the one you've picked previously
  // no matter where you were saving it and where you are now
}
pie6k
źródło
4

Właśnie odkryłem, że date.format.js Stevena Levithana w wersji 1.2.3 robi dokładnie to, czego chcę. Pozwala podać ciąg formatu dla daty JavaScript i zostanie przekonwertowany z czasu lokalnego na UTC. Oto kod, którego teraz używam:

// JavaScript dates don't like hyphens!    
var rectifiedDateText = dateText.replace(/-/g, "/");
var d = new Date(rectifiedDateText);

// Using a predefined mask from date.format.js.
var convertedDate = dateFormat(d, 'isoUtcDateTime'); 
dthrasher
źródło
9
To nie wydaje się być najlepszą odpowiedzią na twoje pytanie. Powinieneś ponownie rozważyć coś, co bezpośrednio odpowiada na twoje pytanie lub zadać pytanie inaczej.
hitautodestruct
1
Tak się składa, że ​​NAPRAWIAM ten dokładny skrypt (i wersję), ponieważ jest on niewystarczający dla IE7 i Firefox.
Barbarrosa
4

Odkryłem, że parsowanie daty wtyczki jQuery Globalization działa najlepiej. Inne metody miały problemy z przeglądarkami i rzeczy takie jak date.js nie były aktualizowane od dłuższego czasu.

Nie potrzebujesz także datePicker na stronie. Możesz po prostu wywołać coś podobnego do przykładu podanego w dokumentacji:

$.parseDate('yy-mm-dd', '2007-01-26');
Brian Ellis
źródło
1
To, że coś nie zostało zaktualizowane, nie oznacza, że ​​nie powinieneś tego używać. Date.js działał tak doskonale od lat, więc nie wymagał aktualizacji. Obiekt daty JS i używane formaty dat nie zmieniły się w ciągu ostatnich kilku lat, więc dlaczego skrypt, który nimi manipuluje? Date.JS jest absolutnie najlepszą dostępną biblioteką JS Date. W github jest kilka problemów, ale poza tym jest idealny. github.com/datejs/Datejs
thugsb
3

Ta funkcja działa dla mnie pięknie.

function ParseDateForSave(dateValue) {
    // create a new date object
    var newDate = new Date(parseInt(dateValue.substr(6)));

    // return the UTC version of the date
    return newDate.toISOString();
}
Will Strohl
źródło
2
var userdate = new Date("2009-1-1T8:00:00Z");
var timezone = userdate.getTimezoneOffset();
var serverdate = new Date(userdate.setMinutes(userdate.getMinutes()+parseInt(timezone)));

To da ci właściwą datę i godzinę UTC.
To dlatego, że getTimezoneOffset()da ci różnicę stref czasowych w minutach. Zalecam, aby nie używać, toISOString()ponieważ dane wyjściowe będą w postaci ciągu. Dlatego w przyszłości nie będzie można manipulować datą

Sanket Patel
źródło
2

Oto co zrobiłem w przeszłości:

var utcDateString = new Date(new Date().toUTCString()).toISOString();
Pradyumna Das
źródło
2

Jeśli potrzebujesz Date Object

Przekazywanie tylko ciągu daty Data zakłada, że ​​czas będzie przesunięty o 00:00 według strefy czasowej:

new Date('2019-03-11')
Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)

Jeśli dodasz bieżące godziny i minuty, otrzymasz odpowiednią datę:

new Date('2019-03-11 ' + new Date().getHours() + ':' + new Date().getMinutes())
Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)
klucz
źródło
1

Patrząc na twoje pytanie, jasne jest, że po prostu chcesz wysłać zakres dat do swojego zaplecza w celu dalszego przetwarzania.

Zakładam, że przestrzegasz standardowych wytycznych dotyczących danych, które oczekują, że dane będą miały określony format. Na przykład używam ODATA, która jest interfejsem API RESTfull, który oczekuje, że obiekty daty i godziny mają format: -

RRRR-MM-DDT00: 00: 00.

Można to łatwo osiągnąć za pomocą zamieszczonego poniżej fragmentu kodu (zmień format zgodnie z wymaganiami).

var mydate;//assuming this is my date object which I want to expose var UTCDateStr = mydate.getUTCFullYear() + "-" + mydate.getUTCMonth() + "-" + mydate.getUTCDate() + "T00:00:00";

Z drugiej strony jesteś w mojej sytuacji, w której otrzymałeś datę z backendu, a przeglądarka przekształca ją w lokalną datę. Z drugiej strony jesteś zainteresowany datą UTC, a następnie możesz wykonać następujące czynności:

var mydate;//assuming this is my date object which I want to expose var UTCDate = new Date(mydate);/*create a copy of your date object. Only needed if you for some reason need the original local date*/ UTCDate.setTime(UTCDate.getTime() + UTCDate.getTimezoneOffset() * 60 * 1000);

Fragment kodu powyżej zasadniczo dodaje / odejmuje czas dodawany / odejmowany przez przeglądarkę na podstawie strefy czasowej.

Na przykład, jeśli jestem w EST (GMT-5), a moja usługa zwraca obiekt daty / godziny = Śr 17 sierpnia 2016 00:00:00 GMT-0500 moja przeglądarka automatycznie odejmuje przesunięcie strefy czasowej (5 godzin), aby uzyskać mój czas lokalny. Więc jeśli spróbuję pobrać czas, dostanę Śr 16 sierpnia 2016 19:00:00 GMT-0500. To powoduje wiele problemów. Istnieje wiele bibliotek, które na pewno to ułatwią, ale chciałem podzielić się czystym podejściem JS.

Aby uzyskać więcej informacji, proszę spojrzeć na: http://praveenlobo.com/blog/how-to-convert-javascript-local-date-to-utc-and-utc-to-local-date/ gdzie mam Inspiracja.

Mam nadzieję że to pomoże!

Reeth
źródło
1

Ta metoda da ci: 2017-08-04T11:15:00.000+04:30i możesz zignorować zmienną strefy , aby po prostu ją zdobyć 2017-08-04T11:15:00.000.

function getLocalIsoDateTime(dtString) {
    if(dtString == "")
        return "";
    var offset = new Date().getTimezoneOffset();
    var localISOTime = (new Date(new Date(dtString) - offset * 60000 /*offset in milliseconds*/)).toISOString().slice(0,-1);
    //Next two lines can be removed if zone isn't needed.
    var absO = Math.abs(offset);
    var zone = (offset < 0 ? "+" : "-") + ("00" + Math.floor(absO / 60)).slice(-2) + ":" + ("00" + (absO % 60)).slice(-2);
    return localISOTime + zone;
}
AmirHossein Manian
źródło
1

Korzystając z pakietu moment, możesz łatwo przekonwertować ciąg dat UTC na nowy obiekt Date:

const moment = require('moment');
let b = new Date(moment.utc('2014-02-20 00:00:00.000000'));
let utc = b.toUTCString();
b.getTime();

Jest to szczególnie pomocne, gdy twój serwer nie obsługuje strefy czasowej i chcesz przechowywać datę UTC zawsze na serwerze i odzyskać ją jako nowy obiekt Date. Powyższy kod działał dla mojego wymagania podobnego problemu, dla którego przeznaczony jest ten wątek. Udostępnianie tutaj, aby pomóc innym. W żadnej odpowiedzi nie widzę dokładnie powyższego rozwiązania. Dzięki.

Bimal Jha
źródło
4
Chociaż może to odpowiedzieć na pytanie, nie ma wyjaśnienia Twojego kodu. Zaktualizuj swoją odpowiedź, aby wyjaśnić, co robisz. Dzięki!
Miroslav Glamuzina
1

const event = new Date ();

console.log (event.toUTCString ());

Sumit Khanduri
źródło
0

Wiem, że to pytanie jest stare, ale analizowałem ten sam problem, a jedną z opcji byłoby zamiast tego wysłanie date.valueOf () na serwer. funkcja valueOf () javascript Date wysyła liczbę milisekund od północy 1 stycznia 1970 UTC.

wartość()

weagle08
źródło
0

Tak właśnie musiałem to zrobić, ponieważ nadal chciałem, aby obiekt daty JavaScript był zmanipulowany jako data i niestety wiele z tych odpowiedzi wymaga przejścia do ciągu znaków.

//First i had a string called stringDateVar that i needed to convert to Date
var newDate = new Date(stringDateVar)

//output: 2019-01-07T04:00:00.000Z
//I needed it 2019-01-07T00:00:00.000Z because i had other logic that was dependent on that 

var correctDate = new Date(newDate.setUTCHours(0))

//This will output 2019-01-07T00:00:00.000Z on everything which allows scalability 
kjohnsonthecoder
źródło
0

przędza dodaje chwili

import moment from 'moment';

//local Js date to UTC using moment
const utcDate = moment.utc(moment(new date()).format('YYYY-MM-DDTHH:mm:ss')).valueOf();
console.log('UTC Date', utcDate);


// UTC to local date without moment
const localDate = convertUTCDateToLocalDate(new Date(utcDate))
console.log('UTC Date', moment(localDate).format('MMM D, YYYY HH:mm'));


function convertUTCDateToLocalDate(date) {

   let newDate = new Date(date.getTime() + date.getTimezoneOffset()*60*1000);

   const offset = date.getTimezoneOffset() / 60;
   const hours = date.getHours();

   newDate.setHours(hours - offset);

   return newDate;

}

Israt Jahan Simu
źródło
-8

Jeszcze prostsze

myvar.setTime(myvar.getTime() + myvar.getTimezoneOffset() * 60000);
ktoś
źródło
2
To jest niekompletne. setTimepolega na new Dateczymś, czego nie obejmujesz. Proszę uzupełnić odpowiedź.
random_user_name
czy ten mężczyzna wciąż żyje? dlaczego nawet nie wrócić do nas, powiedzieć coś lub edytować odpowiedzi?
Beznadziejny