Kumar D
Kumar D

Reputation: 1378

How to get Date pattern from Timezone of Locale in Java

I have a timezone, and Locale of the user. Now I want to get the date pattern.

For example: User's timezone PST and Locale US and the pattern I expect is "MM/dd/yyyy" and if the user's timezone is IST and Locale India, then pattern I expect is "dd/MM/yyyy"

How to get this?

Note: I want to get the pattern not the actual date so that I can use this in some other place.

Upvotes: 7

Views: 2285

Answers (6)

Basil Bourque
Basil Bourque

Reputation: 338775

java.time

The modern solution use the java.time classes that years ago supplanted the terrible legacy classes such as SimpleDateFormat. Specifically replaced by DateTimeFormatter.

Skip the formatting pattern, let java.time localize automatically

You asked:

I have a timezone, and Locale of the user. Now I want to get the date pattern.

There is no need to actually obtain the formatting pattern used by a particular locale.

The .ofLocalized… methods on DateTimeFormatter return a formatter object that can automatically localize the text representing the the date-time object’s value. So you don't need to see the pattern, just ask for generated textual result.

The FormatStyle object controls how long or abbreviated the text. The Locale determines the human language and cultural norms to use in localizing.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; 

Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = 
        DateTimeFormatter
        .ofLocalizedDateTime( FormatStyle.FULL )
        .withLocale( locale ) 
;
String output = zdt.format( f ) ;

Dump to console.

System.out.println( zdt.toInstant().toString() ) ;  // Adjust to UTC.
System.out.println( zdt.toString() ) ;              // Generate text in standard ISO 8601 format extended wisely to append the name of the time zone in square brackets.
System.out.println( output ) ;                      // Automatically formatted content.

See this code run live at IdeOne.com.

2020-07-13T23:26:40.554180Z

2020-07-14T08:26:40.554180+09:00[Asia/Tokyo]

mardi 14 juillet 2020 à 08 h 26 min 40 s heure normale du Japon


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.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Upvotes: 1

RedYeti
RedYeti

Reputation: 1234

If you're using Joda Time (and why wouldn't you if you have any choice? It nearly got bundled into JDK 1.7) you could do something like this:

String patternForStyleAndLocale = org.joda.time.format.DateTimeFormat.patternForStyle("S-", locale);

Which unfortunately only gives a two digit year. One work around for that would be:

if (!org.apache.commons.lang.StringUtils.contains(patternForStyleAndLocale, "yyyy"))
{
    // The default Joda pattern only has a two digit year for US and Europe, China etc - but we want four digit years
    patternForStyleAndLocale = StringUtils.replace(patternForStyleAndLocale, "yy", "yyyy");
}

And you could consider caching them in a ConcurrentHashMap<Locale, String>.

The nice thing about getting a numeric date as a pre-localised pattern like this is that it doesn't require any further localisation later, as it would do if you were using a pattern such as:

"dd MMM yyyy" // UK: "25 Dec 2010" FRANCE: "25 déc. 2010" etc..

However... I just noticed from your later comment that you want to pass the pattern to JavaScript - that might get very difficult since JS uses different pattern formatting to Java (ISO date for instance is "yyyy-MM-dd" in Java and "yy-mm-dd" in JS). I've not tried solving that one but I'd probably use a some string mapping in the JS or Java to simply map from Java patterns to JS. You'd have to know each of the patterns you might encounter for each of the languages in advance of course.

Upvotes: 0

Adi Mor
Adi Mor

Reputation: 2165

you can use Interface Map

the k will be Locale the v will be a string with the date pattern

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340753

The logic translating Locale to date/time formats is burried in java.text.SimpleDateFormat#SimpleDateFormat constructor, precisely in sun.util.resources.LocaleData#getDateFormatData. This method provides ResourceBundle which is then queried for particular pattern depending on which style was chosen.

In other words - unfortunately JDK doesn't seems to provide an API/SPI to access raw formats. My advice is to use the Locale all along and pass it to formatting/parsing methods.

Upvotes: 3

Mac
Mac

Reputation: 1642

It sounds like you want the static getInstance methods on DateFormat. They take an integer constant for style (short, long, etc.), and optionally a different Locale (instead of the JVM's default).

Upvotes: 0

yoprogramo
yoprogramo

Reputation: 1306

Really do you need the TZ for date pattern? The usual way is having the data pattern in the localized properties file for a locale (or locale_country). I think it is enough.

Upvotes: 1

Related Questions