简而言之
- 不要使用
DateUtil
,无论它是什么。(也许是Apache DateUtils库?)
- 不要使用过时的糟糕日期时间类,如
java.util.Date
。
- 使用现代化业界领先的java.time类。
用于解析缺少偏移量的字符串的代码,然后将偏移量设置为UTC的零。
LocalDateTime // Represents a date and a time-of-day but without any concept of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
.parse(
"201801011000" ,
DateTimeFormatter.ofPattern( "uuuuMMddHHmm" )
)
.atOffset( ZoneOffset.UTC ) // Assign an offset-from-UTC. Do this only if you are CERTAIN this offset was originally intended for this input but was unfortunately omitted from the text. Returns an `OffsetDateTime`.
.toInstant() // Extract an `Instant` from the `OffsetDateTime`. Basically the same thing. But `Instant` is always in UTC by definition, so this type is more appropriate if your intention is to work only in UTC. On the other hand, `Instant` is a basic class, and `OffsetDateTime` is more flexible such as various formatting patterns when generating `String` object to represent its value.
使用java.time
Java的现代方法使用java.time类。这个领先行业的框架取代了非常麻烦的旧日期时间类,例如Date
,Calendar
和SimpleDateFormat
。
DateTimeFormatter
解析您的输入字符串。定义一个匹配的格式化模式。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmm" ) ;
String input = "201801011000" ;
LocalDateTime
将输入解析为LocalDateTime
,因为它缺少时区或UTC偏移量指示器。
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
缺少时区或偏移意味着这不代表一个时刻,也不是时间轴上的一个点。相反,这表示潜在的时刻在全球各地的时区范围内约为26-27小时。
如果您确定这个日期和时间是UTC中的一个时刻,请应用常量ZoneOffset.UTC来获取一个OffsetDateTime对象。
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
ZonedDateTime
您的问题比较模糊。听起来您可能知道特定的时区适用于此输入。如果是这样,请分配一个ZoneId
以获取一个ZonedDateTime
对象。
请注意,从UTC偏移量只是小时、分钟和秒数的简单数字。没有更多,也没有更少。相比之下,时区要复杂得多。时区是某个地区的人们使用的偏移量的过去、现在和未来变化的历史。
请指定一个正确的时区名称,格式为大陆/地区
,例如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。绝不要使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
Instant
快速调整回UTC的方法是提取一个Instant
对象。 Instant
始终处于UTC。
Instant instan = zdt.toInstant() ;
ISO 8601
提示:在交换日期时间值的文本时,不要使用自定义格式,而是仅使用标准ISO 8601格式。标准格式实用、易于机器解析、易于跨文化人类阅读。
java.time类默认使用ISO 8601格式进行解析/生成字符串。 ZonedDateTime::toString
方法明智地扩展了标准,以方括号中的区域名称作为附加信息。
Instant instant = Instant.parse( "2018-07-23T16:18:54Z" ) ; // `Z` on the end means UTC, pronounced “Zulu”.
String output = instant.toString() ; // 2018-07-23T16:18:54Z
在你的字符串中始终包括偏移量和时区。暂时省略偏移量/时区就像省略价格的货币一样:你只剩下一个含糊不清、毫无意义的数字。实际上,这比没有还要糟糕,因为它可能引起各种混乱和错误。
关于java.time
java.time框架内置于Java 8及更高版本中。这些类替代了老旧的传统日期时间类,例如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
了解更多信息,请参见Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,也不需要java.sql.*
类。
如何获取java.time类?
ThreeTen-Extra项目扩展了java.time的附加类。该项目是java.time可能未来添加的潜在试验场。您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
和更多。
java.util.Date
对象?如果是这样的话,那么这个问题已经被回答了很多次。我有点困惑,因为我不知道Mirth,而你提到了“classic js”-所以这是Java还是JavaScript? - Matt Johnson-Pintjava.util.Date
、java.util.Calendar
和java.text.SimpleDateFormat
这样的旧日期时间类现在已经过时,被内置于 Java 8 及更高版本的 java.time 类所取代。可以参考 Oracle 的 教程(https://docs.oracle.com/javase/tutorial/datetime/TOC.html)。 - Basil Bourque