tl;博士
现代方法使用 java.time 类。
Instant.now() // Capture current moment in UTC.
.truncatedTo( ChronoUnit.SECONDS ) // Lop off any fractional second.
.plus( 8 , ChronoUnit.HOURS ) // Add eight hours.
.atZone( ZoneId.of( "America/Montreal" ) ) // Adjust from UTC to the wall-clock time used by the people of a certain region (a time zone). Returns a `ZonedDateTime` object.
.format( // Generate a `String` object representing textually the value of the `ZonedDateTime` object.
DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" )
.withLocale( Locale.US ) // Specify a `Locale` to determine the human language and cultural norms used in localizing the text being generated.
) // Returns a `String` object.
23/01/2017 15:34:56
java.time
仅供参考,旧的 Calendar 和 Date 课程现在是 legacy。由java.time 类取代。大部分 java.time 都向后移植到 Java 6、Java 7 和 Android(见下文)。
Instant
使用Instant 类捕捉UTC 中的当前时刻。
Instant instantNow = Instant.now();
instant.toString(): 2017-01-23T12:34:56.789Z
如果您只想要整秒,而不需要任何小数秒,请截断。
Instant instant = instantNow.truncatedTo( ChronoUnit.SECONDS );
instant.toString(): 2017-01-23T12:34:56Z
数学
Instant 班级可以做数学,增加了一定的时间。通过ChronoUnit 枚举指定要添加的时间量,TemporalUnit 的实现。
instant = instant.plus( 8 , ChronoUnit.HOURS );
instant.toString(): 2017-01-23T20:34:56Z
ZonedDateTime
要通过特定地区挂钟时间的镜头查看同一时刻,请应用ZoneId 以获取ZonedDateTime。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString(): 2017-01-23T15:34:56-05:00[美国/蒙特利尔]
生成字符串
您可以通过在DateTimeFormatter 对象中指定格式模式来生成所需格式的字符串。
请注意,格式化模式中的字母大小写很重要。问题的代码有 hh 表示 12 小时时间,而大写 HH 在 java.time.DateTimeFormatter 和旧版 java.text.SimpleDateFormat 中都是 24 小时时间 (0-23)。
java.time 中的格式代码与旧版SimpleDateFormat 中的格式代码相似,但并不完全相同。仔细研究课堂文档。在这里,HH 恰好工作相同。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" ).withLocale( Locale.US );
String output = zdt.format( f );
自动定位
考虑让 java.time 通过调用 DateTimeFormatter.ofLocalizedDateTime 来完全本地化 String 文本的生成,而不是硬编码格式模式。
顺便说一句,请注意时区和Locale 彼此之间没有任何关系;正交问题。一是关于content,意思是(挂钟时间)。另一个是关于表示,确定用于向用户展示该含义的人类语言和文化规范。
Instant instant = Instant.parse( "2017-01-23T12:34:56Z" );
ZoneId z = ZoneId.of( "Pacific/Auckland" ); // Notice that time zone is unrelated to the `Locale` used in localizing.
ZonedDateTime zdt = instant.atZone( z );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH ); // The locale determines human language and cultural norms used in generating the text representing this date-time object.
String output = zdt.format( f );
instant.toString(): 2017-01-23T12:34:56Z
zdt.toString(): 2017-01-24T01:34:56+13:00[太平洋/奥克兰]
输出:mardi 2017 年 1 月 24 日 à 01:34:56 heure avancée de la Nouvelle-Zélande
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
乔达时间
更新:Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。
Joda-Time 让这种工作变得更加容易。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTime later = DateTime.now().plusHours( 8 );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy HH:mm:ss" );
String laterAsText = formatter.print( later );
System.out.println( "laterAsText: " + laterAsText );
运行时……
laterAsText: 19/12/2013 02:50:18
请注意,此语法使用默认时区。更好的做法是使用显式 DateTimeZone 实例。