Date中保存的是什麼
在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毫秒。反過來說,輸出的年月日時分秒其實是根據這個毫秒數來反算出來的。
時區的概念
全球分爲24個時區,相鄰時區時間相差1個小時。比如北京處於東八時區,東京處於東九時區,北京時間比東京時間晚1個小時,而英國倫敦時間比北京晚7個小時(英國採用夏令時時,8月英國處於夏令時)。比如此刻北京時間是2017年8月24日11:17:10,則東京時間是2017年8月24日12:17:10,倫敦時間是2017年8月24日4:17:10。調用Date對象getTime()方法就可以返回這個毫秒數。
Date的時區無關性
既然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裏存放的毫秒數是與時區無關的。
Date 與 Sting 格式互轉:
package utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* Date 和 String
* 關於時間的格式,在應用中一般用 Stirng 和 Date 來表示,
*
* Date--> String 沒有時區的概念,Date中的內容都是 國際的,當getHour() toString() 等方法時,
* 通過 獲取本地的時區對Date進行格式轉換再輸出
*
* String --> Date 時,傳遞的 String,默認是本地的時區時間,如果傳遞的參數不是本地時區時間時,
* 在轉換爲 Date時,需要指定時區
*/
public class Test_TimeZone {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date.getTime()); // 全球統一值
System.out.println(date.toString()); // toString的時候獲取本地時區,做了時間轉換,並不是Date的真實時間
System.out.println();
String date_str_1 = format(date);
System.out.println(date_str_1);
Date date_1 = parse(date_str_1);
System.out.println(date_1.toString());
/* 查看 支持的 TimeZone
String[] ss = TimeZone.getAvailableIDs();
for (String string : ss) {
if (string.indexOf("GMT") > 0) {
System.out.println(string);
}
}
*/
}
/**
* 日期格式轉字符串 (Date -- > String)
* Date 轉字符串,格式隨便定義都可以
*/
public static String format(Date date) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//df.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));
df.setTimeZone(TimeZone.getTimeZone("GMT")); // 國際時間,決定輸出的 String 是國際格式
return df.format(date);
}
/**
* 字符串轉日期格式 (String --> Date)
*/
public static Date parse(String s) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//df.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));
df.setTimeZone(TimeZone.getTimeZone("GMT")); // 指定參數 String爲國際格式,輸出時,按本地時區輸出
return df.parse(s);
}
}
將 某個時區 的 String 格式 轉換爲 另一個時區的 String 格式
package utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Test_Time {
public static void main(String[] args) throws ParseException {
parse_format();
}
/**
* 將 某個時區的 String 的格式 轉換爲 另一個時區的 String 格式
* @throws ParseException
*/
public static void parse_format() throws ParseException {
String timeStr = "2017-8-24 11:17:10";
/*
* 一般是通過 Date 轉換過來的,Date 轉換到 String 的時候 需要指定時區,所以得到的String是有時區的
* (當你此刻輸入一個 String 格式的時間時,這個String一定是有時區的,所以 要深刻理解 String 是有時區的,
* 任何時候需要操作該值的時候,都要指定 String 代表的時區)
*/
SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
bjSdf.setTimeZone(TimeZone.getTimeZone("GMT"));
/*
* 指定 字符串的時區
* 將字符串時間按 國際時間 解析成Date對象
* (因爲你通過其他地方獲取的 String 是國際時間格式,所以按照國際時間轉換)
*/
Date date = bjSdf.parse(timeStr);
System.out.println(date.getTime());
/*
* 如果你獲取的 是 本地的字符串時間,那就需要按照 本地的 時區轉換,
* 轉換成功之後,獲取的Date都是國際格式,但是在 toString的時候,會默認按本地時區輸出,但是輸出內容並不是國際時間,
*
* 但getTime()是統一的,所以我們認爲 Date 沒有時區的概念,任何的輸出操作都會先獲取本地時區,將國際時間格式的Date,按本地時區輸出。(輸出內容不可信)
*/
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 東京
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 設置東京時區
System.out.println("國際時間: " + timeStr + " 對應的東京時間爲:" + tokyoSdf.format(date));
/*
* 輸出:
* 1503573430000
* 國際時間: 2017-8-24 11:17:10 對應的東京時間爲:2017-08-24 20:17:10
* */
}
}
我覺得這兩個例子,應該就能說明大部分問題了,
深刻理解 Date 沒有時區的概念,任何的輸出信息都是根據本地時區來輸出的。
任何一個 String 格式的字符串都有相對應的時區,因爲任何的String都是通過 new Date() 和 format() 轉換過來的,即使沒有寫時區,當時默認也獲取了本地時區。所以,Sting 一定有對應的時區。
參考博客:
https://blog.csdn.net/halfclear/article/details/77573956
https://www.cnblogs.com/softidea/p/8612287.html