-2

I am unable to guess what is the miss in parsing AM/PM time in English to Spanish AM/PM time.

After going through internet I got different views but non of them is working.

Code:-

Locale locale = null;
String[] languageCountryArr = null;
String language = null;
String timeString = "04:17 AM";    
//  SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");

String localeString = Locale.getDefault().toString();

if (localeString.contains("es_")){
     language = "es";
}
else {
     language = "en";
}

locale = new Locale(language);    
simpleDateFormatForTime = new SimpleDateFormat("hh:mm a", locale);    
  try {    
        currentDateTime = simpleDateFormatForTime.parse(currentTimeString);     
        selectedDateTime = simpleDateFormatForTime.parse(selectedTimeString);     
    } catch (ParseException e) {    
        e.printStackTrace();    
    }    

In android :- If device language is English(United States) its working fine but when device language is Spanish its throwing below Exception

java.text.ParseException: Unparseable date: "04:17 AM" (at offset 6)    

Please explain where is the problem in this code?

Any help is appreciated.

  • 1
    Just asking maybe I'm lack of knowledge but why "es_"? Doesn't should be "es"? Or you could use "es", "ES" which is for local and country. – Yupi Jan 27 '17 at 18:12

4 Answers4

1

Simply try:

simpleDateFormatForTime = new SimpleDateFormat("hh:mm a");    

Point is: why do you want to create a formatter when you know that you will be parsing a Date that doesn't work "in Spanish"?

In other words: you know the format you intend to parse; so why do you make things more complicated by also adding that "es" locale when creating the formatter?!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Maybe "es_" is causing the problem o.O? – Yupi Jan 27 '17 at 18:17
  • @Yupi Maybe. But what would happen if "es" doesn't match? Then he creates an "English" locale in the first place. If it at all, I assume that an English locale has even less problems with parsing AM / PM time than a Spanish one. – GhostCat Jan 27 '17 at 18:18
1

When you always use the device locale i.e. system locale then the objection of @GhostCat should be considered. Otherwise, the line

if (localeString.contains("es_")) {

is wrong. Consider for example if a locale only contains the language and nothing else:

System.out.println(new Locale("es").toString()); // es
Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
0

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?

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • No one has explained the reason of the exception which I asked and I lost my earned reputation also. Could any one please explain reason of below exception. – Vikash Kumar Tiwari Jan 30 '17 at 06:06
  • @VikashKumarTiwari (a) Added a section near the top of my Answer showing that a simpler version of **your code works just fine** parsing your input string with Spanish locale using the legacy date-time classes. See that code [running live in IdeOne.com](http://ideone.com/s03kFF). (b) BTW, those legacy classes *really* are bad; you should drop them ASAP and move on to java.time. (c) Tip: Simplify your code as much as possible when posting: [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) – Basil Bourque Jan 30 '17 at 08:05
0

I also know that I can overcome this problem by using new features provided in Java 8. Simply I also can go through the oracle Java documentation and read that one. I want to face problems and find out their solution and for that reason we join StakOverFlow as for as I know. No one has explained the reason of the exception which I asked and I lost my 5 earned reputation. Could any one please explain reason of below exception.

java.text.ParseException: Unparseable date: "04:17 AM" (at offset 6)     
  • (a) Not a proper Answer. I suggest deleting before accumulating down-votes. You can make comments on Answers, make comments on your Question, or revise your Question (if the overall meaning remains the same). (b) You may have received down-votes (not from me) for a poorly written Question that is unclear and lacks the full detail needed for a proper recreation of the problem. For example, the values of `localeString`, `currentTimeString`, nor `selectedTimeString`. Compare your confusing example code to my straightforward version seen in [my Answer](http://stackoverflow.com/a/41906555/642706). – Basil Bourque Jan 30 '17 at 08:13