Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing simple times in hh:mmaa format

DateFormat formatter = new SimpleDateFormat("hh:mmaa");
formatter.parse("01:20pm")

I'm trying to parse times in the format of 01:20pm. If I run the above code, I get the following exception:

java.text.ParseException: Unparseable date: "01:20pm"
    at java.text.DateFormat.parse(DateFormat.java:366)

As far as the format I put in the SimpleDateFormat constructor, I don't see anything wrong. What went wrong here?

like image 992
Xiagua Avatar asked May 06 '16 04:05

Xiagua


People also ask

How do you parse time?

The Parse method tries to convert the string representation of a date and time value to its DateTime equivalent. It tries to parse the input string completely without throwing a FormatException exception.

What is SSS in time format?

SSS (3 S) is required for formating millisecond. i.e. "yyyy-MM-dd HH:mm:ss. SSS" is correct, but "yyyy-MM-dd HH:mm:ss.


2 Answers

Your system locale must not recognize AM/PM. Use a Locale that does. Something like,

DateFormat formatter = new SimpleDateFormat("hh:mmaa", Locale.US);

Or, in Java 8+, use the new java.time API like

LocalTime lt = LocalTime.parse("01:20pm", 
       DateTimeFormatter.ofPattern("hh:mmaa", Locale.US));
like image 137
Elliott Frisch Avatar answered Sep 28 '22 07:09

Elliott Frisch


Number and date parsing in Java uses the Locale to specify, well, locale-specific symbols. In this case, it is mostly the pm value that is being rejected.

To confirm this, here is a piece of code to exercise all available locales in the VM.

For locales that don't work, I was curious to see why, so instead of parsing a time, I format a valid time instead. Had to enable UTF-8 output, but it's interesting to see.

The really interesting part is that all Spanish (es) locales, except the United States variant (es_US) works fine. Hmmm........

Set<String> good = new TreeSet<>();
Set<String> bad = new TreeSet<>();
for (Locale locale : Locale.getAvailableLocales()) {
    try {
        new SimpleDateFormat("hh:mmaa", locale).parse("01:20pm");
        good.add(locale.toLanguageTag());
    } catch (ParseException e) {
        bad.add(locale.toLanguageTag());
    }
}
System.out.println("Good locales: " + good);

Date time = new SimpleDateFormat("hh:mmaa", Locale.ENGLISH).parse("01:20pm");
System.out.println("Bad locales:");
for (String languageTag : bad)
    System.out.printf("  %-5s: %s%n", languageTag, new SimpleDateFormat("hh:mmaa", Locale.forLanguageTag(languageTag)).format(time));

OUTPUT

Good locales: [be, be-BY, bg, bg-BG, ca, ca-ES, da, da-DK, de, de-AT, de-CH, de-DE, de-GR, de-LU, en, en-AU, en-CA, en-GB, en-IE, en-IN, en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-UY, es-VE, et, et-EE, fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, he, he-IL, hi, hr, hr-HR, id, id-ID, is, is-IS, it, it-CH, it-IT, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, nl, nl-BE, nl-NL, nn-NO, no, no-NO, pl, pl-PL, pt, pt-BR, pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sr, sr-BA, sr-CS, sr-Latn, sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, tr, tr-TR, uk, uk-UA, und]
Bad locales:
  ar   : 01:20م
  ar-AE: 01:20م
  ar-BH: 01:20م
  ar-DZ: 01:20م
  ar-EG: 01:20م
  ar-IQ: 01:20م
  ar-JO: 01:20م
  ar-KW: 01:20م
  ar-LB: 01:20م
  ar-LY: 01:20م
  ar-MA: 01:20م
  ar-OM: 01:20م
  ar-QA: 01:20م
  ar-SA: 01:20م
  ar-SD: 01:20م
  ar-SY: 01:20م
  ar-TN: 01:20م
  ar-YE: 01:20م
  cs   : 01:20odp.
  cs-CZ: 01:20odp.
  el   : 01:20μμ
  el-CY: 01:20ΜΜ
  el-GR: 01:20μμ
  es-US: 01:20p.m.
  fi   : 01:20ip.
  fi-FI: 01:20ip.
  ga   : 01:20p.m.
  ga-IE: 01:20p.m.
  hi-IN: ०१:२०अपराह्न
  hu   : 01:20DU
  hu-HU: 01:20DU
  ja   : 01:20午後
  ja-JP: 01:20午後
  ja-JP-u-ca-japanese-x-lvariant-JP: 01:20午後
  ko   : 01:20오후
  ko-KR: 01:20오후
  mt   : 01:20WN
  mt-MT: 01:20WN
  sq   : 01:20MD
  sq-AL: 01:20MD
  sv   : 01:20em
  sv-SE: 01:20em
  th   : 01:20หลังเที่ยง
  th-TH: 01:20หลังเที่ยง
  th-TH-u-nu-thai-x-lvariant-TH: ๐๑:๒๐หลังเที่ยง
  vi   : 01:20CH
  vi-VN: 01:20CH
  zh   : 01:20下午
  zh-CN: 01:20下午
  zh-HK: 01:20下午
  zh-SG: 01:20下午
  zh-TW: 01:20下午
like image 26
Andreas Avatar answered Sep 28 '22 07:09

Andreas