问题
I'm really scratching my head on this one. I've been using SimpleDateFormat
s 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 :)
回答1:
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
回答2:
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
回答3:
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));
回答4:
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.
来源:https://stackoverflow.com/questions/1313280/inconsistent-date-parsing-using-simpledateformat