Moment.js przekształca się w obiekt daty

696

Za pomocą Moment.js nie mogę przekształcić prawidłowego obiektu momentu w obiekt daty ze strefami czasowymi. Nie mogę uzyskać prawidłowej daty.

Przykład:

var oldDate = new Date(),
    momentObj = moment(oldDate).tz("MST7MDT"),
    newDate = momentObj.toDate();
console.log("start date " + oldDate)
console.log("Format from moment with offset " + momentObj.format())
console.log("Format from moment without offset " + momentObj.utc().format())
console.log("(Date object) Time with offset " + newDate)
console.log("(Date object) Time without offset "+ moment.utc(newDate).toDate())
vadim.zhiltsov
źródło
1
Jakich wyników oczekujesz i jakie otrzymujesz?
Felix Kling
4
4 wiersz, więc uzyskaj mi wynik: <kod> (Obiekt daty) Czas z przesunięciem Cz 01 sierpnia 2013 15:23:49 GMT + 0300 (Финляндия (лето)) </code> Ale strefą czasową musi być MST7MDT
vadim.zhiltsov
Wednesday 24th 2019, 12:47:48 amczy można to przekonwertować 2019-04-23T19:17:48.000Z ? @ vadim.zhiltsov
Anupam Maurya
Obiekty daty nie mają strefy czasowej, są tylko przesunięciem w stosunku do 1970-01-01T00: 00: 00Z. Kiedy więc wywołujesz metodę toDate , zwrócony obiekt utracił informacje o strefie czasowej, które zostały dołączone do obiektu chwili .tz("MST7MDT"). Właśnie dlatego istnieją biblioteki takie jak moment.tz, aby uzupełnić możliwości gołych kości wbudowanego obiektu Date, który rozumie tylko UTC i strefę czasową hosta, to wszystko.
RobG

Odpowiedzi:

1236

Użyj tego, aby przekształcić obiekt momentu w obiekt daty:

From http://momentjs.com/docs/#/displaying/as-javascript-date/

moment().toDate();

Wydajność:

Tue Nov 04 2014 14:04:01 GMT-0600 (CST)
Chandrew
źródło
11
@Spencer - Tak, odpowiada na tytuł i toDaterzeczywiście jest sposobem uzyskania Dateobiektu z moment. Ale kod w treści pytania pyta o konwersję strefy czasowej - czego Datenie można zrobić. O ile czas górski nie jest strefą czasową użytkownika, to nie jestem pewien, jak to odpowiedziało na pytanie.
Matt Johnson-Pint
1
@Matt zależy tylko od tego, na którą część pytania patrzysz. Większość osób wyszukuje w Google i widzi, że ten tytuł pokrywa się z ich pytaniem i głosuje za odpowiedzią, która odpowiada na tytuł, a nie treścią pytania. To może wyjaśniać, dlaczego ma to najwięcej pozytywnych opinii, mimo że technicznie nie pomaga OP.
Spencer,
14
Czy to właściwie poprawna odpowiedź? Pytanie dotyczyło sposobu przekształcenia obiektu momentu w datę javascript, ale za pomocą TIMEZONE. Nadal powraca do lokalnej strefy czasowej po zmianie na obiekt daty javascript.
Niewymowny
1
Cześć chłopaki, sprawdź ten link momentjs.com/guides/#/warnings/js-date . Jest to odradzane i zostanie usunięte w nadchodzącym wydaniu głównym.
gtzinos
3
@gtzinos to, co łączysz i do którego się odwołujesz, to osobny problem i scenariusz, np. przekazanie łańcucha do momentu, w którym konstruktor moment("12/12/2011")dostanie tę wiadomość. Nie ma to nic wspólnego z chodzeniem od chwili do tej pory objmoment().toDate()
btbJosh
51

Tak długo, jak zainicjowałeś strefę czasową z danymi dla żądanych stref , Twój kod działa zgodnie z oczekiwaniami.

Poprawnie konwertujesz moment do strefy czasowej, co znajduje odzwierciedlenie w drugim wierszu wyniku z momentObj.format() .

Przełączenie na UTC nie tylko obniża przesunięcie, ale wraca do strefy czasowej UTC. Jeśli masz zamiar to zrobić, wcale nie potrzebujesz oryginalnego .tz()połączenia. Możesz po prostu zrobićmoment.utc() .

Być może po prostu próbujesz zmienić ciąg formatu wyjściowego? Jeśli tak, po prostu określ parametry, które chcesz zastosować do formatmetody:

momentObj.format("YYYY-MM-DD HH:mm:ss")

Odnośnie do ostatnich wierszy kodu - gdy wracasz do Dateobiektu toDate(), rezygnujesz z zachowania mom.js i wracasz do zachowania JavaScript. JavaScriptDate będzie zawsze drukowany w lokalnej strefie czasowej komputera, na którym działa. Nic nie może zrobić w tym momencie.

Kilka innych drobiazgów:

  • Podczas gdy konstruktor może zająć Date, zwykle najlepiej nie używać go. W przypadku „teraz” nie używaj moment(new Date()). Zamiast tego po prostu użyj moment(). Oba będą działać, ale są niepotrzebnie zbędne. Jeśli parsujesz z ciągu, przekaż ten ciąg bezpośrednio do momentu. Nie próbuj go parsować w Datepierwszej kolejności. Przekonasz się, że parser momentu jest znacznie bardziej niezawodny.

  • Strefy czasowe MST7MDTsą dostępne ze względu na kompatybilność wsteczną. Wywodzą się one ze stref czasowych w stylu POSIX, a tylko kilka z nich znajduje się w danych TZDB. O ile nie jest to absolutnie konieczne, powinieneś użyć klucza takiego jak America/Denver.

Matt Johnson-Pint
źródło
Dzięki Matt! Twoja odpowiedź była przydatna. Jak wspomniałeś o używaniu America / Denver zamiast MST7MDT, czy jest dostępna mapa dla tych mapowań? Korzystam z kilku takich stref czasowych, jak CET, EET, EST5EDT, CST6CDT, PST8PDT.
monish001,
czy można przekonwertować np .: „10:20 AM” (uzyskany czas ciągu od momentu (). format ('gg: mm A')) na obiekt Data?
baran
2
@ram - 1) jeśli masz chwilę, po prostu użyj .toDate(). 2) Nie używaj komentarzy do zadawania nowych pytań. Do tego służy duży przycisk „Zadaj pytanie” .
Matt Johnson-Pint,
22

.toDate tak naprawdę nie działało dla mnie, więc oto co zrobiłem:

futureStartAtDate = new Date(moment().locale("en").add(1, 'd').format("MMM DD, YYYY HH:MM"))

mam nadzieję że to pomoże

Mawaheb
źródło
2
Ta odpowiedź nie odpowiada na pytanie. Kod to długi sposób pisania moment().add(1, 'd').toDate().
RobG
12

Ponieważ momentjs nie ma kontroli nad obiektem daty javascript, znalazłem rozwiązanie tego problemu.

const currentTime = new Date();    
const convertTime = moment(currentTime).tz(timezone).format("YYYY-MM-DD HH:mm:ss");
const convertTimeObject = new Date(convertTime);

To da ci obiekt daty javascript z konwertowanym czasem

Yasith Prabuddhaka
źródło
2
To jedyna poprawna odpowiedź, która bezpośrednio odpowiada na pytanie.
Anish Sana
1
Właśnie tego chciałem. Oczekiwałem, że natywne daty właściwie reprezentują strefy czasowe, ale niestety się myliłem.
mklbtz,
1
Format „RRRR-MM-DD GG: mm: ss” nie jest obsługiwany przez Safari, więc wynik jest zerowy . Format powinien wynosić „RRRR-MM-DDTHH: mm: ss” (użyj formatu obsługiwanego przez ECMAScript, „T” między częściami daty i godziny).
RobG
4

Musiałem mieć informacje o strefie czasowej w swoim ciągu daty. Pierwotnie używałem, moment.tz(dateStr, 'America/New_York').toString();ale potem zacząłem dostawać błędy dotyczące podawania tego ciągu z powrotem do momentu.

Próbowałem, moment.tz(dateStr, 'America/New_York').toDate();ale potem straciłem potrzebne informacje o strefie czasowej.

Jedynym rozwiązaniem, które zwróciło przydatny ciąg daty ze strefą czasową, który można było przywrócić do chwili, byłomoment.tz(dateStr, 'America/New_York').format();

chovy
źródło
4
let dateVar = moment('any date value');
let newDateVar = dateVar.utc().format();

ładne i czyste !!!!

Emerson Bottero
źródło
To było jedyne rozwiązanie w moim przypadku, które opracowało format utc. Dzięki
Luis Febro,
3

Aby przekonwertować dowolną datę, na przykład utc:

moment( moment().utc().format( "YYYY-MM-DD HH:mm:ss" )).toDate()
kizoso
źródło
2
To naprawdę uratowało mi dzień!
HV Sharma
Ta odpowiedź jest zła. Dwukrotnie stosuje przesunięcie strefy czasowej: moment().utc()zwraca wartości dla UTC, a następnie .format( "YYYY-MM-DD HH:mm:ss" )zwraca ciąg, który został ustawiony na UTC bez przesunięcia strefy czasowej, więc jest analizowany jako lokalny. Nie pasuje do domyślnego formatu momentu, więc jest analizowany przez wbudowany parser. Nie pasuje też do żadnego formatu obsługiwanego przez ECMAScript, więc parsowanie zależy od implementacji. W każdym razie jest on analizowany jako lokalny, więc przesunięcie strefy czasowej jest ponownie stosowane podczas tworzenia wartości czasu dla daty.
RobG
3

Pytanie jest trochę niejasne. Zrobię co w mojej mocy, aby to wyjaśnić. Najpierw powinieneś zrozumieć, jak korzystać ze strefy czasowej . Zgodnie z tą odpowiedzią tutaj TypeError: moment (). Tz nie jest funkcją , musisz zaimportować moment ze strefy chwilowej zamiast domyślnej (oczywiście musisz najpierw zainstalować npm strefę czasową!). Ze względu na przejrzystość,

const moment=require('moment-timezone')//import from moment-timezone

Teraz, aby użyć funkcji strefy czasowej, użyj moment.tz („date_string / moment ()”, „time_zone”) ( więcej szczegółów na stronie https://momentjs.com/timezone ). Ta funkcja zwróci obiekt chwilowy z określoną strefą czasową. Ze względu na przejrzystość,

var newYork= moment.tz("2014-06-01 12:00", "America/New_York");/*this code will consider NewYork as the timezone.*/

Teraz, gdy spróbujesz przekonwertować newYork (obiekt momentu) za pomocą metody moment toDate () (konwersja formatu ISO 8601), otrzymasz czas z Greenwich w Wielkiej Brytanii. Aby uzyskać więcej informacji, przejdź do tego artykułu https://www.nhc.noaa.gov/aboututc.shtml , o UTC. Jeśli jednak chcesz tylko mieć czas lokalny w tym formacie (zgodnie z tym przykładem czas nowojorski), po prostu dodaj metodę .utc (true) , z arg true , do obiektu momentu. Ze względu na przejrzystość,

newYork.toDate()//will give you the Greenwich ,UK, time.

newYork.utc(true).toDate()//will give you the local time. according to the moment.tz method arg we specified above, it is 12:00.you can ofcourse change this by using moment()

W skrócie, moment.tz uwzględnia podaną strefę czasową i porównuje czas lokalny z czasem w Greenwich, aby dać ci wynik. Mam nadzieję, że było to przydatne.

Vijay Joshua Nadar
źródło
2

moment zaktualizował bibliotekę js od 06/2018.

var newYork    = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london     = newYork.clone().tz("Europe/London");

newYork.format();    // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format();     // 2014-06-01T17:00:00+01:00

jeśli masz swobodę korzystania z Angular5 +, lepiej użyj funkcji datePipe niż funkcji strefy czasowej tutaj. Muszę użyć moment.js, ponieważ mój projekt ogranicza się tylko do Angular2.

Feng Zhang
źródło
1

spróbuj (bez formatkroku)

new Date(moment())

Kamil Kiełczewski
źródło
new Date(moment())jest równoważne z new Date(). Strefa czasowa jest ustawiona tylko dla d .
RobG