Angular 4 日期管道由于时区而显示错误的日期 - 如何解决此问题?

问题描述 投票:0回答:8

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

<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 点。

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

angular date-pipe
8个回答
46
投票

在幕后,

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


10
投票

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

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

您可以以分钟为单位指定,例如 GMT-2,时区:'-120'

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

9
投票

html文件中,如下:

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

ts 文件中添加以下内容,

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

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


1
投票

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

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

现在,当您需要在 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));

1
投票

我在我的项目中使用了 Date

pipe
offset
,如下所示。

我为谁分忧。

在组件中

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

在 HTML 文件中

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

1
投票

请参阅此处了解其他解决方案。将日期格式指定为 UTC 解决了我的问题,我现在引用它,希望对其他人有帮助。


0
投票

创建了自定义日期管道

import { DatePipe } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'localizedDate',
})
export class LocalizedDatePipe implements PipeTransform {
  transform(value: any, locale: any, zone: any): any {
    var datePipe = new DatePipe(locale);

    var newDate = new Date(value);
    value = newDate.toUTCString(); // GMT

    if (locale == 'en-US' || locale == 'es-US') {
      value = datePipe.transform(value, 'MMM d, y', 'UTC');
    } else {
      value = datePipe.transform(value, 'd MMM y', 'UTC');
    }
    return value.replace('.', '').replace('.', '');
  }
}

HTML

<div *ngIf="{ locale: locale$ | async } as vm">
  <div class="card-publish-date">
    {{ item.publishedDate | localizedDate: vm.locale?.code:'UTC' | titlecase }}
  </div>
</div>

0
投票

我认为值得一提的是,您现在拥有可以轻松添加到 app.module.ts 的“DATE_PIPE_DEFAULT_OPTIONS”。

providers: [
    {provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: {timezone: 'UTC+2'}},
]

这将使所有日期都打印为 |日期:“短”在全球范围内的给定时区。

© www.soinside.com 2019 - 2024. All rights reserved.