【问题标题】:Display date and time received from Server as is, without compensating for timezone按原样显示从服务器接收的日期和时间,不补偿时区
【发布时间】:2021-06-20 22:51:35
【问题描述】:

我知道这个问题已被问过几次,但我尝试了不同的解决方案,但似乎没有一个适合我。

我的服务器/API 托管在南非,而连接的客户端则位于南非或迪拜。

向迪拜的用户显示日期时,应将日期显示为已在南非保存,而不是转换为他们的时区。

这是我的 .Net Core API 设置:

services.AddControllers().AddNewtonsoftJson(setup =>
            {
                setup.SerializerSettings.ContractResolver = new DefaultContractResolver();
                setup.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                setup.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
                setup.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                //options.SerializerSettings.DateFormatString = "mm/dd/yy, dddd";
            });

在 API 上,我使用的是DateTimeZoneHandling = Local

在 Angular 应用程序上,我写了一个 HttpInterceptor 来拦截传入的日期,尝试修改它们以正确显示,但这样做失败了。这是我的 Interceptor 中的一个方法示例,该方法尝试保留从 API 接收到的日期。

shiftDates(body): void {
        if (body === null || body === undefined) {
            return body;
        }

        if (typeof body !== 'object') {
            return body;
        }

        for (const key of Object.keys(body)) {
            const value = body[key];
            if (this.iso8601.test(value)) {
                console.log('Original', value); //2021-03-23T13:24:15.047+02:00
                let strippedDateString = String(value).split('+02');
                let strippedDate = new Date(strippedDateString[0]);
                console.log('Stripped Date: ', strippedDate); //Tue Mar 23 2021 13:24:15 GMT+0400 (Gulf Standard Time)
                console.log('New date: ', new Date(strippedDate.getFullYear(), strippedDate.getMonth(), strippedDate.getDate(), strippedDate.getHours(), strippedDate.getMinutes(), strippedDate.getSeconds())); //Tue Mar 23 2021 13:24:15 GMT+0400 (Gulf Standard Time)
                body[key] = new Date(strippedDate.getFullYear(), strippedDate.getMonth(), strippedDate.getDate(), strippedDate.getHours(), strippedDate.getMinutes(), strippedDate.getSeconds());
            } else if (typeof value === 'object') {
                this.shiftDates(value);
            }
        }
    }

即使我尝试了不同的方法来显示从服务器接收到的日期,Javascript 仍然会添加时区,并且 UI 上会显示不同的时间。

我做错了什么?我怎样才能防止这种情况发生?

例子:

假设一个用户,坐在迪拜,在 '2021/03/24 12:39:00' 创建一个收货订单,我的 API 会接收到这样的日期和时间,并将其正确保存在数据库中. 现在,当同一用户查看订单时,收集时间将显示为“2021/03/24 14:39:00”,这是不正确的,因为我希望它显示为“2021/03/24 12”: 39:00'。

Http Interceptor 是否可以使用这种方法

【问题讨论】:

  • 请问这里使用的stringify函数是什么?
  • hmm.. 似乎不是键入 String(value).split('+02'),而是使用 stringify(value)。改了,结果还是一样

标签: javascript angular typescript date .net-core


【解决方案1】:

我通过在 Angular 项目中实现以下两个 HttpInterceptors 解决了这个问题:

拦截器在不同时区拦截传出到服务器/API的日期:

@Injectable()
export class DateInterceptor implements HttpInterceptor {
    constructor(private datePipe: DatePipe) {}
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (req.method === 'POST' || req.method === 'PUT' || req.method === 'GET' ) {
            this.shiftDates(req.body);
        }
        return next.handle(req).pipe(tap(evt => {
            if (evt instanceof HttpResponse) {
                this.shiftDates(evt.body);
            }
        }))
      }
    
      shiftDates(body): void {
        if (body === null || body === undefined) {
            return body;
        }
    
        if (typeof body !== 'object') {
            return body;
        }
    
        for (const key of Object.keys(body)) {
            const value = body[key];
            if (value instanceof Date) {
                body[key] = this.datePipe.transform(value, 'MMM d, y, h:mm:ss a \'+0000\'');
            } else if (typeof value === 'object') {
                this.shiftDates(value);
            }
        }
    }
    
}

拦截传入日期并修改它们的拦截器:

@Injectable()
export class IncomingDateInterceptor implements HttpInterceptor {
    iso8601 = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/;
    constructor(private datePipe: DatePipe) { }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(tap(evt => {
            if (evt instanceof HttpResponse) {
                this.shiftDates(evt.body);
            }
        }))
    }

    shiftDates(body): void {
        if (body === null || body === undefined) {
            return body;
        }

        if (typeof body !== 'object') {
            return body;
        }

        for (const key of Object.keys(body)) {
            const value = body[key];
            if (this.iso8601.test(value)) {
                body[key] = Number(`${String(value).substr(0, 4)}`) + "-" + Number(`${String(value).substr(5, 2)}`) + "-" + Number(`${String(value).substr(8, 2)}`) + " " + Number(`${String(value).substr(11, 2)}`) + ":" + Number(`${String(value).substr(14, 2)}`) + ":" + Number(`${String(value).substr(17, 2)}`);
            } else if (typeof value === 'object') {
                this.shiftDates(value);
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2013-09-30
    • 2018-01-31
    • 2012-05-05
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    相关资源
    最近更新 更多