Java中的時間與時區__java

來源:互聯網
上載者:User
0. 前言:

時間格式:

//世界標準時間,其中T表示時分秒的開始(或者日期與時間的間隔),Z表示這是一個世界標準時間2017-12-13T01:47:07.081Z//本地時間,也叫不含時區資訊的時間,末尾沒有Z2017-12-13T09:47:07.153//含有時區資訊的時間,+08:00表示該時間是由世界標準時間加了8個小時得到的,[Asia/Shanghai]表示時區2017-12-13T09:47:07.153+08:00[Asia/Shanghai]

其中最難理解的是本地時間,2017-12-13T09:47:07.153時間本身是不含有時區資訊的,但是“本地”這兩個字含有時間資訊。所以我認為這個翻譯並不好,不應該叫做“本地時間”,應該直接翻譯為“不含時區資訊的時間”。

國際標準時間,又稱世界統一時間、世界標準時間、國際協調時間。由於英文(CUT)和法文(TUC)的縮寫不同,作為妥協,簡稱UTC。
世界時UT即格林尼治平太陽時間,是指格林尼治所在地的標準時間,也是表示地球自轉速率的一種形式。以地球自轉為基礎的時間計量系統。 1. 先來看Java8:

表示時間的主要有4類String、Instant、LocalDateTime、ZonedDateTime

String是格式化的時間,Instant是時間戳記,LocalDateTime是不含時區資訊的時間,ZonedDateTime是含有時區資訊的時間。 1.1 它們之間的關係是: 1.1.1 String與LocalDateTime是等價的

符合格式的String可以直接解析為LocalDateTime,如下:

System.out.println(LocalDateTime.parse("2017-12-13 10:10:10",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));輸出:2017-12-13T10:10:10

辨析LocalDateTime最好的辦法就是不要把它當成“本地時間”,它就是“不含時區資訊的時間”。它只是儲存了年月日時分秒,沒有儲存任何時區資訊,具體表示哪裡的時間全靠輸入和輸出時進行解釋。與String完全等價,本質上是對String的解析,只是年月日時分秒格式化的儲存到了對象當中,方便取用。 1.1.2 Instant與ZonedDateTime是等價的

Instant是時間戳記,是指世界標準時格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數,Instant本身實際上就指明時區了,0時區。
ZonedDateTime是含有時區資訊的時間,本質上是根據時區對Instant的格式化顯示。

ZonedDateTime ztime1=ZonedDateTime.ofInstant(Instant.now(),ZoneId.systemDefault());System.out.println(ztime1);System.out.println(ztime1.toInstant()); //1System.out.println(ztime1.toLocalDateTime()); //3ZonedDateTime ztime2=ZonedDateTime.ofInstant(Instant.now(),ZoneId.of("Australia/Darwin"));System.out.println(ztime2);System.out.println(ztime2.toInstant()); //2System.out.println(ztime2.toLocalDateTime()); //4輸出:2017-12-13T13:24:55.932+08:00[Asia/Shanghai]2017-12-13T05:24:55.932Z2017-12-13T13:24:55.9322017-12-13T14:54:55.933+09:30[Australia/Darwin]2017-12-13T05:24:55.933Z2017-12-13T14:54:55.933

注釋1、2輸出相同,說明ZonedDateTime的儲存本質是Instant;
注釋3、4輸出不同,說明ZonedDateTime會根據建立ZonedDateTime對象時傳入的時區,進行格式化顯示。

相同的Instant,在不同的時區有不同的展示時間,所以在用Instant構造ZonedDateTime的時候需要傳入時區;ZonedDateTime可以直接轉化為Instant,並且不同的ZonedDateTime可能會產生同樣的Instant。 1.2 如何構造時間對象: 1.2.1 直接定義

System.out.println(Instant.ofEpochMilli(System.currentTimeMillis()));System.out.println(LocalDateTime.of(2017,12,13,10,0,0,0));System.out.println(ZonedDateTime.of(2017,12,13,10,0,0,0,ZoneId.systemDefault()));輸出:2017-12-13T06:22:06.581Z2017-12-13T10:002017-12-13T10:00+08:00[Asia/Shanghai]
1.2.2 擷取系統目前時間now()
System.out.println(Instant.now()); //世界標準時間System.out.println(LocalDateTime.now()); //會把世界標準時間轉換為本時區的時間,但是時區資訊會被丟棄System.out.println(ZonedDateTime.now()); //會把世界標準時間轉換為本時區的時間,但是時區資訊會被保留System.out.println(LocalDateTime.now(ZoneId.of("+00:00"))); //0時區的現在時間System.out.println(ZonedDateTime.now(ZoneId.of("+00:00"))); //0時區的現在時間輸出:2017-12-14T02:53:05.830Z2017-12-14T10:53:05.9042017-12-14T10:53:05.906+08:00[Asia/Shanghai]2017-12-14T02:53:05.9062017-12-14T02:53:05.906Z
1.2.3 解析String
System.out.println(Instant.parse("2007-12-03T10:15:30Z")); //只能解析這種格式,不能自己指定System.out.println(LocalDateTime.parse("2017-12-13 11:51:12.083", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));System.out.println(ZonedDateTime.parse("2017-12-13 11:51:12.083 +04:30", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS ZZZZZ")));輸出:2007-12-03T10:15:30Z2017-12-13T11:51:12.0832017-12-13T11:51:12.083+04:30
1.3 時間對象之間的轉換: 1.3.1 Instant與LocalDateTime、ZonedDateTime之間的轉換
Instant instant=Instant.now();LocalDateTime localDateTime=LocalDateTime.ofInstant(instant,ZoneId.systemDefault());ZonedDateTime zonedDateTime=ZonedDateTime.ofInstant(instant,ZoneId.systemDefault());System.out.println(instant);System.out.println(localDateTime);System.out.println(zonedDateTime);System.out.println(ZoneOffset.systemDefault());System.out.println(ZoneOffset.UTC);System.out.println(ZoneOffset.MIN);System.out.println(ZoneOffset.of("+08:00"));System.out.println(localDateTime.toInstant(ZoneOffset.UTC)); //在把LocalDateTime轉換為Instant時,需要明確指定當前這個時間指的是那個時區的時間System.out.println(localDateTime.toInstant(ZoneOffset.of("+08:00")));System.out.println(zonedDateTime.toInstant());輸出:2017-12-14T01:50:26.098Z2017-12-14T09:50:26.0982017-12-14T09:50:26.098+08:00[Asia/Shanghai]Asia/ShanghaiZ-18:00+08:002017-12-14T09:50:26.098Z2017-12-14T01:50:26.098Z2017-12-14T01:50:26.098Z
1.3.2 LocalDateTime、ZonedDateTime之間的轉換
Instant instant=Instant.now();LocalDateTime localDateTime=LocalDateTime.ofInstant(instant,ZoneId.systemDefault());ZonedDateTime zonedDateTime=ZonedDateTime.ofInstant(instant,ZoneId.systemDefault());System.out.println(instant);System.out.println(localDateTime);System.out.println(zonedDateTime);System.out.println(ZonedDateTime.of(localDateTime,ZoneId.systemDefault())); //LocalDateTime轉ZonedDateTime System.out.println(zonedDateTime.toLocalDateTime()); //ZonedDateTime轉LocalDateTime輸出:2017-12-14T02:01:45.145Z2017-12-14T10:01:45.1452017-12-14T10:01:45.145+08:00[Asia/Shanghai]2017-12-14T10:01:45.145+08:00[Asia/Shanghai]2017-12-14T10:01:45.145
1.4 時區之間的轉換

時區轉換時要特別注意的是:使用者輸入的String類型的時間是沒有時區資訊的,需要人為指定解析。
解析的步驟分2步: 先結合語境,分析使用者時區,把使用者輸入的時間轉化為世界標準時間; 再把世界標準時間轉為需要的時區。 1.5 關於時間的陷阱 1.5.1 問題

因為存在時區的概念,所以會造成2個問題: 不同時區的使用者,對時間的理解不同,不同時區的同一個時間String不是同一個時間戳記; 不同時區的伺服器,對時間的理解也不同,比如,同一份程式運行在不同時區的伺服器上,當這些程式同時調用LocalDateTime.now()時,返回的結果並不同,如果操作不當很容易出現問題; 如果前台和背景程式分別部署在不同時區的伺服器上,情況會更加複雜。如果使用者、前台和背景程式都不在相同時區,……。 1.5.2 解決辦法 建議在系統當中統一使用時間戳,包括前後台傳輸和資料庫儲存,只有在展示的時候再轉化為字串; 如果為了處理方便建議把所有的時間都轉化到0時區進行處理。 2. Java8以前的時間API

JAVA API系列—-日期和時間相關的類
時區轉換:java new Date() 變成GMT&& GMT時間與CST時間轉換 3. 新舊時間API的轉換

新舊時間API串連的橋樑是Date類和Instant類,這兩個都是世界標準時間,但是Date列印的時候會轉化為本地時間。

Date date=Date.from(Instant.now());Instant instant=date.toInstant();System.out.println(date);System.out.println(date.getTime()); //1System.out.println(instant);System.out.println(instant.toEpochMilli()); //2輸出:Thu Dec 14 11:45:58 CST 201715132231585882017-12-14T03:45:58.588Z1513223158588

注釋1、2輸出相同,說明Date類和Instant類是等價的;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.