2009-08-21 28 views
10

我真的在挠挠我的头脑。我一直在使用SimpleDateFormat s,但是现在,使用SimpleDateFormat解析日期(仅在某些时候)显然是错误的。使用SimpleDateFormat进行日期解析不一致

具体来说:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

输出字符串Wed Aug 19 00:00:00 EDT 2009。有没有搞错? - 它甚至不会一直解析错误的日期!


更新:问题解决了精美。你难道不知道吗?那在其他一些地方也被滥用了。喜欢调试其他人的代码:)

+3

我希望人们在犯错时会停止称呼“奇怪”和“怪异”的事物。 :/ – Bombe 2009-08-22 01:57:15

+0

对不起。我正在调试我的大四多年来写过的代码,我希望能够信任它。 – 2009-08-24 15:35:06

回答

25

我想你想使用的HH格式,而不是“HH”,让您在使用00-23小时之间。 'hh'以12小时为增量采用格式,因此它假定它在AM中。

所以这

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

应该打印出来

周三08月19日12:00:00 EDT 2009年

2

您正在打印日期的toString()表示,而不是格式的表示。您可能还想检查小时代表。 H和h意味着不同的东西。 H代表24小时制时钟(0-23),h代表12小时制时钟(1-12)(也分别有k和K代表1-24和0-11基准时间)

需要做的是这样的:

//in reality obtain the date from elsewhere, e.g. new Date() 
Date date = sdf.parse("2009-08-19 12:00:00"); 

//this format uses 12 hours for time 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
//this format uses 24 hours for time 
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

System.out.print(sdf.format(date)); 
System.out.print(sdf2.format(date)); 
+0

我会尝试,但我不认为它会解决问题。在我的应用程序中,我实际上并未转换回字符串。我将日期保存到数据库,并且在那里也是错误的。 – 2009-08-21 17:44:08

+0

您的格式字符串是否一致?有些数据库管理系统会自动转换值,如果他们可以弄清楚,有些不会。在db级应用具有不同格式的列中有问题的值?或来自一个有不同参数设置的连接? – DaveE 2009-08-21 18:03:01

1

TL;博士

LocalDateTime ldt = LocalDateTime.parse("2009-08-19 12:00:00".replace(" " , "T")); 

java.time

其他的答案是正确的,但使用传统的日期时间类。那些麻烦的旧类已经被java.time类所取代。

您的输入字符串接近标准ISO 8601格式。通过用T替换中间的空格来调整。然后可以在不指定格式模式的情况下解析它。解析/生成字符串时,java.time类默认使用ISO 8601。

String input = "2009-08-19 12:00:00".replace(" " , "T"); 

输入数据没有关于offset-from-UTC或时区的信息。所以我们解析为LocalDateTime

LocalDateTime ldt = LocalDateTime.parse(input); 

如果通过上下文知道预期偏移量,应用它。也许它的目的是为UTC(偏移量为零),我们可以使用常数ZoneOffset.UTC

OffsetDateTime odt = ldt.atOffset(ZoneOffset.UTC); 

或者你也许知道它是针对特定时区的。时区是偏移量用于处理异常情况(如夏令时(DST))的一组规则。

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Montreal")); 

关于java.time

java.time框架是建立在Java 8和更高版本。这些课程取代了老的麻烦日期时间课程,如java.util.Date,.Calendar,& java.text.SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。

大部分的java.time功能后移植到Java 6 和ThreeTenABP还适于Android(见How to use…)。

ThreeTen-Extra项目扩展java.time与其他类。这个项目是未来可能增加java.time的一个试验场。

相关问题