Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat 24h

I've got a SimpleDateFormat to parse a String into a Date:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");

When I'm parsing this:

format.parse("2011-08-29T12:44:00+0200");

The result will be, when using Date.toLocaleString:

29 aug. 2011 00:44:00

This should be ofcourse:

29 aug. 2011 12:44:00

And when I'm parsing this:

format.parse("2011-08-29T13:44:00+0200");

Then the result is as expected:

29 aug. 2011 13:44:00

How can I fix this?

like image 840
nhaarman Avatar asked Aug 29 '11 11:08

nhaarman


People also ask

How do I convert a date to 24 hour format?

The pattern dd/MM/yyyy hh:mm:ss aa is used for the 12 hour format and the pattern MM-dd-yyyy HH:mm:ss is used for the 24 hour format.

How do I change my android from 12 hour to 24 hour clock?

Tap Set. Tap Use 24- Hour Format to change the format to 24-hour time. Note that the time on the Notification bar reflects the change. You can return to 12-hour time by tapping Use 24-Hour Format again.

How do I format a simple date?

For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964. During parsing, only strings consisting of exactly two digits, as defined by Character.


2 Answers

Use HH instead of hh for the hours pattern:

H   Hour in day (0-23)  Number  0
k   Hour in day (1-24)  Number  24
K   Hour in am/pm (0-11)    Number  0
h   Hour in am/pm (1-12)    Number  12
like image 87
martin clayton Avatar answered Oct 05 '22 22:10

martin clayton


java.time through desugaring

I suggest that you use java.time, the modern Java date and time API, for your date and time work.

Your string is in ISO 8601 format. Define a formatter for it:

private static final DateTimeFormatter ISO_FORMATTER
        = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .appendOffset("+HHMM", "Z")
                .toFormatter(Locale.ROOT);

It could have been shorter with a format pattern string, but I prefer to reuse the built-in ISO_LOCAL_DATE_TIME, which already handles ISO 8601. As your question testifies, writing a format pattern string is error-prone. I have also specified that an offset of zero from UTC should be accepted as Z in accordance with ISO 8601 (the parser will accept +0000 too).

Parse like this:

    String isoString = "2011-08-29T12:44:00+0200";
    OffsetDateTime dateTime = OffsetDateTime.parse(isoString, ISO_FORMATTER);
    System.out.println(dateTime);

Output is:

2011-08-29T12:44+02:00

To obtain a string formatted for the user’s locale use a second formatter:

private static final DateTimeFormatter LOCALE_FORMATTER
        = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);

We still need not write any format pattern string. Format like this:

    String localeString = dateTime.format(LOCALE_FORMATTER);
    System.out.println(localeString);

Output is exactly what it should be. I ran in nl_NL locale and got:

29 aug. 2011 12:44:00

Please skip the next section.

What if I need an old-fashioned java.util.Date?

No one should use the Date class anymore. Only if you indispensably need a Date for a legacy API that you cannot afford to upgrade to java.time right now, convert:

    Date oldfashionedDate = Date.from(dateTime.toInstant());
    System.out.println(oldfashionedDate);

Funnily output will be time zone dependent. In my time zone I got:

Mon Aug 29 12:44:00 CEST 2011

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

  • Oracle tutorial: Date Time explaining how to use java.time.
  • Wikipedia article: ISO 8601
  • Java Specification Request (JSR) 310, where java.time was first described.
  • ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
  • Java 8+ APIs available through desugaring
  • ThreeTenABP, Android edition of ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
like image 30
Ole V.V. Avatar answered Oct 05 '22 22:10

Ole V.V.