【问题标题】:Resolving Moment.js Deprecation Warning in Angular App解决 Angular 应用程序中的 Moment.js 弃用警告
【发布时间】:2018-06-22 05:46:39
【问题描述】:

我在 Angular 应用程序中使用 moment.js 收到以下代码的警告:

moment(value).add(6, 'hours').format("MM/DD/YYYY");

打印到控制台的警告/错误是:

moment.js:293 弃用警告:提供的值不在 认可的 RFC2822 或 ISO 格式。时刻构建回退到 js Date(),它在所有浏览器和版本中都不可靠。非 不鼓励使用 RFC2822/ISO 日期格式,并将在 即将发布的主要版本。请参阅 http://momentjs.com/guides/#/warnings/js-date/ 了解更多信息。 参数:[0] _isAMomentObject:真,_isUTC:假,_useUTC:假, _l: undefined, _i: Apr 10, 2007, 10:00:00 PM, _f: undefined, _strict: undefined, _locale: [object Object]

我查看了警告中链接的文档页面,但我仍然不清楚需要更改哪些内容才能摆脱弃用警告。例如,我尝试添加一个空数组作为第二个参数:

moment(value, []).add(6, 'hours').format("MM/DD/YYYY");

...但是虽然这消除了错误,但我在视图中打印了“无效日期”,而不是实际日期。我需要如何调整此处的语法以消除警告?

更新:提供的值是使用 Angular 日期管道转换的 UTC 值。所以我要通过两个管道:首先是 Angular 日期管道,然后是这个自定义管道使用矩。完整的管道代码如下所示:

import { Pipe, PipeTransform } from '@angular/core';
const moment = require('moment');

@Pipe({name: 'timeZoneSync'})
export class TimeZoneSyncPipe implements PipeTransform {

    constructor() { }

    transform(value) {
        if (value) {
            return moment(value).add(6, 'hours').format("MM/DD/YYYY");
        }
    }
}

在我看来,我正在使用这样的两个管道:

  <input class="app-input" [ngModel]="client.dob | timeZoneSync | date:'medium'"
                                (ngModelChange)="client.dob=$event" name="inputField" type="text" /> 

【问题讨论】:

  • 看起来您提供给 moment 的日期 value 不是 ISO 或 RFC2822 格式。
  • 什么是value?可以分享一下吗,好像是这个问题
  • 究竟是什么让您感到惊讶? date:'medium' 不会产生任何一种所需的格式。你为什么还要使用它;为什么取一个日期然后将其格式化为字符串然后将其解析回日期然后再次将其格式化为字符串?
  • @jonsharpe 要回答您的问题,我希望日期采用便于阅读的格式。所以日期管道需要 1981-09-24T05:00:00.000Z 并给我一个用户友好的格式。但后来我使用 moment 将小时数添加到日期以解决时区同步问题。
  • “解决时区同步问题” - 现在这看起来像是XY problem,因为仅仅添加一个固定的偏移量并不是处理本地化日期时间的方法。接受的答案并不能解决这个问题。调查例如Moment Timezone。是的,看到有人明显忽略了他们发布的错误消息,没有仔细考虑他们编写的代码实际上做了什么,这令人恼火。如果不出意外,因为这正是您应该在创建minimal reproducible example 时要做的事情。 SO也会自动完成我的实际用户名。

标签: javascript angular date momentjs


【解决方案1】:

您的错误消息中有一个链接。它间接地把你引向这个:https://github.com/moment/moment/issues/1407

引用

不推荐使用非 iso 字符串的矩构造。这意味着您可以安全地进行操作

时刻("2014-04-25T01:32:21.196Z"); // iso 字符串,UTC 时区

时刻("2014-04-25T01:32:21.196+0600"); // 带时区的 iso 字符串

moment("2014 04 25", "YYYY MM DD"); // 带格式的字符串

但你不能可靠地做(因此它被弃用了)

时刻("2014/04/25");

moment("2014 年 4 月 24 日星期四 12:32:21 GMT-0700 (PDT)");

moment("一些看起来像日期的随机字符串");

基本上,任何为您的TimeZoneSyncPipe 提供价值的东西都不能很好地确保日期为ISORFC2822 格式。

更具体地说

'mediumDate' 参数等效于'MMM d, y'(例如Jun 15, 2015),它甚至不接近 ISO。

修复

尝试使用类似"client.dob | date:'yyyy-MM-ddTHH:mm:ss.sssZ' | timeZoneSync"的东西

树后的森林

@jonrsharpe 非常正确!我的回答解释了您看到错误的“原因”。但乔恩提出了一个更好的问题。为什么继续翻译date -> string -> date!?

示例

const parsedDate = moment("1981-09-24T05:00:00.000Z");
console.log(parsedDate.format("YYYY/MM/DD"));

Plunkr

【讨论】:

  • 它在 OP 要求的方面做得很好,这不是这两种格式中的任何一种。
  • 我希望日期采用易于阅读的格式。因此,日期管道采用 1981-09-24T05:00:00.000Z 并为我提供了一种用户友好的格式以显示在视图中。但后来我使用 moment 将小时数添加到日期以解决时区同步问题。
  • @Ademo 您可能希望以不同的顺序执行操作,然后:client.dob | timeZoneSync | date:'medium',即:首先,更正date;其次,将其翻译成字符串。实际上,您将可以在 timeZoneSync 管道中丢弃 .format("MM/DD/YYYY")
  • 谢谢,我也有同样的想法。现在正在修改订单。
  • 不,它应该适用于您在示例中提供的日期。至少我认为事情应该是这样的,基于我对这段代码的解释github.com/moment/moment/blob/develop/src/lib/create/…
猜你喜欢
  • 2018-03-27
  • 2017-03-23
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2017-03-12
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多