0
import java.text.SimpleDateFormat;
import java.util.Locale;

import org.joda.time.DateTime;
import org.joda.time.Interval;

public class JordaTimeTest {

    public static void main(String[] args) {
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
        SimpleDateFormat dateFormat = dateFormat1;

        Interval interval = new Interval(1499628963860L, 1511809983860L);
        DateTime start = new DateTime(interval.getStart());
        DateTime end = new DateTime(interval.getEnd());

        System.out.println(start.toString(dateFormat.toLocalizedPattern()));
    }
}

I followed the way specified in How to set eclipse console locale/language

I used -Duser.language=da -Duser.country=DK as VM arguments. I'm getting exception:

java.lang.IllegalArgumentException: Illegal pattern component: tt

Any idea to fix this?

Jeyatharsini
  • 95
  • 2
  • 11
  • 3
    You're trying to format a joda DateTime with the localized pattern of a SimpleDateFormat, used to format and parse java.util.Date instances. Use a joda DateTimeFormat pattern, as documented: http://joda-time.sourceforge.net/apidocs/org/joda/time/base/AbstractDateTime.html#toString(java.lang.String). What you're doing is basically equivalent to trying to identify a French citizen using an American social security number. – JB Nizet Sep 19 '17 at 14:14
  • 2
    It's actually worse than that: it's like trying to identify a French citizen using an American social security number written in Chinese characters. – JB Nizet Sep 19 '17 at 14:22

2 Answers2

1

When setting the locale to da_DK, the method toLocalizedPattern returns EEE tt/MM HH:mm, and tt is not a recognized pattern in Joda-Time.

If you want the output in a specific language, you don't need to change the JVM default locale (because this can affect all other applications running in the same JVM). Instead, you can create a org.joda.time.format.DateTimeFormatter and set the locale only in the formatter:

DateTimeFormatter fmt = DateTimeFormat
    // set pattern
    .forPattern("EEE dd/MM HH:mm")
    // set locale
    .withLocale(new Locale("da", "DK"));
System.out.println(fmt.print(start));
System.out.println(fmt.print(end));

This will output:

sø 09/07 16:36
ma 27/11 17:13

Please note that the output depends on the JVM default timezone: 1499628963860 corresponds to UTC 2017-07-09T19:36:03.860Z, which is 16:36 in my JVM's default timezone (America/Sao_Paulo). In your machine, the values will be different.

If you want to specify a timezone, you could create your dates like:

// create date in UTC
DateTime start = new DateTime(interval.getStart(), DateTimeZone.UTC);

Now the DateTime is in UTC, so the output will be sø 09/07 19:36.

You can also set to a specific timezone using DateTimeZone.forID("zonename"), where zonename is a valid IANA timezone name (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.

You can get a list of available timezones (and choose the one that fits best your system) by calling DateTimeZone.getAvailableIDs().


As explained in @JB Nizet's comment, there's no need to use SimpleDateFormat (as this is designed to work with java.util.Date and java.util.Calendar).


Java new Date/Time API

Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".

If you can't (or don't want to) migrate from Joda-Time to the new API, you can ignore this section.

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java 6 or 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

You don't need to create an interval and get the start and end from it. You can create the dates directly:

// use system default timezone
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime start = Instant.ofEpochMilli(1499628963860L).atZone(zone);
ZonedDateTime end = Instant.ofEpochMilli(1511809983860L).atZone(zone);

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE dd/MM HH:mm", new Locale("da", "DK"));
System.out.println(start.format(fmt));
System.out.println(end.format(fmt));

The output is:

sø 09/07 16:36
ma 27/11 17:13

If you want to convert to another timezone (instead of JVM default), you can use ZoneId.of("zonename"), or ZoneOffset.UTC to use UTC.

0
SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
DateFormatSymbols dfs = dateFormat.getDateFormatSymbols();
dfs.setLocalPatternChars("GyMdkHmsSEDFwWahKzZ");
dateFormat.setDateFormatSymbols(dfs);
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());

System.out.println(start.toString(dateFormat.toLocalizedPattern()));

this is another way of fix the problem

its the char set to interpret date and time

ex :-  y = year 
d = day
M = month 
m = minutes etc 

in DK t is used inested of Y and u is used insted of d but Joda time doesnt support t and u

Jeyatharsini
  • 95
  • 2
  • 11