tl;dr
(a) Cannot reproduce your exception problem.
(b) Avoid legacy date-time classes.
Your input parses correctly with Spanish Locale
using modern java.time classes.
LocalTime.parse(
"05:18 AM" ,
DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT )
.withLocale( new Locale("es_ES") )
).toString()
05:18
No problem
While I do not recommend using these legacy date-time classes, I did give it a shot for this Question…
I cannot reproduce your problem, using simpler version of your code with a locale of Spanish language. Also works as well with a locale of English in the United States. Granted, I did not run this in Android, I ran in the Oracle Java implementation, Java 8 Update 121, on macOS El Capitan.
String input = "04:17 AM";
Locale locale = new Locale ( "es" ); //Locale.US;
SimpleDateFormat f = new SimpleDateFormat ( "hh:mm a" , locale );
Date date = null;
try {
date = f.parse ( input );
} catch ( ParseException e ) {
e.printStackTrace ();
}
System.out.println ( "date.toString(): " + date );
date.toString(): Thu Jan 01 04:17:00 PST 1970
See this code with legacy date-time classes running live in IdeOne.com.
Avoid legacy date-time classes
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes built into Java 8 and later. Much of java.time is back-ported to Java 6, Java 7, and Android (see below).
LocalDate
You are trying to trade a time-of-day value into a date+time object. Instead use LocalTime
, designed expressly of a time-of-day without any date and without any time zone.
ISO 8601
If at all possible, use an alternate format for your time strings. The ISO 8601 standard defines sensible practical text formats for date-time values. Rather than using a 12-hour clock with AM
or PM
, use the standard 24-hour clock with hours 0-23. So use 05:18
instead of 05:18 AM
, and use 17:18
instead of 05:18 PM
.
Using the ISO 8601 formats are easy, as the java.time classes uses those formats by default when parsing/generating strings.
DateTimeFormatter
The DateTimeFormatter
class defines a parsing pattern to match your input strings. You can specify the formatting pattern, or let the class automatically localize for you.
String input = "05:18 AM" ;
Locale l = Locale.US ;
DateTimeFormatter fTimeUS = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( l );
LocalTime lt = LocalTime.parse( input , fTimeUS );
input: 05:18 AM
lt.toString(): 05:18
The same input can be parsed as Spanish as well as English, which seems to be the main point of your Question. Apparently AM
& PM
are used the same way in both languages.
DateTimeFormatter fTimeSpanishSpain = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( new Locale("es_ES") );
LocalTime lt2 = LocalTime.parse( input , fTimeSpanishSpain );
I do not understand why you would look for a Locale
involving Spanish and then create a Spanish-only Locale
from that. I refer that block of code with looking for "es_". Makes no sense. Please edit your Question to explain your concern or purpose.
If you need to generate a String representing the time-of-day value but localized for the user, you should ask the user for their preferred Locale
if vital. If not vital, the rely on the JVM’s current default locale. But do so explicitly to make your intention clear to other programmers. If the Locale
is omitted, the implicit use of the default creates ambiguity as to whether you so intended or if you, like so many programmers, failed to consider the issue.
Locale localeSpanishSpain = new Locale("es_ES") ;
DateTimeFormatter fTimeSpanishSpain = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( localeSpanishSpain );
String output = lt.format( fTimeSpanishSpain );
Live code
See this code run live in IdeOne.com.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.