日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解Java時區處理之Date,Calendar,TimeZone,SimpleDateFormat

瀏覽:14日期:2022-08-28 18:58:57

一、概述

1、問題描述

使用Java處理時間時,我們可能會經常發現時間不對,比如相差8個小時等等,其真實原因便是TimeZone。只有正確合理的運用TimeZone,才能保證系統時間無論何時都是準確的。由于我在外企工作,服務器在美國,美國也有很多時區,經常會碰到向處于不同時區的服務器發請求時需要考慮時區轉換的問題。譬如,服務器位于西八區(GMT-8:00),而身處東八區的用戶想要查詢當天的銷售記錄。則需把東八區的“今天”這個時間范圍轉換為服務器所在時區的時間范圍。

2、時區認識

GMT時間:即格林威治平時(Greenwich Mean Time)。平太陽時是與視太陽時對應的,由于地球軌道非圓形,運行速度隨地球與太陽距離改變而出現變化,因此視太陽時欠缺均勻性。為了糾正這種不均勻 性,天文學家就計算地球非圓形軌跡與極軸傾斜對視太陽時的效應,而平太陽時就是指經修訂之后的視太陽時。在格林威治子午線上的平太陽時稱為世界時(UTC), 又叫格林威治平時(GMT)。

3、Java 時間和時區API

3.1、Date

類Date表示特定的瞬間,精確到毫秒。獲得一個表示當前時間的Date對象有兩種方式:

Date date = new Date(); Date date = Calendar.getInstance().getTime();

Date對象本身所存儲的毫秒數可以通過date.getTime()方法得到;該函數返回自1970年1月1日 00:00:00 GMT以來此對象表示的毫秒數。它與時區和地域沒有關系(其實可以認為是GMT時間),而且還會告訴我們這個時區是否使用夏令時。有個這個信息,我們就能夠繼續將時區對象和日期格式化器結合在一起在其它的時區和其它的語言顯示時間了。

3.2、 Calendar

Calendar的getInstance()方法有參數為TimeZone和Locale的重載,可以使用指定時區和語言環境獲得一個日歷。無參則使用默認時區和語言環境獲得日歷。

3.3、TimeZone

TimeZone對象給我們的是原始的偏移量,也就是與GMT相差的微秒數,即TimeZone表示時區偏移量,本質上以毫秒數保存與GMT的差值。

獲取TimeZone可以通過時區ID,如'America/New_York',也可以通過GMT+/-hh:mm來設定。例如北京時間可以表示為GMT+8:00。

TimeZone.getRawOffset()方法可以用來得到當前時區的標準時間到GMT的偏移量。上段提到的'America/New_York'和'GMT+8:00'兩個時區的偏移量分別為-18000000和28800000。

4、影響TimeZone的因素

1. 操作系統的時區設置。

2. 數據傳輸時時區設置。

第一個原因其實是根本原因,當數據在不同操作系統間流轉時,就有可能因為操作系統的差異造成時間偏差,而JVM默認情況下獲取的就是操作系統的時區設置。因此在項目中最好事先設置好時區,例如:

TimeZone.setDefault(TimeZone.getTimeZone('Asia/Shanghai'));

5、解決的方法:

從以上的分析可以看出,解決時區問題就簡單了,在時區間轉換時間時,首先用原時間減掉原時間所在時區相對于GMT的偏移量,得到原時間相對于GMT的值,然后再加上目標時區相對GMT的偏移量即可。需要注意的是這樣得到的結果依然是毫秒數,所以我們要按照指定日期格式重新轉換成Date對象即可。

6、實例:

在實例之前,假設當前的時區為中國的東八區。即GMT+8:00

package com.wsheng.aggregator.timezone;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.TimeZone;/** * @author Josh Wang(Sheng) * * @email swang6@ebay.com * */public class TimeZone1 {public static void main(String[] args) { Date date = new Date(1391174450000L); // 2014-1-31 21:20:50 String dateStr = '2014-1-31 21:20:50 '; SimpleDateFormat dateFormat = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); dateFormat.setTimeZone(TimeZone.getTimeZone('GMT')); try { Date dateTmp = dateFormat.parse(dateStr); System.out.println(dateTmp); } catch (ParseException e) { e.printStackTrace(); } String dateStrTmp = dateFormat.format(date); System.out.println(dateStrTmp); }}

執行結果:

Sat Feb 01 05:20:50 CST 20142014-01-31 13:20:50

我們發現同一時間,字符串和日期運行出來的結果并不相同,那么我們應該怎么理解呢?

一切都要以根本原因, 即當前操作系統的時間為基準。

我的操作系統 是'Asia/Shanghai',即GMT+8的北京時間,那么執行日期轉字符串的format方法時,由于日期生成時默認是操作系統時區,因此 2014-1-31 21:20:50是北京時間,那么推算到GMT時區,自然是要減8個小時的,即結果(2014-01-31 13:20:50);而執行字符串轉日期的parse方法時,由于字符串本身沒有時區的概念,因此 2013-1-31 22:17:14就是指GMT(UTC)時間【ps:所有字符串都看做是GMT時間】,那么當轉化為日期時要加上默認時區, 即'Asia/Shanghai',因此要加上8個小時。

用Calendar的話,如下:

package com.wsheng.aggregator.timezone;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;/** * @author Josh Wang(Sheng) * * @email swang6@ebay.com * */public class TimeZone2 { public static void main(String[] args) { Date date = new Date(1391174450000L); // 2014-1-31 21:20:50 System.out.println(date); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone('GMT')); // 或者可以 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone('GMT')); calendar.setTime(date); System.out.println(calendar.get(Calendar.HOUR_OF_DAY) + ':' + calendar.get(Calendar.MINUTE)); } }

執行結果:

Fri Jan 31 21:20:50 CST 201413:20

Calendar不涉及到日期與字符串的轉化,因此不像SimpleDateFormat那么復雜,與日期轉字符串的思路類似。但是需要注意的是,設置完時區后,我們不能用calendar.getTime()來直接獲取Date日期,因為此時的日期與一開始setTime時是相同值,要想獲取某時區的時間,正確的做法是用calendar.get()方法,那么我們怎么獲得Date類型的日期呢?

正確的做法如下:

package com.wsheng.aggregator.timezone;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;/** * @author Josh Wang(Sheng) * * @email swang6@ebay.com * */public class TimeZone3 { public static void main(String[] args) { Date date = new Date(1391174450000L); // 2014-1-31 21:20:50 System.out.println(date); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone('GMT')); // 或者可以 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone('GMT')); calendar.setTime(date); Calendar calendar2 = Calendar.getInstance(); calendar2.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); System.out.println(calendar2.getTime()); } }

執行結果:

Fri Jan 31 21:20:50 CST 2014Fri Jan 31 13:20:50 CST 2014

完美通用轉換方法

其實上面兩個轉換方法都要受到操作系統的時區設置影響,如果軟件在不同操作系統運行,仍然會有時間誤差,那么怎么才能統一呢?

/** * */package com.wsheng.aggregator.timezone;import java.util.Date;import java.util.TimeZone;/** * @author Josh Wang(Sheng) * * @email swang6@ebay.com * */public class TimeZone4 { public static void main(String[] args) { Date date = new Date(1391174450000L); // 2014-1-31 21:20:50 System.out.println(date); date = changeTimeZone(date, TimeZone.getTimeZone('Asia/Shanghai'), TimeZone.getTimeZone('GMT')); System.out.println(date); } /** * 獲取更改時區后的日期 * @param date 日期 * @param oldZone 舊時區對象 * @param newZone 新時區對象 * @return 日期 */ public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) { Date dateTmp = null; if (date != null) { int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset(); dateTmp = new Date(date.getTime() - timeOffset); } return dateTmp; } }

運行結果:

Fri Jan 31 21:20:50 CST 2014Fri Jan 31 13:20:50 CST 2014

更通用的,我們可以寫一個支持類型轉換的類:

package com.wsheng.aggregator.timezone;import java.text.*; import java.util.*; /** * * @author Josh Wang(Sheng) * * @email swang6@ebay.com * */public class DateTransformer { public static final String DATE_FORMAT = 'MM/dd/yyyy HH:mm:ss'; public static String dateTransformBetweenTimeZone(Date sourceDate, DateFormat formatter, TimeZone sourceTimeZone, TimeZone targetTimeZone) { Long targetTime = sourceDate.getTime() - sourceTimeZone.getRawOffset() + targetTimeZone.getRawOffset(); return DateTransformer.getTime(new Date(targetTime), formatter); } public static String getTime(Date date, DateFormat formatter){ return formatter.format(date); } public static void main(String[] args){ DateFormat formatter = new SimpleDateFormat(DATE_FORMAT); Date date = Calendar.getInstance().getTime(); System.out.println(' date: ' + date); TimeZone srcTimeZone = TimeZone.getTimeZone('EST'); TimeZone destTimeZone = TimeZone.getTimeZone('GMT+8'); System.out.println(DateTransformer.dateTransformBetweenTimeZone(date, formatter, srcTimeZone, destTimeZone)); } }

DateFormat是日期/時間格式化子類的抽象類,它以與語言無關的方式格式化并解析日期或時間。日期/時間格式化子類(如 SimpleDateFormat)允許進行格式化(也就是日期 -> 文本)、解析(文本-> 日期)和標準化。將日期表示為 Date 對象,或者表示為從 GMT(格林尼治標準時間)1970 年 1 月 1 日 00:00:00 這一刻開始的毫秒數。SimpleDateFormat則是一個以與語言環境有關的方式來格式化和解析日期的具體類,可以以“日期和時間模式”字符串指定日期和時間格式。我們函數中所用模式字符串為'MM/dd/yyyy HH:mm:ss',則輸出日期:'07/16/2013 04:00:00'

其他常見的模式字母定義如下:

字母 日期或時間元素 表示 示例 G Era 標志符 Text AD y 年 Year 1996; 96 M 年中的月份 Month July; Jul; 07 w 年中的周數 Number 27 W 月份中的周數 Number 2 D 年中的天數 Number 189 d 月份中的天數 Number 10 F 月份中的星期 Number 2 E 星期中的天數 Text Tuesday; Tue a Am/pm 標記 Text PM H 一天中的小時數(0-23) Number 0 k 一天中的小時數(1-24) Number 24 K am/pm 中的小時數(0-11) Number 0 h am/pm 中的小時數(1-12) Number 12 m 小時中的分鐘數 Number 30 s 分鐘中的秒數 Number 55 S 毫秒數 Number 978 z 時區 General time zone Pacific Standard Time; PST; GMT-08:00 Z 時區 RFC 822 time zone -0800

由上面的分析和事例說明可知:

1. 計算機內部記錄的時間(Date date = new Date()), 為格林威治標準時(GMT). 即java.util.Date代表一個時間點,其值為距公元1970年1月1日 00:00:00的毫秒數。所以它可以認為是沒有時區和Locale概念的。

2. 日期格式化類DateFormat, 對于不同地區的配置一般有兩個點, 一個是Locale , 一個是TimeZone 前者(Locale)使DateFormat按所配置的地區特性來輸出文字(例如中國,美國,法國不同地區對日期的表示格式不一樣,中國可能是2001年10月5日) 后者(TimeZone)讓DateFormat知道怎么去轉換,去調整時間偏移度,從而得到符合配置的時區的時間.(即假設取得當前時間(假設當前時區為GMT+0,即與new Date()最后轉換的時間毫秒數一致)為2:00, 那么如果你配置DateFormat.setTimeZome('GMT+8'), 即北京時間的時區, 那么這時候格式化輸出的就是10:00了, 因為系統對原始毫秒數進行了時間偏移調整(調到你設置的時區),即加多8小時,之后再格式化輸出日期的字符串形式)

3. GMT與UTC的時區是一樣的,都是以倫敦時間為基準. 而GMT+8時區就是北京時間所在時區.同一時刻的時間比GMT快8小時。

到此這篇關于Java時區處理之Date,Calendar,TimeZone,SimpleDateFormat的區別于用法的文章就介紹到這了,更多相關Java時區處理 Date,Calendar,TimeZone,SimpleDateFormat內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91日韩免费| 91av亚洲| 亚洲欧美网站| 精品91久久久久| 日韩一区二区免费看| 尤物在线精品| 蜜臀av在线播放一区二区三区| 不卡av一区二区| 黄色亚洲在线| 亚洲午夜免费| 国产日韩亚洲| 国产成人精选| 国产一区二区三区久久| 红杏一区二区三区| | 欧美日韩1区| 国产精品第十页| 成人一区而且| 激情综合网站| 亚洲精品视频一二三区| 国产欧美欧美| 欧产日产国产精品视频| 亚洲激情中文| 欧美日韩在线精品一区二区三区激情综合| 国产精品麻豆成人av电影艾秋| 久久女人天堂| 国内在线观看一区二区三区| 香蕉成人av| 在线免费观看亚洲| 国产精品亚洲二区| 久久久久久美女精品| 亚洲少妇诱惑| 国产精品第十页| 91精品婷婷色在线观看| 蜜桃久久久久久| 国产精品免费精品自在线观看| 日产精品一区二区| 99亚洲视频| 欧美激情三区| 国精品一区二区| 日本三级亚洲精品| 国产66精品| 日韩精品一级中文字幕精品视频免费观看| 欧美一区激情| 久久国产日韩| 免费亚洲婷婷| 99riav国产精品| 免费一级欧美在线观看视频 | 老司机免费视频一区二区| www.com.cn成人| 亚洲综合不卡| 亚洲欧美日韩视频二区| 91亚洲精品视频在线观看 | 色在线视频观看| 首页欧美精品中文字幕| 国产精品一卡| 国产精品日本欧美一区二区三区| 国产精品va视频| 国产一区成人| 成人在线观看免费视频| 免播放器亚洲一区| 欧美少妇精品| 久久精品超碰| 国产精品毛片| 日韩成人精品一区| 久久电影一区| 久草免费在线视频| 日韩av一区二区在线影视| 99tv成人| 精品久久久亚洲| 亚洲狼人精品一区二区三区| 色一区二区三区| 国产精品一国产精品k频道56| 国产视频一区免费看| 国产精品久久观看| 日本在线一区二区三区| 激情婷婷综合| 超碰99在线| 国产精品一区二区精品| 日韩在线播放一区二区| 国产成人久久| 久久精品99国产国产精| 国产亚洲在线| 99久久精品国产亚洲精品| 久久99视频| 青草国产精品| 亚洲人成网77777色在线播放| 久久亚洲国产| а√天堂8资源中文在线| 国产精品亚洲产品| 综合在线一区| 国产一区视频在线观看免费| 国产在线观看91一区二区三区 | 一区三区视频| 播放一区二区| 久久影院午夜精品| 精品国内亚洲2022精品成人| 欧美三区不卡| 91国内精品| 日韩精品一区二区三区av | 综合日韩在线| 亚洲一区二区三区高清| 91精品一区二区三区综合在线爱 | 国产精品中文字幕亚洲欧美| 免费国产亚洲视频| 国产偷自视频区视频一区二区| 久久精品青草| 99精品美女| 欧美二三四区| 都市激情国产精品| 国产成人免费精品| 精品视频91| 久久精品伊人| 卡一精品卡二卡三网站乱码| 国产精品极品国产中出| 国产一卡不卡| 国产欧美88| 国产欧美久久一区二区三区| 欧美日韩夜夜| 日韩激情视频网站| 蜜臀av国产精品久久久久| 老司机久久99久久精品播放免费| 亚洲免费影视| 亚洲精品美女91| 亚洲精品在线二区| 亚洲免费成人av在线| 色狠狠一区二区三区| 亚洲精品乱码| 国产精品资源| 精品视频在线你懂得| 精品欠久久久中文字幕加勒比| 美女尤物国产一区| 国产成人精选| 91精品啪在线观看国产18| 天堂√8在线中文| 久久久天天操| 婷婷成人基地| 日韩在线a电影| 欧美日韩国产一区二区在线观看| 久久国产乱子精品免费女| 国产伦乱精品| 精品久久免费| 肉色欧美久久久久久久免费看| 欧洲av一区二区| 红桃视频国产一区| 日韩一区精品| 另类小说一区二区三区| 婷婷综合六月| 免费在线观看日韩欧美| 视频一区视频二区在线观看| 亚洲精品第一| 国产精品红桃| 久久精品一区二区不卡| 亚洲免费影视| 国产欧美另类| 日韩国产一区二区| 影院欧美亚洲| 国产香蕉精品| 日本久久成人网| 蜜桃视频在线观看一区二区| 国产精品一卡| 99久久亚洲精品蜜臀| 视频一区二区不卡| 国产精品欧美在线观看| 国产精品99一区二区三区| 91精品婷婷色在线观看| 亚洲精品九九| 成人在线视频中文字幕| 欧美日韩国产亚洲一区| 久久激五月天综合精品| 在线一区视频观看| 日本综合精品一区| 给我免费播放日韩视频| 久久福利一区| 美女久久99| 999精品一区| 日韩精品福利一区二区三区| 国产精品黑丝在线播放| 亚洲视频电影在线| 另类综合日韩欧美亚洲| 日韩网站在线| 国产一区二区三区免费在线| 视频在线观看国产精品| 麻豆国产一区| 久久亚洲电影| 久久uomeier| 日韩亚洲精品在线观看| 波多视频一区| 日本99精品| 欧美精品一二| 久久精品一区二区国产| 免费人成精品欧美精品| 国产成人精品一区二区免费看京| 日韩在线一区二区| 国产成人精品一区二区免费看京| 国产视频一区三区| 国产成人精品一区二区免费看京| 亚洲涩涩av| 伊人精品一区| 鲁大师精品99久久久|