問題描述
如何讓 Java 解析和格式化具有相同時區的日期/時間?我一直在獲取本地時區 (How do I get Java to parse and format a date/time with the same time zone? I keep getting the local timezone)
My application keeps all Java Date's in UTC. Parsing them is easy, but when I print them out, the display shows the computer's local time zone, and I want to show it as UTC.
Example code:
String sample = "271210 200157 UTC";
SimpleDateFormat dfmt = new SimpleDateFormat("ddMMyy HHmmss Z");
Date result = dfmt.parse(sample);
System.out.printf("%tc\n", result);
the result is
Mon Dec 27 15:01:57 EST 2010
What I want is
Mon Dec 27 20:01:57 UTC 2010
Clearly I have to set some Locale and TimeZone values, but I don't see where to put them. Thanks Pat
參考解法
方法 1:
You can set the time zone for the DateFormat:
dfmt.setTimeZone(timeZone);
Also, you do not want to print the Date object itself, but again use the DateFormat
String formattedDate = dfmt.format(result);
方法 2:
Avoid java.util.Date
The old java.util.Date, .Calendar, and SimpleDateFormat classes are notoriously troublesome. Avoid them.
Among the many problems is the fact that a java.util.Date object:
- Has a time zone buried deep inside
- Ignores that time zone for most practical purposes
- Has a
toString
method implementation that applies the JVM’s current default time zone when generating the String representation of its internal UTC date-time value.
So to a naïve programmer, the Date object seems to have a time zone but is actually always is UTC (just a 64-bit integer inside, a count from epoch).
Bad Format
The format of your input string is clumsy. In particular, using two digits for the year is problematic.
If you have any control, I strongly suggest changing it. The first choice is to follow the standard ISO 8601 formats.
Joda-Time & java.time
Use either Joda-Time or the new java.time package built into Java 8 (and inspired by Joda-Time).
Unlike a java.util.Date, a DateTime object in Joda-Time clearly understands its own assigned time zone. If you omit the time zone, the JVM’s current default time zone is assigned. I recommend always specifying the desired time zone.
Both Joda-Time and java.time use ISO 8601 formats by default for both generating and parsing String representations of date-time values.
In Joda-Time 2.7…
String input = "271210 200157 UTC";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "ddMMyy HHmmss z" ).withZoneUTC();
DateTime dateTimeUtc = formatter.parseDateTime( input );
Easy to adjust time zone. For fun, let's move that UTC value into Québec time zone.
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
String output = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH ).print( dateTimeMontréal );
Dump to console.
System.out.println( "input : " + input );
System.out.println( "dateTimeUtc : " + dateTimeUtc );
System.out.println( "dateTimeMontréal : " + dateTimeMontréal );
System.out.println( "output : " + output );
<pre class="lang-none prettyprint-override">input : 271210 200157 UTC dateTimeUtc : 2010-12-27T20:01:57.000Z dateTimeMontréal : 2010-12-27T15:01:57.000-05:00 output : lundi 27 décembre 2010 15 h 01 EST
</pre>
(by fishtoprecords、Thilo、Basil Bourque)