Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
245 views
in Technique[技术] by (71.8m points)

java - How to use Calendar.getInstance with specified Locale

I am trying to use Calendar.getInstance(Locale l) with specified Locale and is not working. I cannot figure out what I am doing wrong.

The Java Doc. say:

getInstance public static Calendar getInstance(Locale aLocale) Gets a calendar using the default time zone and specified locale. The Calendar returned is based on the current time in the default time zone with the given locale. Parameters: aLocale - the locale for the week data Returns: a Calendar.

My code:

 public static void main (String[] args){

     Locale local = new Locale("pt", "BR");

     Calendar c = Calendar.getInstance(local); // here I am using the method
     System.out.println(c.getTime()); // and here, I cannot figure out why is not working


     DateFormat dt = DateFormat.getDateInstance(DateFormat.LONG, local);
     String s = dt.format(c.getTime());
     System.out.println(s); // here just a example in portuguese Brasil
 }

Output:

Wed Apr 29 10:18:16 BRT 2015

29 de Abril de 2015

Should the first print must be in Locale("pt", "BR"), in portuguese?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Answer by Loc is correct: Your call to Calendar::getTime produces a java.util.Date object. The java.util.Date class has no explicit time zone yet its toString method confusingly applies the JVM’s current default time zone while generating a String.

All very confusing names and behavior - some of the many reasons to avoid these poorly designed, confusing, and troublesome old legacy date-time classes. Instead you should be using the java.time classes that officially supplant the old classes.

java.time

Get the current moment in UTC. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now();

You can create a String to represent that value with standard ISO 8601 formatting by calling toString.

String output = instant.toString();

2016-09-28T19:38:21Z

The code in the Question ignores the issue of time zone. When you do not specify a time zone your JVM’s current default time zone is implicitly applied. Better to specify explicitly.

Note that Locale and time zone are two completely separate distinct issues.

  • Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.
  • Time zone determines the wall-clock time used to present the date-time value.

You can have any combination of the two. For example, a time zone of Kolkata India with a French locale, or a Brazil Portuguese locale with an Auckland New Zealand time zone.

Locale locale = new Locale("pt", "BR");
ZoneId z = ZoneId.of( "Pacific/Auckland" );

Apply the time zone as a ZoneId to produce a ZonedDateTime. Conceptually, think of it as ZonedDateTime = ( Instant + ZoneID ).

Specify a proper time zone name in the format of continent/region. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZonedDateTime zdt = instant.atZone( z );

The Locale does not affect the meaning, on the presentation. We can let the Locale object drive the automatic localization of when producing a String to represent the date-time value via the DateTimeFormatter class. Specify a FormatStyle to determine how long or abbreviated should the string be.

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

Dump to console. The instant and zdt objects seen here represent the very same moment, the same point on the timeline. The only difference is a view through the lens of a different region’s wall-clock time.

System.out.println ( "instant.toString(): " + instant 
                     + " | zdt: " + zdt 
                     + " | output: " + output );

instant.toString(): 2016-09-28T20:20:38.242Z | zdt: 2016-09-29T09:20:38.242+13:00[Pacific/Auckland] | output: Quinta-feira, 29 de Setembro de 2016 09h20min38s NZDT

Conversion

Avoid the old .Date and .Calendar classes. But if you must use them with old code not yet updated for the java.time types, you can convert. Use new methods added to the old classes. Here we call java.util.GregorianCalendar.from( ZonedDateTime ).

java.util.Calendar cal = java.util.GregorianCalendar.from( zdt ) ;

And, going the other direction:

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

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

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

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...