需要在 spring-boot 应用程序中将 Json 输入的本地日期保存到 oracle DB
Need to persist local date from Json input to oracle DB in a spring-boot application
我在 json 中输入了字符串格式 dd-MM-yyyy HH:mm:ss
格式的本地日期 [让它成为任何格式都没有问题],在 header 中有一个单独的字段时区 [例如: CST,CDT 等]。在 java 中,当我尝试使用此值和时区创建日期时,它是使用我的系统 [jvm 运行 系统] 时区创建的。
我需要使用输入时区保留输入的确切日期和时间。
我该怎么做 ?
我什至尝试将日期 object 和 @DateTimeFormat
放在 dto 而不是字符串中,但这没有用。
我想要这样的方法从输入的日期字符串和时区中获取本地日期。
public Date getLocalDate(String dateString, String localTimeZone) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss a");
formatter.setTimeZone(TimeZone.getTimeZone(localTimeZone));
return formatter.parse(dateString);
}
输入:dateString:“20-04-2019 20:15:00 AM”localTimeZone:"CDT".
预期输出:日期 object,值为 20-04-2019 20:15:00 AM CDT。
实际输出:与 IST 时区 IST-CDT 时差相同的日期
对于 Date
对象的真正含义存在误解。自 '01-01-1970 00:00:00 UTC'
以来只是几毫秒。换句话说,它总是 一个 UTC date/time,当您尝试打印它时,它会被默认格式化程序隐式转换为您当地的时区。
如果要同时存储 instant(即 UTC date/time)和时区,则必须使用 Calendar
对象.但是无论如何,如果你想在 Oracle 中同时存储时间和时区,你应该直接存储一个字符串,或者一个日期和一个字符串(用于时区),因为 AFAIK,Oracle DATE 字段没有时区的概念。
java.time
您使用的日期时间 classes 多年前被 JSR 310 中定义的 java.time classes 取代.
“CST”等2-4个字符的伪区不是时区。它们不是标准化的,甚至不是唯一的!例如:CST
是北美中部时间,也是中国标准时间。
真实时区的格式为 Continent/Region
。例如:Europe/Paris
或 Africa/Tunis
。请参阅维基百科中的列表。
要在时区上下文中表示日期和时间,请使用 ZonedDateTime
class。
要将日期时间与区域分开存储,请使用 LocalDateTime
和 ZoneId
classes。
数据库
您的评论表明希望将当前时刻存储在数据库中。
以 UTC 格式捕捉当前时刻。
Instant instant = Instant.now() ;
要与 JDBC 4.2 一起使用,请转换为 OffsetDateTime
。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
传递给准备好的语句。
myPreparedStatement.setObject( … , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
我在 json 中输入了字符串格式 dd-MM-yyyy HH:mm:ss
格式的本地日期 [让它成为任何格式都没有问题],在 header 中有一个单独的字段时区 [例如: CST,CDT 等]。在 java 中,当我尝试使用此值和时区创建日期时,它是使用我的系统 [jvm 运行 系统] 时区创建的。
我需要使用输入时区保留输入的确切日期和时间。 我该怎么做 ?
我什至尝试将日期 object 和 @DateTimeFormat
放在 dto 而不是字符串中,但这没有用。
我想要这样的方法从输入的日期字符串和时区中获取本地日期。
public Date getLocalDate(String dateString, String localTimeZone) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss a");
formatter.setTimeZone(TimeZone.getTimeZone(localTimeZone));
return formatter.parse(dateString);
}
输入:dateString:“20-04-2019 20:15:00 AM”localTimeZone:"CDT".
预期输出:日期 object,值为 20-04-2019 20:15:00 AM CDT。
实际输出:与 IST 时区 IST-CDT 时差相同的日期
对于 Date
对象的真正含义存在误解。自 '01-01-1970 00:00:00 UTC'
以来只是几毫秒。换句话说,它总是 一个 UTC date/time,当您尝试打印它时,它会被默认格式化程序隐式转换为您当地的时区。
如果要同时存储 instant(即 UTC date/time)和时区,则必须使用 Calendar
对象.但是无论如何,如果你想在 Oracle 中同时存储时间和时区,你应该直接存储一个字符串,或者一个日期和一个字符串(用于时区),因为 AFAIK,Oracle DATE 字段没有时区的概念。
java.time
您使用的日期时间 classes 多年前被 JSR 310 中定义的 java.time classes 取代.
“CST”等2-4个字符的伪区不是时区。它们不是标准化的,甚至不是唯一的!例如:CST
是北美中部时间,也是中国标准时间。
真实时区的格式为 Continent/Region
。例如:Europe/Paris
或 Africa/Tunis
。请参阅维基百科中的列表。
要在时区上下文中表示日期和时间,请使用 ZonedDateTime
class。
要将日期时间与区域分开存储,请使用 LocalDateTime
和 ZoneId
classes。
数据库
您的评论表明希望将当前时刻存储在数据库中。
以 UTC 格式捕捉当前时刻。
Instant instant = Instant.now() ;
要与 JDBC 4.2 一起使用,请转换为 OffsetDateTime
。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
传递给准备好的语句。
myPreparedStatement.setObject( … , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;