Reputation: 1378
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
Reputation: 338775
The modern solution use the java.time classes that years ago supplanted the terrible legacy classes such as SimpleDateFormat
. Specifically replaced by DateTimeFormatter
.
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
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
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
Reputation: 2165
you can use Interface Map
the k will be Locale the v will be a string with the date pattern
Upvotes: 0
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
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
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