使用 SimpleDateFormat 的日期解析不一致

发布于 2024-08-02 18:06:53 字数 453 浏览 9 评论 0原文

我对这个实在是摸不着头脑。我已经使用 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。到底是什么? - 它甚至不会一直解析为错误的日期!


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

I'm really scratching my head on this one. I've been using SimpleDateFormats with no troubles for a while, but now, using a SimpleDateFormat to parse dates is (only sometimes) just plain wrong.

Specifically:

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());

prints the string Wed Aug 19 00:00:00 EDT 2009. What the heck? - it doesn't even parse into the wrong date all the time!


Update: That fixed it beautifully. Wouldn't you know it, that was misused in a few other places as well. Gotta love debugging other people's code :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

污味仙女 2024-08-09 18:06:53

我认为您想要使用 HH 格式,而不是“hh”,以便您使用 00-23 之间的时间。 “hh”采用以 12 小时为增量的格式,因此假定时间为上午。

所以这

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());

应该打印出

2009 年 8 月 19 日星期三 12:00:00 EDT

I think you want to use the HH format, rather than 'hh' so that you are using hours between 00-23. 'hh' takes the format in 12 hour increments, and so it assumes it is in the AM.

So this

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());

Should print out

Wed Aug 19 12:00:00 EDT 2009

喜你已久 2024-08-09 18:06:53

The hour should be specified as HH instead of hh. Check out the section on Date and Time patterns in http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html

一生独一 2024-08-09 18:06:53

您正在打印日期的 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));

You're printing out the toString() representation of the date, rather than the format's representation. You may also want to check the hour representation. H and h mean something different. H is for the 24 hour clock (0-23), h is for the 12 hour clock (1-12), (there is also k and K for 1-24 and 0-11 based times respectively)

You need to do something like:

//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));
旧城烟雨 2024-08-09 18:06:53

tl;dr

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

java.time

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

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

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

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

LocalDateTime ldt = LocalDateTime.parse( input );

如果根据上下文您知道预期的偏移量,请应用它。也许它是为 UTC(偏移量为零)而设计的,我们可以在其中使用常量 < a href="http://docs.oracle.com/javase/8/docs/api/java/time/ZoneOffset.html#UTC" rel="nofollow noreferrer">ZoneOffset.UTC< /a>.

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 项目,现已在 维护模式,建议迁移到 java.time。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。

许多 java.time 功能都向后移植到 Java 6 和 Java 6。 ThreeTen-Backport 中的 7 并进一步适应 AndroidThreeTenABP(请参阅如何使用...)。

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。

tl;dr

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

java.time

Other Answers are correct but use legacy date-time classes. Those troublesome old classes have been supplanted by the java.time classes.

Your input string is close to standard ISO 8601 format. Tweak by replacing the SPACE in the middle with a T. Then it can be parsed without specifying a formatting pattern. The java.time classes use ISO 8601 by default when parsing/generating Strings.

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

The input data has no info about offset-from-UTC or time zone. So we parse as a LocalDateTime.

LocalDateTime ldt = LocalDateTime.parse( input );

If by the context you know the intended offset, apply it. Perhaps it was intended for UTC (an offset of zero), where we can use the constant ZoneOffset.UTC.

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

Or perhaps you know it was intended for a particular time zone. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文