简而言之
Instant.ofEpochMilli ( 1_393_572_325_000L )
.toString()
2014年2月28日07:25:25 Z
详情
(a) 您似乎对日期的概念感到困惑。正如JB Nizet的回答所说,日期跟踪自Unix 纪元(1970年第一时刻)以来的毫秒数,在UTC时区(即没有时区偏移)。因此,日期没有时区†。它也没有“格式”。我们从日期的值中创建字符串表示形式,但日期本身不是字符串,也没有字符串。
(b)你提到了“UTC格式”。UTC不是我听说过的格式。
协调世界时(UTC)是时区的起点。伦敦格林威治皇家天文台以东的时区比UTC快一些小时和分钟。向西的时区比UTC慢。
你似乎在提到ISO 8601格式化字符串。你使用了可选格式,省略了(1)中间的T
和(2)最后的UTC偏移量。除非将字符串呈现给应用程序用户界面中的用户,否则建议您通常使用通常的格式:
2014-02-27T23:03:14+05:30
2014-02-27T23:03:14Z
('Z'代表Zulu或UTC,带有+00:00的偏移量)
(c) 避免使用三或四个字母的时区代码,它们既不标准化也不唯一。例如,“IST”可以表示印度标准时间或爱尔兰标准时间。
(d) 在发帖前请尽力搜索StackOverflow,你会找到所有答案。
(e) 避免使用Java附带的java.util.Date & Calendar类,它们经常出现问题。使用
Joda-Time库或Java 8的新java.time包(受Joda-Time启发,由JSR 310定义)。
java.time
Java.time类在解析和生成字符串时默认使用标准的ISO 8601格式。
OffsetDateTime odt = OffsetDateTime.parse( "2014-02-27T23:03:14+05:30" );
Instant instant = Instant.parse( "2014-02-27T23:03:14Z" );
将您从1970年第一时刻起的毫秒计数解析为UTC时间。
Instant instant = Instant.ofEpochMilli ( 1_393_572_325_000L );
instant.toString(): 2014-02-28T07:25:25Z
将该 Instant
转换为所需的时区。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString(): 2014年2月28日02时25分25秒,美国蒙特利尔时区
关于 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
, 以及更多。
Joda-Time
更新:Joda-Time项目现在处于维护模式,建议迁移到java.time类。
Joda-Time使用ISO 8601作为其默认格式。
Joda-Time DateTime
对象知道它所在的时区,而java.util.Date对象则不知道。
通常最好显式指定时区,而不是依赖于默认时区。
代码示例
long input = 1393572325000L;
DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );
DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneIreland = DateTimeZone.forID( "Europe/Dublin" );
DateTime dateTimeIndia = dateTimeUtc.withZone( timeZoneIndia );
DateTime dateTimeIreland = dateTimeIndia.withZone( timeZoneIreland );
// Use a formatter to create a String representation. The formatter can adjust time zone if you so desire.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FM" ).withLocale( Locale.CANADA_FRENCH ).withZone( DateTimeZone.forID( "America/Montreal" ) );
String output = formatter.print( dateTimeIreland );
将数据转储到控制台...
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeIreland: " + dateTimeIreland );
System.out.println( "output for Montréal: " + output );
当运行时...
dateTimeUtc: 2014-02-28T07:25:25.000Z
dateTimeIndia: 2014-02-28T12:55:25.000+05:30
dateTimeIreland: 2014-02-28T07:25:25.000Z
output for Montréal: vendredi 28 février 2014 02:25:25
†实际上,java.util.Date 确实有一个时区。该时区被分配在其源代码深处。然而,对于大多数实际目的,该类忽略了该时区。它的toString
方法应用JVM的当前默认时区,而不是内部时区。令人困惑吗?是的。这是避免旧的java.util.Date/.Calendar类的许多原因之一。改用java.time和/或Joda-Time。
Instant.now.toString()
简短而简单。 - arulraj.netjava.util.Date
、java.util.Calendar
和java.text.SimpleDateFormat
这样的旧日期时间类现在已经成为遗留系统,被内置于Java 8及更高版本中的java.time类所取代。请参阅Oracle的教程。 - Basil Bourque