我有模式"yyyy-MM-dd'T'HH:mm:ssZ"
的字符串,我想使用Java将其转换为ZonedDateTime
格式。
输入字符串示例:"2019-11-23T10:32:15+12:24"
输出:ZonedDateTime
编辑:我已经尝试过了,但它不起作用。
ZonedDateTime convertToZonedDateTime(final String source) {
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = dateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
我有适用于字符串“ 2018-04-05 19:58:55”的解决方案,它会产生输出2018-04-05T19:58:55 + 05:30 [Asia / Kolkata],但是当我将函数中的模式更改为“ yyyy-MM-dd'T'HH:mm:ssZ“,并将字符串输入到2019-11-23T10:32:15 + 12:24,由于ParseException:无法解析的数据,它不起作用。
我需要API的ZonedDateTime格式,该格式需要使用该格式的输入时间。
最佳答案
tl; dr
OffsetDateTime // Represent a moment as a date with time-of-day in the context of an offset-from-UTC (a number of hours-minutes-seconds).
.parse( // Parse text into a date-time object.
"2019-11-23T10:32:15+12:24" // The offset of +12:24 looks suspicious, likely an error.
) // Returns an `OffsetDateTime` object.
从语义上讲,我们现在已经有了一个
OffsetDateTime
对象。但是您声称使用的是需要
ZoneDateTime
对象的API。我们没有适用的时区,因此我们应用UTC(零时分分钟秒)。OffsetDateTime // Represent a moment as a date with time-of-day in the context of an offset-from-UTC (a number of hours-minutes-seconds).
.parse( // Parse text into a date-time object.
"2019-11-23T10:32:15+12:24" // The offset of +12:24 looks suspicious, likely an error.
) // Returns an `OffsetDateTime` object.
.atZoneSameInstant( // Convert from `OffsetDateTime` to `ZonedDateTime` by applying a time zone.
ZoneOffset.UTC // This constant is a `ZoneOffset` object, whose class extends from `ZoneId`. So we can use it as a time zone, though semantically we are making a mess.
) // Returns a `ZonedDateTime` object.
.toString() // Generate text in standard ISO 8601 format.
参见此code run live at IdeOne.com。
2019-11-22T22:08:15Z
警告:示例输入字符串的偏移量对我来说似乎是错误的。
细节
您需要了解一些有关日期时间处理的概念。
偏移量
距UTC的偏移量仅比格林威治皇家天文台绘制的子午线早或晚数小时-数秒。
在Java中,我们用
ZoneOffset
类表示偏移量。偏移量上下文中的日期和时间用OffsetDateTime
类表示。这样的对象表示时刻,即时间轴上的特定点。时区
时区更多。时区是特定地区人民过去,现在和将来对偏移量的更改的历史记录。这些变化是由政客决定的。因此,这些更改可能是任意的,反复无常的,并且经常出乎意料地发生,常常很少甚至没有警告。例如,在北美,大多数地区都采用了夏令时(DST)废话,导致偏移每年更改两次。当前,政客们热衷于退出DST更改,而在“夏令时”永久保持全年无休,比标准时间早一小时。
有一个数据库将这些更改分类。 tZ数据是IANA维护的文件,列出了全球范围内的更改。您很可能会在主机OS,企业质量的数据库管理系统(例如Postgres)和Java虚拟机中找到这些数据的副本。确保随着您关心的区域的变化而使这些保持最新。
时区的名称格式为
Continent/Region
。例如,Africa/Tunis
,Europe/Paris
和Asia/Kolkata
。OffsetDateTime
因此,“ 2019-11-23T10:32:15 + 12:24”之类的输入字符串没有时区指示符,只有偏移量。因此,我们必须将其解析为
OffsetDateTime
。OffsetDateTime odt = OffsetDateTime.parse( "2019-11-23T10:32:15+12:24" ) ;
以
ZonedDateTime
的身份要求没有任何意义。我们不能仅从偏移量可靠地确定时区。许多时区可能会在某些品脱时间上共享偏移量。同样,该特定输入字符串
2019-11-23T10:32:15+12:24
是可疑的。十二小时二十四分钟的偏移量不会映射到任何当前时区。您确定正确吗?您可以通过指定要在调整中使用的时区将
OffsetDateTime
转换为ZonedDateTime
。我建议使用UTC。尽管这在技术上可行,但从语义上来说却令人困惑。 UTC中的时刻最好用OffsetDateTime
而不是ZonedDateTime
表示。但是显然,您正在与需要ZonedDateTime
的代码进行互操作,所以请耐心等待。ZonedDateTime zdt = odt.atZoneSameInstant( ZoneOffset.UTC ) ;
Instant
提示:通常,应将API作为
Instant
对象来传递时间,根据定义,该对象始终位于UTC中。LocalDateTime
您提出了另一个字符串输入“ 2018-04-05 19:58:55”。此输入缺少任何时区或UTC偏移量指示符。因此,我们不知道这是否意味着在日本东京将近-8PM,在法国图卢兹将近-8PM,或者在美国俄亥俄州托莱多将近-8PM –所有这些事件相隔数小时,发生在时区上的不同时间点。
该值必须解析为
LocalDateTime
。将中间的SPACE替换为T
以符合ISO 8601标准格式。LocalDateTime ldt = LocalDateTime.parse( "2018-04-05 19:58:55".replace( " " , "T" ) ) ;
结果对象不代表时刻,也不是时间轴上的一点。这样的物体代表了大约26-27小时(全球时区范围)内的潜在时刻。
ZonedDateTime
如果确定输入字符串用于特定时区,请应用
ZoneId
以获得ZonedDateTime
。然后,您确定了一个时刻,即时间轴上的特定点。ZoneId z = ZonedId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如
java.util.Date
,Calendar
和SimpleDateFormat
。要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
现在位于Joda-Time中的maintenance mode项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用与JDBC driver或更高版本兼容的JDBC 4.2。不需要字符串,不需要
java.sql.*
类。在哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7
大多数java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。
Android
更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26),ThreeTenABP项目改编为ThreeTen-Backport(如上所述)。请参见How to use ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
和more。
关于java - 将OffSetDateTime字符串转换为ZonedDateTime Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59378786/