Java獲取時間與系統時間相差8小時終極解決方案


https://www.cnblogs.com/exmyth/p/5320186.html

https://www.cnblogs.com/oldtrafford/p/9680791.html

 

一、在取日期以前設置一下時區

//這兩種寫法都能獲取到東八區

TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone tz = TimeZone.getTimeZone("GMT+08:00");

TimeZone.setDefault(tz);

此種方法適用於單次快速獲取系統本地時間

二、設置java命令參數

java -Duser.timezone=Asia/Jerusalem DateTest

三、設置JVM的默認時區為東八區(北京時間)

在下 面四個目錄(bea\jdk142_11\jre\lib\zi\Etc、bea\jdk142_11\jre\lib\zi、bea\jrockit81sp6_142_10\jre\lib\zi\Etc、bea\jrockit81sp6_142_10\jre\lib\zi)下找到GMT文件bak備份 一下,然后復制一份GMT-8並重命名為GMT,復制完畢,重新運行一下java程序問題即可解決!

 

 

 

 

 

世界時區和Java時區詳解

 

0、引言

Druid中時區的問題一直困擾着我們,所以我專門去研究了一下世界時區和Java中的時區,對使用Druid很用幫助.

1、UTC時間&GMT時間

UTC時間是時間標准時間(Universal Time Coordinated),UTC是根據原子鍾來計算時間,誤差非常小。

UTC也是指零時區的時間,如果要表示其他時區的時間,這里要注意沒有UTC+0800或者UTC+8這樣的表示方式(至少Java里面沒有,一般用於口頭表示),只有Asia/Shanghai這樣的表示方式,詳細的時區列表參考這個文檔時區列表,不要問我為什么沒有北京時區。。。

GMT時間是根據地球的自轉和公轉來計算時間,老的時間計量標准,這里我們不過多討論

2、表達時間方式

我們一般表示時間都會帶格式以方便理解,例如時間表達式是'2018-09-12 08:00:00',因為我們在東八區,所以默認是:北京時間2018年9月12號8點整。但是如果是一個美國人看到這個時間,就會認為是美國東部or西部時間的2018年9月12號8點整。所以從這種表達方式很不准確,因為沒有指明到底是哪個時區的時間!!!!

所以准確的表達時間必須帶有時區,例如2018-09-12 08:00:00+0800,表達了Asia/Shanghai這個時區的時間2018年9月12號8點整。這里要注意+0800並不是表示加8小時的意思,只是表示這個時間'2018-09-12 08:00:00'是東八區Asia/Shanghai的時間,僅此而已。

3、UTC時間的時間戳

講清楚了時間表達方式,再講時間戳。其實時間戳是沒有時區概念的,或者說時間戳只能是0時區的。時間戳是從1970-01-11 00:00:00+0000開始的(原因大家都知道),也就是在'1970-01-11 00:00:00+0000'這個時間點,時間戳是0。再換句話說在'1970-01-11 08:00:00+0800'時間戳也是0。這也是Java里時間組件的默認方式,不管用戶輸入的人類可識別的時間是什么格式,在內部統一存的是時間戳。

例如時間是'2018-09-01 08:00:00+0800',那么使用date.getTime()獲取到時間戳是1535760000000;時間是'2018-09-01 00:00:00+0000',獲取到時間戳也是1535760000000。

測試代碼如下:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); System.out.println(sdf.parse("2018-09-01 08:00:00+0800").getTime()); System.out.println(sdf.parse("2018-09-01 00:00:00+0000").getTime()); 

可以觀察到這2行代碼的輸出都是1535760000000,這就證明了上面的觀點。再啰嗦2點:

  • 第一行代碼DateFormat中Z表示時區,所以String類型格式時間帶上+0800這種表達式,就能正確獲取時間戳了。

  • SimpleDateFormat是線程不安全的,不要用

4、時區設置

為什么我們寫以下代碼的時候,程序能正確知道我們的時區呢?

SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf2.parse("2018-09-01 08:00:00").getTime()); 

因為我們在mac上設置了時區

在Java中也可以設置時區

1)啟動設置
java -Duser.timezone=Asia/Shanghai -jar xxx.jar

  1. 代碼中設置
TimeZone.setDefault(TimeZone.getTimeZone("UTC")); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.parse("2018-09-01 08:00:00").getTime()); 
  1. 單次處理生效,建議使用joda的時間包
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.9</version> </dependency> DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withChronology(ISOChronology.getInstance(DateTimeZone.forID("Asia/Shanghai"))); System.out.println(dateTimeFormatter.parseDateTime("2018-09-01 08:00:00").getMillis());

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM