我尝试从数据库中检索日期时间值,并且我已将upload_date_time声明为Instant,这就是该值在数据库中的存储方式。
然而,当我尝试从数据库中检索该值时,它给我的是“2022-03- 01 T14:00:00 Z”。
上传订单表
@NotNull
@Column(name = "upload_date_time", nullable = false)
private Instant uploadDateTime;
public Instant getUploadDateTime() {
return uploadDateTime;
}
public UploadOrder uploadDateTime(Instant uploadDateTime) {
this.uploadDateTime= uploadDateTime;
return this;
}
public void setUploadDateTime(Instant uploadDateTime) {
this.uploadDateTime= uploadDateTime;
}
服务
public PrePickOrderOverPickEmailDTO generateOverPickEmails() {
log.debug("Request to retrieve Upload data : {}");
List<UploadOrder> uploadOrders = uploadPickRepository.findAllByEmailSent(false);
String data = "";
for (UploadOrder order : uploadOrders) {
data = data +
"Upload Date: " + order.getUploadDateTime() +"\n" +
// do others
}
}
很好奇我在这里做错了什么。任何帮助都是很好的。谢谢
3条答案
按热度按时间qgzx9mmu1#
由于您注解数据库时区为UTC+10:00,因此您看到的是正确的。
2022-03-02T00:00+10:00
与2022-03-01T14:00:00Z
是相同的日期,Z是UTC(+0),因此它们都表示相同的日期值,只是用不同的时区表示。您可以通过以下方式进行验证:
若要将UTC瞬间定位到不同的区域,可以使用
Instant::atZone()
或Instant::atOffset()
。3df52oht2#
Instant
是一个时刻,没有指定任何时区,而实际存储的Instant
是UTC 3月1日下午2点,也就是AEST 3月2日午夜。当您通过SQL客户端查看此值时,SQL客户端将其转换为您的本地时间,因此您看到的是3月2日午夜。
当你用Java程序检索它时,你不需要指定时区或时间偏移量就可以显示它,当你对
Instant
这样做时,你可以看到它是UTC格式的。实际上,你需要做的是在显示
Instant
之前将其转换为LocalDateTime
-这样,你就可以在AEST中看到它,或者你的本地时区。LocalDateTime
类有一个名为ofInstant
的static
方法,它可以做到这一点。你需要传递你的时区的ZoneId
,如下所示。甚至像这样,获取系统默认时区。
vngu2lb83#
数据类型
问题上的标记表示您正在使用 Microsoft SQL Server 作为数据库引擎。
根据文档,您应该将列定义为数据类型
datetimeoffset
,该类型类似于SQL标准类型TIMESTAMP WITH TIME ZONE
,它存储一个时刻。smalldatetime
、datetime
或datetime2
类型。这些类型缺少时区或UTC偏移量的上下文。因此这些类型不能表示时刻,即时间线上的特定点。👉 给定使用名称
uploadDateTime
的代码片段,您的业务逻辑需要跟踪时刻,因此您的表列必须是datetimeoffset
类型。你的第一句话是:
我正在尝试检索日期时间值
如果您的意思是字面上的
datetime
类型,那么您的列使用了错误的类型,这将给您带来混乱和麻烦。OffsetDateTime
虽然您忽略了在
@Column
注解中使用的是什么框架库,但我不能肯定地说,但我可以猜测Instant
是错误的Java类。JDBC 4.2及更高版本的JDBC规范要求JDBC drivers支持 java.time 类。该规范将SQL标准类型
TIMESTAMP WITH TIME ZONE
的值Map到Java类java.time.OffsetDateTime
。Java类Instant
在JDBC中 * 根本没有 * Map。检索
OffsetDateTime
后,如果需要,可以提取Instant
:Instant instant = myOffsetDateTime.toInstant() ;
.