Використання momentjs для перетворення дати в епоху, а потім у дату


80

Я намагаюся перетворити рядок дати в епоху, а потім епоху назад у рядок дати, щоб переконатися, що я надаю правильний рядок дати.

var epoch = moment("10/15/2014 9:00").unix(); // do I need to do .local()?
var momentDate = moment(epoch); // I've also tried moment.utc(epoch) 
var momentDateStr = momentDate.calendar();
alert("Values are: epoch = " + epoch + ", momentDateStr = " + momentDateStr);

Візуалізації

Values are: epoch = 1413378000, momentDateStr = 01/17/1970

Примітка: Я використовую наступну версію скрипта js moment, //cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment-with-locales.js


1
Я отримую це попередження для першого рядка: Попередження про припинення: момент побудови повертається до js Date. Це не рекомендується і буде вилучено у наступному великому випуску. Для отримання додаткової інформації зверніться до github.com/moment/moment/issues/1407 .
timaschew

Відповіді:


170

Тут є кілька помилок:

  • По-перше, термінологія. "Епоха" означає вихідну точку чогось. "Епоха Unix" - опівночі, 1 січня 1970 UTC. Ви не можете перетворити довільний "рядок дати в епоху". Ви, мабуть, мали на увазі "Час Unix" , який часто помилково називають "Часом Епохи".

  • .unix()повертає час Unix за цілі секунди, але momentконструктор за замовчуванням приймає позначку часу в мілісекундах . Натомість слід використовувати .valueOf()для повернення мілісекунд. Зауважте, що дзвінок .unix()*1000також буде працювати, але це призведе до втрати точності.

  • Ви аналізуєте рядок, не вказавши специфікатор формату. Це не є гарною ідеєю, оскільки такі значення, як 1/2/2014, можна трактувати як 1 лютого, так і як 2 січня, залежно від локалі, де працює код. (Ось чому ви також отримуєте попередження про припинення використання в консолі.) Натомість надайте рядок формату, який відповідає очікуваному вводу, наприклад:

    moment("10/15/2014 9:00", "M/D/YYYY H:mm")
    
  • .calendar()має цілком специфічне використання. Якщо ви наближаєтесь до дати, вона поверне значення, таке як "Сьогодні 9:00". Якщо це не те, що ви очікували, вам слід використовувати .format()функцію. Знову ж таки, ви можете передати специфікатор формату.

  • Щоб відповісти на ваші запитання в коментарях, Ні - вам не потрібно телефонувати .local()або .utc().

Склавши все це разом:

var ts = moment("10/15/2014 9:00", "M/D/YYYY H:mm").valueOf();
var m = moment(ts);
var s = m.format("M/D/YYYY H:mm");
alert("Values are: ts = " + ts + ", s = " + s);

На моїй машині в американському тихоокеанському часовому поясі це призводить до:

Значення: ts = 1413388800000, s = 15.10.2014 9:00

Оскільки вхідне значення інтерпретується з точки зору місцевого часу, ви отримаєте інше значення, tsякщо ви перебуваєте в іншому часовому поясі.

Також зверніть увагу, що якщо ви дійсно хочете працювати цілими секундами (можливо, втрачаючи точність), у моменту також є методи для цього. Ви можете використовувати, .unix()щоб повернути мітку часу за цілі секунди і moment.unix(ts)проаналізувати її назад до моменту.

var ts = moment("10/15/2014 9:00", "M/D/YYYY H:mm").unix();
var m = moment.unix(ts);

3
Веселий ярлик для .valueOf()->+moment()
Адам Мойса

14

http://momentjs.com/docs/#/displaying/unix-timestamp/

Ви отримуєте кількість unix секунд, а не мілісекунд!

Вам потрібно помножити його на 1000 або за допомогою valueOf()і не забудьте скористатися форматором, оскільки ви використовуєте формат, що не відповідає ISO 8601. А якщо ви забудете передати програму форматування, дата буде проаналізована за часовим поясом UTC або як недійсна дата.

moment("10/15/2014 9:00", "MM/DD/YYYY HH:mm").valueOf()

2
Будь ласка, зверніться до github.com/moment/moment/issues/1407, наведений вище метод наразі знецінений.
Кеннеді Няга,

3
Використовується кращий, точніший варіантvalueOf()
reectrix
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.