Difference between java HH:mm and hh:mm on SimpleDateFormat

JavaDateFormat

Java Problem Overview


Whats the difference between kk:mm, HH:mm and hh:mm formats ??

    SimpleDateFormat broken = new SimpleDateFormat("kk:mm:ss");
    broken.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
    SimpleDateFormat working = new SimpleDateFormat("HH:mm:ss");
    working.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
    SimpleDateFormat working2 = new SimpleDateFormat("hh:mm:ss");
    working.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

    System.out.println(broken.format(epoch));
    System.out.println(working.format(epoch));
    System.out.println(working2.format(epoch));

prints:

24:00:00
00:00:00
05:30:00

Java Solutions


Solution 1 - Java

kk: (01-24) will look like 01, 02..24.

HH:(00-23) will look like 00, 01..23.

hh:(01-12 in AM/PM) will look like 01, 02..12.

so the last printout (working2) is a bit weird. It should say 12:00:00 (edit: if you were setting the working2 timezone and format, which (as kdagli pointed out) you are not)

Solution 2 - Java

Please take a look here

HH is hour in a day (starting from 0 to 23)

hh are hours in am/pm format

kk is hour in day (starting from 1 to 24)

mm is minute in hour

ss are the seconds in a minute

Solution 3 - Java

Actually the last one is not weird. Code is setting the timezone for working instead of working2.

SimpleDateFormat working2 = new SimpleDateFormat("hh:mm:ss"); working.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

kk goes from 1 to 24, HH from 0 to 23 and hh from 1 to 12 (AM/PM).

Fixing this error gives:

24:00:00
00:00:00
01:00:00

Solution 4 - Java

h/H = 12/24 hours means you will write hh:mm = 12 hours format and HH:mm = 24 hours format

Solution 5 - Java

Use the built-in localized formats

If this is for showing a time of day to a user, then in at least 19 out of 20 you don’t need to care about kk, HH nor hh. I suggest that you use something like this:

	DateTimeFormatter defaultTimeFormatter
			= DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
	System.out.format("%s: %s%n",
			Locale.getDefault(), LocalTime.MIN.format(defaultTimeFormatter));

The point is that it gives different output in different default locales. For example:

> en_SS: 12:00 AM > fr_BL: 00:00 > ps_AF: 0:00 > es_CO: 12:00 a.m.

The localized formats have been designed to conform with the expectations of different cultures. So they generally give the user a better experience and they save you of writing a format pattern string, which is always error-prone.

I furthermore suggest that you don’t use SimpleDateFormat. That class is notoriously troublesome and fortunately long outdated. Instead I use java.time, the modern Java date and time API. It is so much nicer to work with.

Four pattern letters for hour: H, h, k and K

Of course if you need to parse a string with a specified format, and also if you have a very specific formatting requirement, it’s good to use a format pattern string. There are actually four different pattern letters to choose from for hour (quoted from the documentation):

  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   h       clock-hour-of-am-pm (1-12)  number            12
   K       hour-of-am-pm (0-11)        number            0
   k       clock-hour-of-day (1-24)    number            24
   H       hour-of-day (0-23)          number            0

In practice H and h are used. As far as I know k and K are not (they may just have been included for the sake of completeness). But let’s just see them all in action:

	DateTimeFormatter timeFormatter
			= DateTimeFormatter.ofPattern("hh:mm a  HH:mm  kk:mm  KK:mm a", Locale.ENGLISH);
	System.out.println(LocalTime.of(0, 0).format(timeFormatter));
	System.out.println(LocalTime.of(1, 15).format(timeFormatter));
	System.out.println(LocalTime.of(11, 25).format(timeFormatter));
	System.out.println(LocalTime.of(12, 35).format(timeFormatter));
	System.out.println(LocalTime.of(13, 40).format(timeFormatter));

> 12:00 AM 00:00 24:00 00:00 AM > 01:15 AM 01:15 01:15 01:15 AM > 11:25 AM 11:25 11:25 11:25 AM > 12:35 PM 12:35 12:35 00:35 PM > 01:40 PM 13:40 13:40 01:40 PM

If you don’t want the leading zero, just specify one pattern letter, that is h instead of hh or H instead of HH. It will still accept two digits when parsing, and if a number to be printed is greater than 9, two digits will still be printed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2527039View Question on Stackoverflow
Solution 1 - JavakamjaginView Answer on Stackoverflow
Solution 2 - JavapeshkiraView Answer on Stackoverflow
Solution 3 - JavakdagliView Answer on Stackoverflow
Solution 4 - JavaRohit DodiyaView Answer on Stackoverflow
Solution 5 - JavaOle V.V.View Answer on Stackoverflow