Moment.js 没有显示正确的时间

Posted

技术标签:

【中文标题】Moment.js 没有显示正确的时间【英文标题】:Moment.js doesn't show correct time 【发布时间】:2019-09-07 08:52:02 【问题描述】:

在我的计算机上本地运行我的 node.js 项目时,moment.js 显示正确的时间(2019-10-28T07:00:00.000Z,因为时刻已针对 DST 4 月 +02:00 和 +01:00 进行了调整十月)):

Moment 
  _isAMomentObject: true,
  _i: '2019-04-15T06:00:00.000Z',
  _f: 'YYYY-MM-DDTHH:mm:ss.SSSSZ',
  _tzm: 0,
  _isUTC: false,
  _pf:
    empty: false,
     unusedTokens: [],
     unusedInput: [],
     overflow: -1,
     charsLeftOver: 0,
     nullInput: false,
     invalidMonth: null,
     invalidFormat: false,
     userInvalidated: false,
     iso: true,
     parsedDateParts: [ 2019, 3, 15, 6, 0, 0, 0 ],
     meridiem: undefined,
     rfc2822: false,
     weekdayMismatch: false ,
  _locale:
   Locale 
     _calendar:
       sameDay: '[Today at] LT',
        nextDay: '[Tomorrow at] LT',
        nextWeek: 'dddd [at] LT',
        lastDay: '[Yesterday at] LT',
        lastWeek: '[Last] dddd [at] LT',
        sameElse: 'L' ,
     _longDateFormat:
       LTS: 'h:mm:ss A',
        LT: 'h:mm A',
        L: 'MM/DD/YYYY',
        LL: 'MMMM D, YYYY',
        LLL: 'MMMM D, YYYY h:mm A',
        LLLL: 'dddd, MMMM D, YYYY h:mm A' ,
     _invalidDate: 'Invalid date',
     ordinal: [Function: ordinal],
     _dayOfMonthOrdinalParse: /\d1,2(th|st|nd|rd)/,
     _relativeTime:
       future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: 'a minute',
        mm: '%d minutes',
        h: 'an hour',
        hh: '%d hours',
        d: 'a day',
        dd: '%d days',
        M: 'a month',
        MM: '%d months',
        y: 'a year',
        yy: '%d years' ,
     _months:
      [ 'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December' ],
     _monthsShort:
      [ 'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec' ],
     _week:  dow: 0, doy: 6 ,
     _weekdays:
      [ 'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday' ],
     _weekdaysMin: [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ],
     _weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
     _meridiemParse: /[ap]\.?m?\.?/i,
     _abbr: 'en',
     _config:
       calendar: [Object],
        longDateFormat: [Object],
        invalidDate: 'Invalid date',
        ordinal: [Function: ordinal],
        dayOfMonthOrdinalParse: /\d1,2(th|st|nd|rd)/,
        relativeTime: [Object],
        months: [Array],
        monthsShort: [Array],
        week: [Object],
        weekdays: [Array],
        weekdaysMin: [Array],
        weekdaysShort: [Array],
        meridiemParse: /[ap]\.?m?\.?/i,
        abbr: 'en' ,
     _dayOfMonthOrdinalParseLenient: /\d1,2(th|st|nd|rd)|\d1,2/ ,
  _a: [ 2019, 3, 15, 6, 0, 0, 0 ],
  _d: 2019-10-28T07:00:00.000Z,
  _isValid: true,
  _z: null 

但在我的服务器上,我得到了这个:

Moment 
  _isAMomentObject: true,
  _i: '2019-04-15T06:00:00.000Z',
  _f: 'YYYY-MM-DDTHH:mm:ss.SSSSZ',
     week: [Object],
     weekdays: [Array],
     weekdaysMin: [Array],
     weekdaysShort: [Array],
     meridiemParse: /[ap]\.?m?\.?/i,
     abbr: 'en' ,
  _dayOfMonthOrdinalParseLenient: /\d1,2(th|st|nd|rd)|\d1,2/ ,
  _a: [ 2019, 3, 15, 6, 0, 0, 0 ],
  _d: 2019-10-28T06:00:00.000Z,
  _isValid: true,
  _z: null 

日期错误地设置为 2019-10-28T06:00:00:000Z。 我在服务器上设置了时区sudo timedatectl set-timezone Europe/Oslo

如果我在服务器上使用moment.isDST() 作为日期,它会正确地给出我四月的true 和十月的false

我不确定如何在服务器上或在我的代码中解决这个问题?

【问题讨论】:

最初的日期是什么时候?另外,您的意思是“10 月的-1”,对吧? 原始日期是 2019-04-15T06:00:00.000Z 输入的 4 月,时间 UTC +02:00 和 DST。 10 月份奥斯陆没有 DST,因此 10 月份显示的正确时间将是 2019-10-28T07:00:00.000Z,因为我们有 UTC +01:00 让我们看看我是否正确理解了您的问题。您正在使用2019-04-15T06:00:00.000Z 创建时刻对象,在您当地的时区它应该是2019-04-15T08:00:00.000 UTC+02:00,这是正确的。添加到此日期后,例如6 months,它应该是(在您当地的时区):2019-10-15T07:00:00.000 UTC+01:00,但不是? 是的,没错。我运行 node.js 的本地桌面计算机正确执行此操作,但不是我的 Linux 服务器 那么您当地时区(10 月)的日期时间到底是多少? dt.toLocaleString() 的输出是什么? 【参考方案1】:

我想我解决了。通过回答来自 Styx 的问题,我终于意识到在 docker 容器中运行的服务器应用程序没有正确的时区。通过在docker-compose.yml 文件中设置environment: TZ: "Europe/Oslo",这解决了问题,我现在得到了正确的时间。

【讨论】:

一般来说,不应将服务器端应用程序设计为依赖于特定的本地时区。尽管这可能会解决您目前遇到的问题,但它并不能为您未来的成功做好准备。考虑您的应用程序是否需要支持来自第二个或更多时区的用户。可以这么说,你会把自己画在一个角落里。

以上是关于Moment.js 没有显示正确的时间的主要内容,如果未能解决你的问题,请参考以下文章

moment.js、day.js怎么生成每周,每月

moment.js的方法总结

带有 Moment.js 的 Jquery 数据表的终极日期/时间排序插件

moment.js的常用方法

moment.js 格式化显示时间差

使用 moment.js 将跨越秋季 DST 边界的一系列非 UTC 时间戳转换为 UTC 时间戳的正确方法?