Date本身沒有時區概念
查看源碼可以知道, Date對象中存儲的是一個long型變量
這個變量的值爲自1997-01-01 00:00:00(GMT)至Date對象記錄時刻所經過的毫秒數
可以通過getTime()方法,獲取這個變量值,且這個變量值和時區沒有關係
全球任意地點同時執行new Date().getTime()獲取到的值相同
Date源碼
private transient long fastTime;
/**
* Allocates a <code>Date</code> object and initializes it so that
* it represents the time at which it was allocated, measured to the
* nearest millisecond.
*
* @see java.lang.System#currentTimeMillis()
*/
public Date() {
this(System.currentTimeMillis());
}
/**
* Allocates a <code>Date</code> object and initializes it to
* represent the specified number of milliseconds since the
* standard base time known as "the epoch", namely January 1,
* 1970, 00:00:00 GMT.
*
* @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
* @see java.lang.System#currentTimeMillis()
*/
public Date(long date) {
fastTime = date;
}
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this <tt>Date</tt> object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
public long getTime() {
return getTimeImpl();
}
private final long getTimeImpl() {
if (cdate != null && !cdate.isNormalized()) {
normalize();
}
return fastTime;
}
/**
* Converts this <code>Date</code> object to a <code>String</code>
* of the form:
* <blockquote><pre>
* dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
* where:<ul>
* <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
* Thu, Fri, Sat</tt>).
* <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
* Jul, Aug, Sep, Oct, Nov, Dec</tt>).
* <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
* <tt>31</tt>), as two decimal digits.
* <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
* <tt>23</tt>), as two decimal digits.
* <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
* <tt>59</tt>), as two decimal digits.
* <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
* <tt>61</tt>, as two decimal digits.
* <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
* time). Standard time zone abbreviations include those
* recognized by the method <tt>parse</tt>. If time zone
* information is not available, then <tt>zzz</tt> is empty -
* that is, it consists of no characters at all.
* <li><tt>yyyy</tt> is the year, as four decimal digits.
* </ul>
*
* @return a string representation of this date.
* @see java.util.Date#toLocaleString()
* @see java.util.Date#toGMTString()
*/
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == BaseCalendar.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
// 注意: 這裏涉及到時區
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
getTime()獲取毫秒數,獲取到的毫秒數和格式化後時間的關係
這個變量的值爲自1997-01-01 00:00:00(GMT)至Date對象記錄時刻所經過的毫秒數
這個毫秒數和格式化後時間是模型和視圖的關係, 時區(TimeZone)決定了同一模型展示成什麼樣的視圖(格式化Date)
Date date = new Date();
System.out.println(date);
System.out.println(date.getTime());
// 輸出
Tue Dec 10 18:44:24 CST 2019
1575974664352
格式化Date對象成字符串, 涉及時區
不管是調用Date對象的toString方法, 還是使用SimpleDateFormat的format方法去格式化Date對象,或者使用parse解析字符串成Date對象都會涉及到時區,
也就是說Date對象沒有時區概念, 但是格式化Date對象, 或者解析字符串成Date對象時, 是有時區概念的
toString
Date date = new Date();
// 默認是系統時區
System.out.println(date);
// 修改默認時區
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
System.out.println(date);
// 輸出
Tue Dec 10 19:03:46 CST 2019
Tue Dec 10 11:03:46 GMT 2019
SimpleDateFormat
Date date = new Date();
// 默認是系統時區
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateFormat.format(date));
// 設置時區
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
System.out.println(dateFormat.format(date));
// 輸出
2019-12-10 19:06:31
2019-12-10 12:06:31
解析字符串成Date對象, 涉及時區
將同一個時間字符串按照不同的時區來解析, 得到的Date對象值不一樣
很好理解: 東八區8點當然和0時區8點不一樣
String dateStr = "2019-12-10 08:00:00";
// 默認是系統時區
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = dateFormat.parse(dateStr);
System.out.println(date1.getTime());
// 設置時區
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
Date date2 = dateFormat.parse(dateStr);
System.out.println(date2.getTime());
// 輸出
1575936000000
1575961200000
將本地的時間字符串轉換成另一時區的時間字符串
String dateStr = "2019-12-10 08:00:00";
// 按照本地時區解析字符串成Date
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = dateFormat.parse(dateStr);
// 使用目標時區格式化Date
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+9:00"));
System.out.println(dateFormat.format(date1));
// 輸出
2019-12-10 09:00:00