//獲得標準時區的時間 function getLocalTime(i) { //參數i爲時區值數字,好比北京爲東八區則輸入8,西5輸入-5,現默認東八區北京時間 var i=i?parseFloat(i):8; //獲得本地時間 var d = new Date(); //獲得1970年一月一日到如今的秒數 var local = d.getTime(); //本地時間與GMT時間的時間偏移差 var offset = d.getTimezoneOffset() * 60000; //獲得如今的格林尼治時間 var utcTime = local + offset; return new Date(utcTime + 3600000 * i); }
//轉換服務器時區時間 function formatTime(t,utc){ //t傳入的時間參數,utc傳入的時區參數 if(!t) return; //獲取本地時間 var d=new Date(); //得到本地時區 utc=utc?parseFloat(utc):d.getTimezoneOffset()/60; //格式化傳入時間 var time=new Date(t); //轉換傳入時間爲本地時間(默認傳入服務器時間爲東八區時間) time.setHours(time.getHours()+(utc-8)); //輸出時間 var yy=time.getFullYear(); var MM=time.getMonth()+1; MM=MM<10?'0'+MM:MM; var dd=time.getDate(); dd=dd<10?'0'+dd:dd; var hh=time.getHours(); hh=hh<10?'0'+hh:hh; var mm=time.getMinutes(); mm=mm<10?'0'+mm:mm; var ss=time.getSeconds(); ss=ss<10?'0'+ss:ss; var date=yy+'-'+MM+'-'+dd+' '+hh+':'+mm+':'+ss; return date; }
d = new Date(); localTime = d.getTime(); //經過調用Data()對象的getTime()方法,便可顯示1970年1月1往後到此時時間之間的毫秒數。
接下來,經過Data()對象的getTimezoneOffset()方法來找出當地時間偏移值。在缺省狀況下,此方法以分鐘顯示時區偏移值結果,所以在早先的計算中要將此值轉換成毫秒。java
localOffset = d.getTimezoneOffset() * 3600000;
而後將當前時間與時區偏移量相加,獲得國際標準時間(用毫秒錶示的,由於後面還須要計算,因此這裏不作轉換),而後與你想要知道的時區的偏移量再進行相加,獲得那個時間的時間,而後再利用Date對象將其轉換爲時間字符串。程序員
utc = localTime + localOffset; //獲得國際標準時間 offset = 5.5; // 已知的時區 calctime = utc + (3600000*offset); nd = new Date(calctime); document.write('指定時區時間是:' + nd.toLocalString());
場景描述:根據國外用戶所在的時區,獲取數據庫(東八區錄入)在當地所應展現的時間數據庫
function getLocalTime() { var d = new Date();//得到當前時間 var gmtHours =-( d.getTimezoneOffset()/60);//根據當前時間獲得你是哪一個時區的 var date = '2014-08-12 09:25:24';//上課時間 date=date.replace(/-/g,':').replace(' ',':'); date=date.split(':'); var time1 = new Date(date[0],(date[1]-1),date[2],date[3],date[4],date[5]); console.log("時區:" + gmtHours); //獲得1970年一月一日到如今的秒數 var len = time1.getTime(); //本地時間與GMT時間的時間偏移差 var offset = -8 * 3600000; // 東八區 //獲得如今的格林尼治時間 var utcTime = len + offset; return new Date(utcTime + 3600000 *gmtHours ); }
在java中,只要咱們執行 Date date = new Date();
就能夠獲得當前時間。如:服務器
Date date = new Date(); System.out.println(date);
輸出結果是: Thu Aug 24 10:15:29 CST 2017
函數
也就是我執行上述代碼的時刻:2017年8月24日10點15分29秒。是否是Date對象裏存了年月日時分秒呢?不是的,Date對象裏存的只是一個long型的變量,其值爲自1970年1月1日0點至Date對象所記錄時刻通過的毫秒數,調用Date對象getTime()方法就能夠返回這個毫秒數,以下代碼:操作系統
Date date = new Date(); System.out.println(date + ", " + date.getTime());
輸出以下: Thu Aug 24 10:48:05 CST 2017, 1503542885955
即上述程序執行的時刻是2017年8月24日10點48分05秒,該時刻距離1970年1月1日0點通過了1503542885955毫秒。反過來講,輸出的年月日時分秒實際上是根據這個毫秒數來反算出來的。code
全球分爲24個時區,相鄰時區時間相差1個小時。好比北京處於東八時區,東京處於東九時區,北京時間比東京時間晚1個小時,而英國倫敦時間比北京晚7個小時(英國採用夏令時時,8月英國處於夏令時)。好比此刻北京時間是2017年8月24日11:17:10,則東京時間是2017年8月24日12:17:10,倫敦時間是2017年8月24日4:17:10。orm
既然Date裏存放的是當前時刻距1970年1月1日0點時刻的毫秒數,若是此刻在倫敦、北京、東京有三個程序員同時執行以下語句:對象
Date date = new Date();
那這三個date對象裏存的毫秒數是相同的嗎?仍是北京的比東京的小3600000(北京時間比東京時間晚1小時,1小時爲3600秒即3600000毫秒)?答案是,這3個Date裏的毫秒數是徹底同樣的。確切的說,Date對象裏存的是自格林威治時間( GMT)1970年1月1日0點至Date對象所表示時刻所通過的毫秒數。因此,若是某一時刻遍及於世界各地的程序員同時執行new Date語句,這些Date對象所存的毫秒數是徹底同樣的。也就是說,Date裏存放的毫秒數是與時區無關的。字符串
繼續上述例子,若是上述3個程序員調用那一刻的時間是2017年8月24日11:17:10,他們繼續調用
System.out.println(date);
那麼北京的程序員將會打印出2017年8月24日11:17:10,而東京的程序員會打印出2017年8月24日12:17:10,倫敦的程序員會打印出2017年8月24日4:17:10。既然Date對象只存了一個毫秒數,爲何這3個毫秒數徹底相同的Date對象,能夠打印出不一樣的時間呢?這是由於Sysytem.out.println函數在打印時間時,會取操做系統當前所設置的時區,而後根據這個時區將同毫秒數解釋成該時區的時間。固然咱們也能夠手動設置時區,以將同一個Date對象按不一樣的時區輸出。能夠作以下實驗驗證:
Date date = new Date(1503544630000L); // 對應的北京時間是2017-08-24 11:17:10 SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 北京 bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 設置北京時區 SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 東京 tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 設置東京時區 SimpleDateFormat londonSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 倫敦 londonSdf.setTimeZone(TimeZone.getTimeZone("Europe/London")); // 設置倫敦時區 System.out.println("毫秒數:" + date.getTime() + ", 北京時間:" + bjSdf.format(date)); System.out.println("毫秒數:" + date.getTime() + ", 東京時間:" + tokyoSdf.format(date)); System.out.println("毫秒數:" + date.getTime() + ", 倫敦時間:" + londonSdf.format(date));
輸出爲:
毫秒數:1503544630000, 北京時間:2017-08-24 11:17:10 毫秒數:1503544630000, 東京時間:2017-08-24 12:17:10 毫秒數:1503544630000, 倫敦時間:2017-08-24 04:17:10
能夠看出,同一個Date對象,按不一樣的時間來格式化,將獲得不一樣時區的時間。因而可知,Date對象裏保存的毫秒數和具體輸出的時間(即年月日時分秒)是模型和視圖的關係,而時區(即Timezone)則決定了將同模型展現成什麼樣的視圖。
有時咱們會遇到從一個字符串中讀取時間的要求,即從字符串中解析時間並獲得一個Date對象,好比將"2017-8-24 11:17:10"解析爲一個Date對象。如今問題來了,這個時間到底指的是北京時間的2017年8月24日11:17:10,仍是東京時間的2017年8月24日11:17:10?若是指的是北京時間,那麼這個時間對應的東京時間2017年8月24日12:17:10;若是指的是東京時間,那麼這個時間對應的北京時間就是2017年8月24日10:17:10。所以,只說年月日時分秒而不說是哪一個時區的,是有歧義的,沒有歧義的作法是,給出一個時間字符串,同時指明這是哪一個時區的時間。 從字符串中解析時間的正確做法是:指定時區來解析。示例以下:
String timeStr = "2017-8-24 11:17:10"; // 字面時間 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 設置北京時區 Date d = sdf.parse(timeStr); System.out.println(sdf.format(d) + ", " + d.getTime());
輸出爲: 2017-08-24 11:17:10, 1503544630000
,
將一個時間字符串按不一樣時區來解釋,獲得的Date對象的值是不一樣的。驗證以下:
String timeStr = "2017-8-24 11:17:10"; // 字面時間 SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); Date bjDate = bjSdf.parse(timeStr); // 解析 System.out.println("字面時間: " + timeStr +",按北京時間來解釋:" + bjSdf.format(bjDate) + ", " + bjDate.getTime()); SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 東京 tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 設置東京時區 Date tokyoDate = tokyoSdf.parse(timeStr); // 解析 System.out.println("字面時間: " + timeStr +",按東京時間來解釋:" + tokyoSdf.format(tokyoDate) + ", " + tokyoDate.getTime());
輸出爲:
字面時間: 2017-8-24 11:17:10,按北京時間來解釋:2017-08-24 11:17:10, 1503544630000 字面時間: 2017-8-24 11:17:10,按東京時間來解釋:2017-08-24 11:17:10, 1503541030000 能夠看出,對於"2017-8-24 11:17:10"這個字符串,按北京時間來解釋獲得Date對象的毫秒數是 1503544630000;而按東京時間來解釋獲得的毫秒數是1503541030000,前者正比如後者大於3600000毫秒即1個小時,正好是北京時間和東京時間的時差。這很好理解,北京時間2017-08-24 11:17:10對應的毫秒數是1503544630000,而東京時間2017-08-24 11:17:10對應的北京時間實際上是2017-08-24 10:17:10(由於北京時間比東京時間晚1個小時),北京時間2017-08-24 10:17:10天然比北京時間2017-08-24 11:17:10少3600000毫秒。
綜合以上分析,若是給定一個時間字符串,並告訴你這是某個時區的時間,要將它轉換爲另外一個時區的時間並輸出,正確的作法是:
好比,將北京時間"2017-8-24 11:17:10"輸出成東京時間,代碼爲:
String timeStr = "2017-8-24 11:17:10"; // 字面時間 SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); Date date = bjSdf.parse(timeStr); // 將字符串時間按北京時間解析成Date對象 SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 東京 tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 設置東京時區 System.out.println("北京時間: " + timeStr +"對應的東京時間爲:" + tokyoSdf.format(date));
輸出爲: 北京時間:2017-8-24 11:17:10對應的東京時間爲:2017-08-24 12:17:10