将字符串解析为LocalDateTime

时间:2019-02-14 20:08:05

标签: java date datetime parsing java-8

以下内容可以正常工作:

String startDate = "2019-10-12T00:00:00.000-07:00"

LocalDateTime startDateTime = LocalDateTime.parse(startDate,
    DateTimeFormatter.ISO_ZONED_DATE_TIME);

但是,对于以下代码:

String startDate = "2019-10-12T00:00:00.000+07:00"

LocalDateTime startDateTime = LocalDateTime.parse(startDate,
    DateTimeFormatter.ISO_ZONED_DATE_TIME);

我得到一个例外:

  

抛出   java.time.format.DateTimeParseException:无法在索引23处解析文本'2019-10-12T00:00:00.000 07:00'

有人可以帮助我了解这里可能有什么问题吗?

3 个答案:

答案 0 :(得分:4)

我尝试使用LocalDateTime的相同解析在本地运行两个日期,并且它们都正确运行

我可以使用不同的日期(请注意区域偏移处的空格而不是+-来重新创建相同的错误)2019-10-12T00:00:00.000 07:00而不是2019-10-12T00:00:00.000+07:00。错误消息显示的是什么(但代码没有显示的)。

您确定显示的使用2019-10-12T00:00:00.000+07:00的代码版本是产生错误的实际版本吗?看来您一直在使用2019-10-12T00:00:00.000 07:00,然后导致错误。

答案 1 :(得分:4)

tl; dr

(A)如Andreas的注释中所述,错误消息中+字符的消失是可疑的。您可能有字符编码问题。我们这里没有足够的信息来进行诊断。

(B)使用OffsetDateTime而不是LocalDateTime来拟合数据。

OffsetDateTime
.parse( "2019-10-12T00:00:00.000+07:00" )
.toInstant()
.toString()
  

2019-10-11T17:00:00Z

请参阅此code run live at IdeOne.com

LocalDateTime是错误的课程

LocalDateTime类缺少任何时区或UTC偏移量的概念。因此,根据定义,它不能代表一个时刻。 LocalDateTime对象不是时间轴上的一个点。

但是,您的输入字符串表示与UTC的偏移量,即+07:00中的2019-10-12T00:00:00.000+07:00。您尝试将此值放入LocalDateTime是不合适的,是square peg in a round hole

当您指的是特定时刻,时间轴上的特定点时,切勿使用LocalDateTime。目前或过去,此类类几乎从未在面向业务的应用程序中使用。将来进行约会时,无论政客是否重新定义该地区的时区,只要您希望一天中的时间保持不变,都应使用此类。

OffsetDateTime

解析为OffsetDateTime对象。

您的输入字符串恰好完全符合文本日期时间格式的ISO 8601标准。 java.time 类在解析/生成字符串时默认使用这些格式。因此,无需指定格式设置模式。

String input = "2019-10-12T00:00:00.000+07:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input ) ;

UTC

要调整到UTC的挂钟时间(零偏移),请调用OffsetDateTime::withOffsetSameInstant。为了方便起见,请使用常量ZoneOffset.UTC

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC ) ;

或者直接在 java.time 中提取基本构建模块类的对象,即Instant。根据定义,Instant始终采用UTC。

Instant instant = odt.toInstant() ;

ZonedDateTime

要查看特定区域(时区)的人们在墙上时钟所看到的相同时刻,请应用ZoneId以获得ZonedDateTime

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:-2)

startDateTime中有一个额外的零 使用startDateTime =“ 2019-10-12T00:00:00.00 + 07:00”