角度4:日期管道,UTC到当地时间的时间:如何告诉Angular当前时区?

时间:2017-09-29 14:05:45

标签: angular model-view-controller .net-core

我们正在使用Angular 4和用.net核心编写的MVC应用程序。 使用SignalR服务接收数据,集线器用C#编写。数据库提供了Datetime2(7)字段(T-SQL),即收到的内容,如下所示(对于日期字段):

dueDt:"2017-10-02T08:54:00"

此时间是UTC时间。我们住在+2时区。 现在,在CSHTML-File中,我们显示这个值:

 <small>Due: {{item.dueDt | date:'dd.MM.yy HH:mm'}}</small>

显示如下内容:     27.09.17 12:43 这很好,问题只是我们的时区不是+0而是+2,所以它应该显示 14:43 作为时间。

我已经读过Angulars DatePipe使用客户端本地时区的地方,但这似乎不会发生在这里。 (我用chrome,firefox和Edge试过这个 - 没有区别)。 有没有人有想法,为什么会这样,或者我怎么告诉Angular当地时区是什么? 我试过包括角度力矩,但它也没有真正起作用。 (我可以详细说明,如果这看起来很重要,但这是一个不同的问题)。

2 个答案:

答案 0 :(得分:3)

我使用moment.js做了类似的事情,但是Locale实际上特定于Locale和日期模式的每个用户配置:

import { Injectable, Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment';
import { Observable } from 'rxjs/Rx';
import { UserService } from '../security/user/user.service';

@Pipe({
    name: 'formatDate'
})
@Injectable()
export class DateTimePipe implements PipeTransform {

    constructor(private userService: UserService) {

    }

    /**
     * Asynchronous pipe, transforms a date into a formatted date.
     * The transformation is based on the 'locale' and 'pattern' properties from the current user preferences.
     * Usage: this pipe need to be followed by the'async' pipe, since it returns an Observable.
     */
    transform(value: any, showTime?: boolean): Observable<string> {
        if (value) {
            return this.userService.getPreferences()
                .map(prefs => {
                    const locale = prefs.preferences.get('locale');

                    let pattern;
                    if (showTime) {
                        pattern = prefs.preferences.get('dateTimeFormat') || 'DD/MM/YYYY HH:mm';
                    } else {
                        pattern = prefs.preferences.get('dateFormat') || 'DD/MM/YYYY';
                    }

                    moment.locale(locale);

                    let date = value instanceof Date ? value : new Date(value);
                    return moment(date).format(pattern);
                });
        }
        return Observable.of(value);
    }
}

你也可以随时改变本地

moment.locale('en_GB')

在此处查看完整选项https://momentjs.com/

答案 1 :(得分:0)

将Json Deserializer选项设置为UTC可以解决问题。

Json解串器的默认DateTime类型为RoundTripKind。当服务器端日期时间对象的Kind设置为Unspecified时,RoundTripKind不会在反序列化字符串的末尾添加Z。我猜这是正确的行为,但是如果我们假设所有日期对象实际上都是UTC时间,那么我们可以说服Json Deserializer考虑。

现在日期管道实际上得到的时间是UTC并以本地时间显示,显然是默认情况下

services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            });

"2019-03-15T21:00:00"之类的字符串将变成"2019-03-15T21:00:00Z"

请参阅:Newtonsoft Json.Net DateTimeZoneHandling setting