首页 > 解决方案 > 角度材料日期选择器:1天前的日期解析UTC问题

问题描述

我知道有几个关于这个的线程,我都阅读了它们,但几天都无法解决这个问题。我可能找到了解决方案,但它似乎对我来说很脏。

因此,与其他用户一样,我对 datePicker 也有同样的问题。对我来说,它是 Angular Material Datepickermat-datepicker

当我记录值时,我得到正确的结果:

Wed Dec 24 1999 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

但在请求中是

1999-12-23T23:00:00.000Z

我尝试过的:

我已经添加{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }到我的component和我的app.module.ts. 这对我来说没有任何区别。

我的肮脏解决方案(在发送请求之前):

 let newDate= new Date(this.personalForm.get("dateOfBirth").value);
 newDate.setMinutes(newDate.getMinutes() - newDate.getTimezoneOffset());

当我这样做时,控制台会记录:

Wed Dec 24 1999 01:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

并且请求是正确的:

1997-12-24T00:00:00.000Z

但是,如果现在有人来自不同的时区,例如 GMT-0100,这将再次不起作用。如何正确解决这个问题?

如果有必要知道,我还会动态更改适配器:

 this._adapter.setLocale(this.translateService.currentLang);

标签: angulartypescriptdatepickerangular-materialutc

解决方案


回应您自己的错误答案……</p>

UTC 晚上 11 点 = 次日 00:00+01:00(同一时刻)

Wed Dec 24 1999 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit) 但在请求中它是

1999-12-23T23:00:00.000Z

这两个字符串代表相同的值。它们是观看同一时刻的两种方式。一个是 UTC 晚上 11 点,另一个是 UTC 前一个小时,因此它代表第二天的第一刻。在长达 24 小时的一天中,在 23 日晚上 11 点增加一小时需要经过午夜的钟声,到 24 日的第一刻。

解析

将您的输入字符串解析为Instant. 末尾的 Z 表示 UTC,发音为“Zulu”。根据定义,一个Instant代表 UTC 的时刻,始终是 UTC。

您的输入字符串采用标准 ISO 8601 格式。java.time类在解析/生成字符串时默认使用这些标准格式。所以不需要指定格式模式。

Instant instant = Instant.parse( "1999-12-23T23:00:00.000Z" ) ;

一个时刻(日期、时间和分配的时区或与 UTC 的偏移量)必须保存到类型类似于标准 SQL 类型的数据库列中TIMESTAMP WITH TIME ZONE。类似于类型的列TIMESTAMP WITHOUT TIME ZONE将是错误的数据类型。

要写入您的数据库,我们需要从基本构建块类切换Instant到更灵活的OffsetDateTime类。JDBC 4.2 及更高版本要求支持OffsetDateTimeJDBC 驱动程序中的类,而Instant支持是可选的。

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ; 

PreparedStatement通过带有占位符的 a 写入数据库?

myPreparedStatement.setObject( … , odt ) ;

恢复。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

这已经在 Stack Overflow 上讨论过很多次了。因此,搜索以了解更多信息。并且请在发布前彻底搜索 Stack Overflow。

LocalDate

如果您的目标只是跟踪一个日期,并且您并不真正关心时间和时区,那么您应该LocalDate在 JavaDATE中使用标准 SQL 中的列。


推荐阅读