簡體   English   中英

Java當前日期/時間比原始時間提前1小時顯示

[英]Java Current Date/Time displays 1 hour ahead that original time

當我嘗試使用Calender實例打印當前日期和時間時,我得到的結果比實際時間提前1小時。

我在遠程機器上工作,它運行EST時區。 以下是我嘗試過的,但沒有任何效果。

Calendar cal = Calendar.getInstance(TimeZone.getDefault());
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
Calendar cal = Calendar.getInstance(Locale.ENGLISH);

System.out.println("Current Date & Time: " +calendar.getTime());

o/p:
Time: Sat Dec 28 11:55:10 UTC 2013

But expected o/p: 
Time: Sat Dec 28 10:55:10 UTC 2013

所有3種類型都給出了相同的結果。 我無法理解我錯過了什么來獲得確切的日期和時間。 這個問題是否與日光時間有關?

有人可以幫助我克服這個問題。 提前致謝。

這又是java.util.Date的舊缺陷:它的toString() - 打印calendar.getTime()時間接使用的方法使用默認時區,而不是日歷實例的時區(設置為'美東時間')。

解:

Date currentTime = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("Current Date & Time: " + sdf.format(currentTime));

說明:

a)在第一行中不需要日歷實例,因為您只對當前的全球時間感興趣(與時區無關的物理時間相同)。 Calendar.getInstance()也更耗費資源。 最后,兩個表達式new Date()Calendar.getInstance(...).getTime()在關於內部狀態時沒有時區引用。 只有juDate的toString()方法使用默認時區。

b)您需要定義第2行中給出的輸出格式。您可以更改它。 只需研究java.text.SimpleDateFormat的模式文檔。

c)您還需要在輸出格式中定義時區,以幫助格式對象將全局Date實例轉換為時區感知表示。 順便說一句,我選擇了標識符'America / New_York',而不是'EST',因為后一種形式有時可能是曖昧的。 您應該選擇第一個表單(IANA或Olson時區標識符)或表單'GMT +/- HH:mm'。

d)輸出本身是用sdf.format(currentTime) ,而不僅僅是currentTime (沒有對toString()隱式調用)。

e)回答你的問題'這個問題是否與夏令時有關?':不,時區EST(America / New_York)的時間從未在12月的DST中。

結論:

如果可以,你應該盡量避免使用juDate和juCalendar,因為存在太多陷阱。 目前,JodaTime是一個更好的選擇,盡管並非沒有問題。

避免使用3個字母的時區

切勿使用3個字母的時區代碼。 它們既不標准也不獨特。 你的“EST”至少意味着:

  • 東部標准時間(美國)
  • 東部標准時間(澳大利亞)
  • 巴西東部標准時間

使用時區名稱

避免juDate /日歷

您已經發現了避免使用與Java捆綁的java.util.Date和java.util.Calendar類的眾多原因之一: Date實例沒有時區信息,但其toString方法根據Java環境的默認時間混淆地呈現字符串區。

使用Joda-Time

使用稱職的日期時間庫。 在Java中,這意味着Joda-Time或Java 8中的新java.time。*類(受Joda-Time啟發)。

示例代碼...

// Default time zone
DateTime dateTime_MyDefaultTimeZone = new DateTime();

// Specific time zone. If by "EST" you meant east coast of United States, use a name such as New York.
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
DateTime dateTime_EastCoastUS = new DateTime( timeZone );

轉儲到控制台......

System.out.println( "dateTime_MyDefaultTimeZone: " + dateTime_MyDefaultTimeZone );
System.out.println( "dateTime_EastCoastUS: " + dateTime_EastCoastUS );
System.out.println( "date-time in UTC: " + dateTime_EastCoastUS.toDateTime( DateTimeZone.UTC ) );

跑的時候......

dateTime_MyDefaultTimeZone: 2013-12-28T18:51:18.485-08:00
dateTime_EastCoastUS: 2013-12-28T21:51:18.522-05:00
date-time in UTC: 2013-12-29T02:51:18.522Z

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM