UTC是以原子時計時,更加精準,適應現代社會的精確計時。不過通常使用不須要精確到秒時,視爲等同。GMT是前世界標準時,UTC是現世界標準時。每一年格林尼治天文臺會發調時信息,基於UTC。
GMT和 UTC能夠視爲幾乎是等同的,UTC更精準,有閏秒的概念。前端
//世界標準時間UTC,其中T表示時分秒的開始(或者日期與時間的間隔),Z表示這是一個世界標準時間 String utcStr = "2010-10-12T15:24:22Z"; //本地時間,也叫不含時區信息的時間,末尾沒有Z String localStr = "2010-10-12T15:24:22"; //含有時區的時間,+08:00表示該時間是由世界標準時間加了8個小時獲得的,[Asia/Shanghai]表示時區 String zoneStr = "2017-12-13T09:47:07.153+08:00[Asia/Shanghai]";
表示時間的類主要有個:String、Instant、LocalDateTime、ZonedDateTime,
String是字符串形式的時間,Instant是時間戳,LocalDateTime是不含時區信息的時間,ZonedDateTime是含有時區信息的時間。java
符合格式的String 能夠直接轉換爲LocalDateTime數據庫
System.out.println(LocalDateTime.parse("2019-12-15 10:10:10", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
LocalDateTime字面意思是本地時間,實際上它能夠理解爲不含時區信息的時間,只儲存了年月日時分秒,要表達是哪裏的時間須要時區解釋。後端
Instant是時間戳,是指世界標準時格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至如今的總秒數,Instant自己已經攜帶了時區信息,默認是0時區。
ZonedDateTime是含有時區信息的時間,能夠理解爲它是Instant的格式化對象,
JDK 8之前的時區是用TimeZone,TimeZone ID是在java裏ZoneInfoFile類加載的。在jvm初始化的時候,會讀取jdk安裝目錄下的 ${ java.home } /jre/lib/tzdb.dat,放到其成員變量爲zones的ConcurrentHashMap裏。當調用TimeZone.getTimeZone(id)方法時,會用id到這個map裏進行匹配獲取到指定id的時區。其中TimeZone.getTimeZone("Asia/Shanghai")和TimeZone.getTimeZone("GMT+8")是相同的,能夠相互替換使用。瀏覽器
System.out.println(ZonedDateTime.ofInstant(Instant.now(),ZoneId.systemDefault()).toInstant()); System.out.println(ZonedDateTime.ofInstant(Instant.now(),"Australia/Darwin").toInstant());
相同的Instant,在不一樣的時區有不一樣的展現時間,因此在用Instant構造ZonedDateTime的時候須要傳入時區;ZonedDateTime能夠直接轉化爲Instant,而且不一樣的ZonedDateTime可能會生成一樣的Instant服務器
用戶輸入的String類型的時間是沒有時區信息的,須要人爲指定時區再解析。
解析的步驟分2步: 先肯定用戶時區
1.把用戶輸入的時間轉化爲世界標準時間;//Instant.parse("2010-10-12T15:24:22Z")
2.再把世界標準時間轉爲須要的時區的時間。//ZonedDateTime.ofInstant(instant,ZoneId.systemDefault());jvm
首前後端封裝一個接口後獲取服務器相對GMT(格林尼治標準時間)時間的偏移量:code
TimeZone zone = TimeZone.getDefault(); System.out.println(zone.getRawOffset());
這段代碼放在不一樣時區的服務器上執行結果會不一樣(前提是服務器的時區設置跟本地時區一致)。若是在泰國執行結果爲25200000ms,換算成小時爲7,說明泰國的時區的偏移量相對於GMT標準時間相差7小時。下文簡稱「時區偏移量」。orm
前端首先調用該接口獲取服務器的時區偏移量,再在瀏覽器上獲取本地的時區偏移量,計算出兩個偏移量的差值。本地瀏覽器上獲取當前的時間戳,減去上一步計算出來的差值便可獲得服務器這個時間的時間戳,把這個時間戳傳給後端 再轉換成時間,就是服務器對應的時間,存入數據庫便可。
前端:server
//服務的時區偏移量,經過接口得到,注意換成負值 var serveroffset=-25200000; var d = new Date(); //獲取本地瀏覽器的時區偏移量 var localOffset = d.getTimezoneOffset() * 60000; //的到本地和偏移量的差值 var deffoffset=localOffset-(serveroffset); //獲取本地瀏覽器時間戳 var localTime = d.getTime(); //計算出傳到服務器的時間戳 var servertime=localTime+deffoffset;
經過上述方式,能夠實現服務器全球各地部署,系統均可以正常使用。