简短概述
使用现代的java.time类替代Joda-Time。
LocalDateTime // Represent a date and time-of-day without the context of a time zone or offset-from-UTC. *Not* a moment, *not* a point on the timeline.
.parse( // Parse text into a date-time value.
"2010-10-03 18:58:07".replace( " " , "T" ) // Replace SPACE in middle with a `T` to comply with ISO 8601 standard used by default in *java.time* when parsing/generating strings.
) // Returns a `LocalDateTime` object.
.atZone( // Assign the time zone we know for certain was intended for this input.
ZoneId.of( "Europe/Moscow" ) // Real time zones are named in `Continent/Region` format, never 2-4 letter codes such as CST, PST, IST, CEST, etc.
) // Returns a `ZonedDateTime` object, a date with time-of-day and with a time zone assigned to determine a moment.
.toInstant() // Adjust from time zone to UTC.
.equals(
OffsetDateTime // Represent a date and time-of-day with an offset-from-UTC but not a full time zone.
.parse( "2010-10-03T16:58:07.000+02:00" ) // Parse a standard ISO 8601 string.
.toInstant() // Adjust from offset to UTC (in other words, an offset of zero hours-minutes-seconds).
) // Returns `boolean`.
真
详情
jarnbjo的回答是正确的,您误解了与UTC偏移量和时区值的含义。
现在,在2018年,Joda-Time项目处于维护模式。该项目的主要作者Stephen Colebourne继续创建了JSR 310并编写了其实现,即在OpenJDK中找到的java.time类。
第一个输入
您输入的字符串2010-10-03 18:58:07
几乎符合ISO 8601标准格式。为了符合要求,请将中间的空格替换为T
。
String input1 = "2010-10-03 18:58:07".replace( " " , "T" ) ;
那个字符串缺乏任何时区指示符或UTC偏移量。因此解析为
LocalDateTime
。
LocalDateTime ldt = LocalDateTime.parse( input1 ) ;
这个值并不代表一个瞬间,也不是时间轴上的一个点。如果没有区域或偏移量的上下文,它可能是全球时区范围内许多瞬间中的任何一个,该范围大约为26-27小时。在您的评论中,您透露该输入字符串似乎表示欧洲/莫斯科时区的日期和时间。因此,我们可以指定该区域来确定一个瞬间,即时间轴上的一个点。
ZoneId zMoscow = ZoneId.of( "Europe/Moscow" ) ;
ZonedDateTime zdtMoscow = ldt.atZone( zMoscow ) ; // Determine a moment by assigning a time zone.
zdtMoscow.toString(): 2010-10-03T18:58:07+04:00[Europe/Moscow]
第二个输入
您的第二个输入2010-10-03T16:58:07.000+02:00
符合标准ISO 8601格式。
此输入携带比UTC提前两小时的偏移量。因此,此字符串表示UTC中的14:58:07的当天时间。
我们可以将其解析为OffsetDateTime
以尊重给定的偏移量。
OffsetDateTime odt2 = OffsetDateTime.parse( "2010-10-03T16:58:07.000+02:00" ) ;
odt2.toString(): 2010-10-03T16:58:07+02:00
比较
这两个输入是否表示相同的时刻,相同的时间轴上的点?
一种比较方法是将两者都调整为UTC。根据定义,Instant
始终处于UTC中。
提示:养成以UTC思考、工作、存储、交换和记录的习惯。把UTC看作是“唯一真实的时间”。
Instant instant1 = zdtMoscow.toInstant() ; // Adjust from time zone to UTC.
Instant instant2 = odt2.toInstant() ; // Adjust from offset to UTC.
boolean equality = instant1.equals( instant2 );
当运行时,我们会看到结果末尾有一个
Z
。这意味着UTC,并发音为
Zulu
。确实,我们可以看到这两个值表示相同的时刻,即UTC下的下午3点。
instant1.toString(): 2010-10-03T14:58:07Z
instant2.toString(): 2010-10-03T14:58:07Z
equality: true
关于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
以及更多。
withZone(DateTimeZone.forID("Europe/Berlin"))
测试就可以通过了。虽然我不知道我们在莫斯科有服务器。 :D - wilfried