【问题标题】:Angular 4 date pipe displays wrong date because of time zones - how to fix this?由于时区,Angular 4 日期管道显示错误的日期 - 如何解决这个问题?
【发布时间】:2017-12-20 15:46:27
【问题描述】:

我的每个对象都有一个日期值,我可以像这样打印:

<td> {{competition.compStart }}</td>

这是它的外观:

1931-05-31T00:00:00.000+0000

为了更改格式以使其更具可读性,我正在使用 Angular 日期管道:

<td> {{competition.compStart | date : "dd/MM/yyyy"}}</td>

有了这个结果:

30/05/1931

如您所见,它显示的是前一天(5 月 30 日而不是 5 月 31 日)。

据我了解,问题与时区有关,因为我在阿根廷,我们有 GMT-3,那么第 31 次负 3 小时的 00:00 将是 5 月 30 日晚上 9 点。

那么我怎样才能让它从字面上花时间而不是根据时区处理它,但仍然在管道中应用格式?

【问题讨论】:

  • 您期望的显示格式是什么?
  • 我在管道中使用的同一个:“dd/MM/yyyy”
  • 如何编写自定义管道并将日期转换为 '1931-05-31T03:00:00.000+0000' ,即增加 3 小时。
  • date 管道目前似乎无法实现您要查找的内容(但在路上),您可以查看github.com/angular/angular/issues/9324。您自己的自定义管道(例如,基于 moment.js)可能是一种可行的方法。

标签: angular date-pipe


【解决方案1】:

在幕后,DatePipe 使用语言环境在用户的时区显示日期。尝试使用客户的时区数据:

1931-05-31T00:00:00.000-0300 而不是1931-05-31T00:00:00.000+0000

您可以使用(new Date()).getTimezoneOffset()在几分钟内获得客户的偏移量

这实际上是DatePipe 的已知问题/限制。社区意识到了这一点。将来,您将能够将时区指定为参数之一 ({{ value | date:format:zone }})。

这里是github上的问题:https://github.com/angular/angular/issues/9324

对于更高级的日期操作,我推荐moment.js(更少的麻烦,更好的一致性,更少的测试,更简单的维护)。

编辑:已添加:

date_expression | date[:format[:timezone[:locale]]]

代码:https://github.com/angular/angular/blob/5.0.4/packages/common/src/pipes/date_pipe.ts#L137 文档:https://angular.io/api/common/DatePipe

【讨论】:

  • 您仍然建议在回答编辑后使用 moment 吗?
  • Moment 是一个非常有用的库,但是它也很大。如果可以,请仅使用 DatePipe。对于需要对日期进行大量操作的应用,我仍然建议您使用 moment。
  • 是的!这就是每个人都抱怨的……大小。现在你不能用 dataPipe 做的一件事是使用例如“Australia/Sydney”转换日期,你必须传递这样的代码“+4300”
  • 我有一个问题,当我使用夏令时之前的日期时,它不考虑额外的小时。使用此命令this.datePipe.transform("2018-11-01T00:00:00.000-04:00", 'MMMM yyyy', 'EST'),它以-5 小时而不是-4 小时计算,这是记录日期的时间。关于如何解决这个问题的任何想法?/
  • @DoubleA 这是因为 EST 只是 -5 小时偏移量的绰号。你和世界上的其他人仍然在同一条船上,并且必须先验地知道偏移量。在您的情况下,您需要知道日期时间是在夏令时期间,然后使用 EDT。
【解决方案2】:

对于 angular 5 及以上,您可以尝试在管道中添加时区,

默认采用用户机器的本地时区

您可以在几分钟内指定它,例如 GMT-2,时区:'-120'

{{ competition.compStart | date: 'short' : '-120'}}

【讨论】:

  • 这不是在操纵我的时间。无论我为"-120" 输入什么,它仍然显示相同的格式化日期
  • 我正在寻找使用 currentDateTime.toUTCString() 的替代方法,这是我用于获取相同时间的日期的日期管道:{{currentDateTime | date:'full':'GMT'}} 该区域可以采用“GMT”、“GMT”等值+2' 或 'EST'
  • 它还需要UTCUTC+1
  • 对于 -120,这将有助于节省日期。例如,在法国。 sep 和 nov 中的时区偏移量不同。即 2019-11-08 和 2019-08-08 的时区偏移量不同。
  • 如果时区是 UTC -6 那么它应该是 {{ Competition.compStart |日期:'short':'-0600'}} 如果 UTC 8:30 则 {{ Competition.compStart |日期:'短':'0830'}}
【解决方案3】:

我也遇到了同样的问题。 在保存数据之前,将日期格式转换为服务中使用的格式。例如,在我的 Java 中,它是“YYYY-MM-DD”。所以在保存所有数据之前以角度表示: 出生日期绑定到您的模板字段或仅显示。

this.birthdate=this.datePipe.transform(birthDate, 'yyyy-MM-dd'); 其中birthdate 不是日期对象而是字符串日期。

现在,当您需要在 UI 上显示日期时:

                let dd = (new Date(data.birthDate)).getUTCDate().toString();

                let mm = ((new Date(data.birthDate)).getMonth()).toString();
                let yy = (new Date(data.birthDate)).getFullYear().toString();

                this.birthDate = new Date(Number(yy), Number(mm), Number(dd));

【讨论】:

    【解决方案4】:

    我在我的项目中使用了日期pipeoffset,如下所示。

    我为谁担心。

    在组件中

    this.offset = new Date().getTimezoneOffset();
    

    在 HTML 文件中

    <div>{{deviceInfo?.updatedAt | date: 'dd/MM/yyyy hh:mm:ss' : 'offset'}}</div>
    

    【讨论】:

      【解决方案5】:

      html文件中,如下:

      {{ value | date:'yyyy-MM-dd hh:mm:ss a':'UTC+offset'}}
      

      ts文件添加以下内容,

      offset:number;
      this.offset = (new Date().getTimezoneOffset());
      

      可用于将 UTC 时间转换为系统时间(本地)

      【讨论】:

        猜你喜欢
        • 2018-07-16
        • 2020-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-01
        相关资源
        最近更新 更多