简述
- 使用现代化的 java.time 类。
- 永远不要使用
Date
/Calendar
/SimpleDateFormat
类。
示例:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc.
)
.truncatedTo( // Lop off finer part of this value.
ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object.
) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original.
.format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output.
) // Returns a `String`.
.replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
现代方法使用
java.time类,这些类多年前替代了可怕的旧日期时间类,例如
Calendar
和
SimpleDateFormat
。
想要当前日期和时间
使用
Instant
在UTC中捕获当前时刻。
Instant instant = Instant.now() ;
要以某个特定地区(时区)使用的挂钟时间来查看同一时刻,可以应用
ZoneId
获取
ZonedDateTime
。
以
continent/region
格式指定
适当的时区名称,例如
America/Montreal
、
Africa/Casablanca
或
Pacific/Auckland
。永远不要使用3-4个字母的缩写,如
EST
或
IST
,因为它们不是真正的时区,不被标准化,甚至不是唯一的!
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
或者,作为一种快捷方式,将ZoneId
传递给ZonedDateTime.now
方法。
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
java.time 类使用纳秒为分辨率。这意味着可以显示到小数点后九位的秒。如果您只需要三位,即毫秒,请截断。将您所需的限制作为 ChronoUnit
枚举对象传递。
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.truncatedTo(
ChronoUnit.MILLIS
)
以“dd/MM/yyyy HH:mm:ss.SS”格式
我建议在生成字符串时始终包括UTC偏移量或时区,以避免歧义和误解。
但如果您坚持,可以在生成表示日期时间值的字符串时指定特定格式。一个内置的预定义格式器几乎满足您所需的格式,但对于您想要空格的T
,需要进行修改。
String output =
zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )
;
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
不要使用用于向人类展示的文本交换日期时间值。
相反,使用专门为此目的定义的标准格式,可在ISO 8601中找到。
java.time在解析/生成字符串时默认使用这些ISO 8601格式。
在交换特定时刻时,始终包括UTC偏移量或时区指示器。因此,应避免使用上述所讨论的期望格式进行数据交换。此外,通常最好将时刻作为UTC交换。这意味着在java.time中是一个Instant
。您可以从ZonedDateTime
交换Instant
,有效地将时区调整为UTC以获得相同的时刻、时间线上的相同点,但具有不同的挂钟时间。
Instant instant = zdt.toInstant() ;
String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
这个ISO 8601格式在结尾使用
Z
代表协调世界时,发音为“Zulu”。
关于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
和更多。
Date.toString()
返回默认格式,无法更改。您需要使用SimpleDateFormat
来格式化字符串输出。 - Viruzzo.SSS
吗?Java不支持1/100秒。如果你使用.SS
,它可能不会按照你的预期行事。 - Peter Lawreyjava.util.Date
、java.util.Calendar
和java.text.SimpleDateFormat
这样的旧日期时间类现在已经成为遗留系统,被内置于Java 8及更高版本中的java.time类所取代。请参阅Oracle的教程。 - Basil Bourque