Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joda-Time parse datetime in different language

I am trying to parse time with Joda-Time using similar code as below (copied from btiernay in Using Joda Date & Time API to parse multiple formats)

DateTimeParser[] parsers = { 
        DateTimeFormat.forPattern( "yyyy-MM-dd HH" ).getParser(),
        DateTimeFormat.forPattern( "yyyy-MM-dd" ).getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append( null, parser).toFormatter();

DateTime date1 = formatter.parseDateTime( "2010-01-01" );
DateTime date2 = formatter.parseDateTime( "2010-01-01 01" );

however, the application maybe used overseas, which means the month may contain foreign language,

For example Haz is shorten for June in Turkish, how do I make it parse "07.Haz.2014", It throws an java.lang.IllegalArgumentException: Invalid format

like image 897
shaoyibai Avatar asked May 08 '26 23:05

shaoyibai


1 Answers

Format Must Match Your Inputs

Your input data 07.Haz.2014 does not match the format in your example code, yyyy-MM-dd HH.

See the example code below for correct format pattern.

Specify a Locale

To parse the names of Turkish months, you must specify a Java locale (which includes a language). See this question, Setting Turkish and English locale.

Example code in Joda-Time 2.3.

A Locale object consists of a language and a country/region.

Note the use of a time zone. If you omit the time zone, one will be assigned for you, the JVM's current default time zone. Better to specify one rather than depend on default. The time zone controls how to interpret the beginning of the day. June 7th begins at different moments around the world, with a new day dawning earlier in Istanbul than it does Montréal for example.

Do not confuse locale and time zone.

  • Locale = Language + Culture
    • The locale controls the language used for choosing names of months, day-of-week, and such when parsing/generating text.
    • The country/region portion of a Locale does not adjust the time to that area. Rather, the country/region defines the cultural rules applied when generating a textual representation of a date-time. For example, should the day-of-week be placed at the front.  
  • Time Zone = Offset + Anomalies
    • The time zone adjusts to the local wall-clock time. A time zone represents some number of hours and minutes ahead or behind UTC. This offset is represented by PLUS or MINUS with double-digit hours, and optionally double-digit minutes. Examples: -08:00 for west coast of North America being several hours behind UTC, and +05:30 for India being five and half hours ahead of UTC.
    • A time zone also encapsulates the past, present, and planned anomalies such as historical corrections, political/bureaucratic adjustments, and Daylight Saving Time nonsense.

Generally we think of locale and time zone together, with a time zone used in the geography of a locale, but actually they can be orthogonal. For example, a businessperson in Montréal may want to read in French the date-time string that represents the local date-time when a Turkish customer is expecting a delivery. In such a case, the string is rendered with a Québécois locale but a Turkish time zone.

I strongly recommend always specifying both the locale and the time zone. If omitted, the JVM's default for either/both is applied. This application of a default causes no end of confusion in date-time programming.

String input = "07.Haz.2014";

java.util.Locale locale = new java.util.Locale( "tr", "TR" );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Istanbul" );  // Assuming this time zone (not specified in Question).
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd.MMM.yyyy" ).withLocale( locale ).withZone( timeZone );
DateTime dateTime = formatter.parseDateTime( input );
String outputQuébécois = DateTimeFormat.forStyle( "FF" ).withLocale( java.util.Locale.CANADA_FRENCH ).print( dateTime ); // 
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );

Dump to console…

System.out.println( "input: " + input );
System.out.println( "locale: " + locale );
System.out.println( "dateTime: " + dateTime );
System.out.println( "outputQuébécois: " + outputQuébécois );
System.out.println( "dateTimeUtc: " + dateTimeUtc );

When run…

input: 07.Haz.2014
locale: tr_TR
dateTime: 2014-06-07T00:00:00.000+03:00
outputQuébécois: samedi 7 juin 2014 0 h 00 EEST
dateTimeUtc: 2014-06-06T21:00:00.000Z
like image 94
Basil Bourque Avatar answered May 11 '26 14:05

Basil Bourque



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!