[英]java.util.Date - Test Conversion US <-> UK
我在下面有這個測試代碼。
行/// 1 ///和/// 2 ///是備選方案。
如果我使用第///2行///輸出看起來有點兒,似乎沒有考慮到美國波士頓和英國倫敦在全年沒有相差5小時的事實。 如果我使用行/// 1 ///它看起來沒問題,似乎它解釋了這個事實。 為什么這樣? 概念差異在哪里? 為什么將這兩個日期改為1天(我的意思是在/// 2 ///中)是不正確的?
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeZoneExample02 {
// private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) {
Calendar bostonTime = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
Calendar londonTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"));
londonTime.setTimeInMillis(bostonTime.getTimeInMillis());
bostonTime.getTime();
londonTime.getTime();
for (int i=0; i>=-500; i--){
bostonTime.add(Calendar.DATE, -1);
// londonTime.setTimeInMillis(bostonTime.getTimeInMillis()); /// 1 ///
londonTime.add(Calendar.DATE, -1); /// 2 ///
bostonTime.getTime();
londonTime.getTime();
System.out.printf("Boston time: %s", getString(bostonTime));
System.out.print(" /// ");
System.out.printf("London time: %s\n", getString(londonTime));
}
}
private static String getString(Calendar c){
StringBuilder sb = new StringBuilder();
sb.append(c.get(Calendar.YEAR));
sb.append("-");
sb.append(String.format("%02d", c.get(Calendar.MONTH) + 1));
sb.append("-");
sb.append(String.format("%02d", c.get(Calendar.DAY_OF_MONTH)));
sb.append(" ");
sb.append(String.format("%02d", c.get(Calendar.HOUR_OF_DAY)));
sb.append(":");
sb.append(String.format("%02d", c.get(Calendar.MINUTE)));
sb.append(":");
sb.append(String.format("%02d", c.get(Calendar.SECOND)));
sb.append(".");
return sb.toString();
}
}
輸出1:
波士頓時間:2013-10-30 18:51:12 ///倫敦時間:2013-10-30 22:51:12
波士頓時間:2013-10-29 18:51:12 ///倫敦時間:2013-10-29 22:51:12
波士頓時間:2013-10-28 18:51:12 ///倫敦時間:2013-10-28 22:51:12
波士頓時間:2013-10-27 18:51:12 ///倫敦時間:2013-10-27 22:51:12
波士頓時間:2013-10-26 18:51:12 ///倫敦時間:2013-10-26 23:51:12
波士頓時間:2013-10-25 18:51:12 ///倫敦時間:2013-10-25 23:51:12
波士頓時間:2013-10-24 18:51:12 ///倫敦時間:2013-10-24 23:51:12
輸出2:
波士頓時間:2013-10-30 18:50:53 ///倫敦時間:2013-10-30 23:50:53
波士頓時間:2013-10-29 18:50:53 ///倫敦時間:2013-10-29 23:50:53
波士頓時間:2013-10-28 18:50:53 ///倫敦時間:2013-10-28 23:50:53
波士頓時間:2013-10-27 18:50:53 ///倫敦時間:2013-10-27 23:50:53
波士頓時間:2013-10-26 18:50:53 ///倫敦時間:2013-10-26 23:50:53
波士頓時間:2013-10-25 18:50:53 ///倫敦時間:2013-10-25 23:50:53
波士頓時間:2013-10-24 18:50:53 ///倫敦時間:2013-10-24 23:50:53
倫敦時間隨着夏令時(DST)在2013-10-27 結束時凌晨2點凌晨1點(再次)結束。
java.util.Calendar的文檔在其頂部的討論中解釋了unlike set(), add() forces an immediate recomputation of the calendar's milliseconds and all fields.
此外, add
方法上java.util.GregorianCalendar的文檔指出不調整較小的時間單位。 該文檔特別指出, HOUR
是DAY_OF_MONTH
的較小字段,因此不進行調整。 這意味着你從23小時開始,所以你最終得到23小時,毫秒 - 自 - epoch根據需要重新計算。
您在set
和add
方法中看到的行為都是正確的。 功能,而不是錯誤。
捆綁的java.util.Date ,java.util.Calendar和java.text.SimpleDateFormat是眾所周知的麻煩,令人困惑和棘手。 它們在設計和實施方面都存在缺陷。
我理解您對“使用Java的內置功能”的興趣。 雖然這種興趣通常值得稱贊,但在Java的這個特定角落,這是浪費時間。 甚至Sun和Oracle都放棄了這些課程。 Java 8帶來了一個全新的java.time。*包,由JSR 310定義,受Joda-Time的啟發,並取代舊的捆綁類。
如果您還不能轉到Java 8,請使用Joda-Time 。 Joda-Time可以在多個版本的Java中運行,並且在Java 8中繼續工作,因為它是主動維護的。
使用Joda-Time 2.3的一些示例代碼可以幫助您前進。
一些筆記......
Joda-Time DateTime實際上知道自己的時區。 相比之下,java.util.Date沒有時區,但其toString
方法應用JVM的默認時區,這不會產生混淆。
請注意,在此示例中, dateTime_Boston
和dateTime_London
具有相同的毫秒數 - 自 - 紀元。
Joda-Time默認使用標准的ISO 8601格式進行字符串輸出,如2014-02-13T10:32:28.131+05:30
。
最后的+
或-
標記與UTC / GMT偏移的時區。 不要看這是一個公式中的操作數。 閱讀此標簽,例如,“印度的時區偏移為+05:30,因此顯示的日期時間比UTC / GMT提前了五個半小時”。
最后的Z
發音為“Zulu”,是+00:00
簡寫。 這意味着UTC / GMT時區,即沒有時區偏移。
// Specify a time zone rather than rely on default.
DateTimeZone timeZone_Boston = DateTimeZone.forID( "America/New_York" );
DateTimeZone timeZone_London = DateTimeZone.forID( "Europe/London" );
DateTime dateTime_Boston = new DateTime( 2013, 10, 27, 22, 51, 12, timeZone_Boston );
DateTime dateTime_London = dateTime_Boston.toDateTime( timeZone_London );
DateTime earlier_London = dateTime_London.minusDays( 2 ); // Use '2' to get us before DST change.
DateTime earlier_UtcGmt = earlier_London.toDateTime( DateTimeZone.UTC );
轉儲到控制台......
System.out.println( "dateTime_Boston " + dateTime_Boston );
System.out.println( "dateTime_London " + dateTime_London );
System.out.println( "earlier_London " + earlier_London );
System.out.println( "earlier_UtcGmt " + earlier_UtcGmt );
跑的時候......
dateTime_Boston 2013-10-27T22:51:12.000-04:00
dateTime_London 2013-10-28T02:51:12.000Z
earlier_London 2013-10-26T02:51:12.000+01:00
earlier_UtcGmt 2013-10-26T01:51:12.000Z
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.