Why is 12:20 bred to 0:20 the next day?

I am using java.text.SimpleDateFormat to parse string representations of date / time values โ€‹โ€‹inside an XML document. I see all the times that have a value of 12 hours, shifted by 12 hours into the future, i.e. e. 20 minutes after noon, 20 minutes after midnight the next day are analyzed.

I wrote a unit test, which seems to confirm that the error occurs during parsing (I checked the return values โ€‹โ€‹from getTime() with the linux shell date command). Now I am wondering:

  • Is there an error in the parse() method?
  • Is there something wrong with the input line?
  • Am I using the wrong format string for input?

The input is taken from Yahoo YWeather. Here is the test and its output:

 public class YWeatherReaderTest { public static final String[] rgDateSamples = { "Thu, 08 Apr 2010 12:20 PM CEST", "Thu, 08 Apr 2010 12:20 AM CEST" }; public void dateParsing() throws ParseException { DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy K:maz", Locale.US); for (String dtsSrc : YWeatherReaderTest.rgDateSamples) { Date dt = formatter.parse(dtsSrc); String dtsDst = formatter.format(dt); System.out.println(dtsSrc); System.out.println(dtsDst); System.out.println(); } } } 
  Thu, 08 Apr 2010 12:20 PM CEST
 Fri, 09 Apr 2010 0:20 AM CEST

 Thu, 08 Apr 2010 12:20 AM CEST
 Thu, 08 Apr 2010 0:20 PM CEST

The second output line of the second iteration is a bit strange because 00:20 is not PM. However, the millisecond value of the date object corresponds to a (erroneous) time of 20 minutes at noon.

+4
source share
4 answers

The K SimpleDateFormat in SimpleDateFormat documented to use a clock starting at 0. Not sure what should happen if you ask it should parse a value out of range, such as 12 ... it probably acts like you type 00:20 PM , and then add an extra 12 hours.

If you want to use 12 for the first hour, try using h .

Why not horrify a damaged 12-hour watch system?

+3
source

If you use K in the format string, it goes from 0-11 (so 12:20 should really be 00:20). You can try using h instead, which goes from 1-12, which is what you expected.

http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html

+3
source

If you use K .... etc. etc .... (read bobince answer)

To force the expected behavior (and throw a parsing exception when using 12), set the lsient parser property to false:

 .... DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy K:maz", Locale.US); formatter.setLenient( false ); for (String dtsSrc : YWeatherReaderTest.rgDateSamples) { .... 

Conclusion:

 java YWeatherReaderTest Exception in thread "main" java.text.ParseException: Unparseable date: "Thu, 08 Apr 2010 12:20 PM CEST" at java.text.DateFormat.parse(DateFormat.java:335) at YWeatherReaderTest.dateParsing(YWeatherReaderTest.java:17) at YWeatherReaderTest.main(YWeatherReaderTest.java:25) 
+1
source

As a side mark: I highly recommend switching to Joda Time.

The java.util.date functions tend to just guess (which in your case was not what you expected). Joda Time throws an exception if it does not meet the specifications.

This is close to what you have:

 String s = "Thu, 08 Apr 2010 12:20 PM"; String format = "EEE, dd MMM yyyy h:ma"; DateTimeFormatter fmt = DateTimeFormat.forPattern(format).withLocale(Locale.US); System.out.println(fmt.parseDateTime(s)); 

Although Joda Time doesn't seem to support time zone parsing yet (see http://joda-time.sourceforge.net/api-release/org/joda/time/format/DateTimeFormat.html )

0
source

Source: https://habr.com/ru/post/1306403/


All Articles