1. 程式人生 > >JavaSE(七)處理日期和時間

JavaSE(七)處理日期和時間

處理日期和時間

概念

日期、時間和時刻
時區TimeZone:

GMT+08:00
UTC+08:00
CST:China Standard Time / Central Standard Time USA
Asia/Shanghai

夏令時,同一地區用GMT/UTC和城市表示的時區可能導致時間不同
Locale用來針對當地使用者習慣格式化日期、時間、數字、貨幣等

Date和Calendar

Date

Epoch Time:從1970-01-01 00:00:00 GMT+0:00開始到現在的秒數
JDK有新舊兩套API處理日期和時間

java.util java.time(JDK >= 1.8)
Date、Calendar LocalDate、LocalTime、ZonedDateTime、Instant

java.util.Date表示日期和時間,內部使用long表示epoch毫秒數
java.util.Date轉化為String:

1)toString()
2)toGMTString()
3)toLocaleString()
4)SimpleDateFormat()

SimpleDateFormat:用於Date和String的解析和格式化

Calendar

Calendar和Date、long可以互相轉換
Calendar可以用set、get設定和獲取指定欄位
Calendar可以實現

1)設定特定的日期和時間
2)設定時區並獲得轉換後的時間
3)加減日期和時間

TimeZone表示時區,getAvailableIDs()可以列舉所有有效的時區ID

java.time的API

LocalDateTime

java.time提供了新的API

1)LocalDate
2)LocalTime
3)LocalDateTime
4)ZonedDateTime
5)ZoneId
6)Instant
7)Formatter

新API特點

1)嚴格區分日期和時間
2)不變類
3)修復了Month和Week的常量值
	Month範圍1~12(Jan~Dec)
	Week範圍1~7(Mon~Sun)

LocalDate:日期
LocalTime:時間
LocalDateTime:日期+時間
DateTimeFormatter:格式化日期和時間
預設按ISO 8601解析和格式化
可以對日期和時間進行加減、調整、判斷先後,計算Period
對日期進行加減

// 加減
plusDays()
minusHours()
plusWeeks()
...
// 調整
withDayOfMonth()
withMonth()
withHour()
...
with()
// 判斷時間先後
isBefore()
isAfter()
equals()
// 計算日期的Period
getYears()
getMonths()
getDays()

LocalDateTime沒有時區資訊,無法與long進行轉換

ZonedDateTime

ZonedDateTime = LocalDateTime + ZoneId
ZonedDateTime可以做時區轉換:withZoneSameInstant
ZoneId:新的時區物件
Instant:時刻,可以轉換為long(單位秒)
ZonedDateTime、Instant和long可以互相轉換

ZonedDateTime.toInstant()
Instant.getEpochSecond()

在這裡插入圖片描述
在這裡插入圖片描述
Period和Duration表示一段時間,可以用於日期和時間加減
其他底層API:

ZoneOffset:時區偏移量
OffsetDateTime:類似ZonedDateTime
OffsetTime:帶Offset的LocalTime
ChronoLocalDate:用於實現其他曆法
ChronoLocalDateTime

最佳實踐

Java處理日期和時間

1)java.util.Date同時表示日期和時間
2)java.sql.Date僅表示日期
3)java.sql.Time僅表示時間
4)java.sql.Timestamp表示資料庫的TIMESTAMP型別

理解資料庫型別到Java型別的對映

資料庫 對應Java類(舊) 對應Java類(新)
DATETIME java.utilDate LocalDateTime
DATE java.sql.Date LocalDate
TIME java.sql.Time LocalTime
TIMESTAMP java.sql.Timestamp LocalDateTime

新舊API的轉換:通過long作為中介
在這裡插入圖片描述
新舊API時區轉換
在這裡插入圖片描述
儲存時刻最好使用long型別,可以編寫格式化方法把long轉換為使用者本地時間

時間各種轉換

將LocalDateTime轉為自定義的時間格式的字串

public static String getDateTimeAsString(LocalDateTime localDateTime, String format) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    return localDateTime.format(formatter);
}

將long型別的timestamp轉為LocalDateTime

public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
    Instant instant = Instant.ofEpochMilli(timestamp);
    ZoneId zone = ZoneId.systemDefault();
    return LocalDateTime.ofInstant(instant, zone);
}

將LocalDateTime轉為long型別的timestamp

public static long getTimestampOfDateTime(LocalDateTime localDateTime) {
    ZoneId zone = ZoneId.systemDefault();
    Instant instant = localDateTime.atZone(zone).toInstant();
    return instant.toEpochMilli();
}

將某時間字串轉為自定義時間格式的LocalDateTime

public static LocalDateTime parseStringToDateTime(String time, String format) {
    DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
    return LocalDateTime.parse(time, df);
}

練習

通過System.currentMillis()可以獲取當前的Epoch Time,以long型別表示,請編寫一個方法,根據使用者輸入的時區,以yyyy-MM-dd HH:mm:ss的格式打印出本地日期和時間

public class WorldClock {
	public static String getCurrentDateTime(String zoneId){
		ZoneId zone = ZoneId.of(zoneId);
		long currentTime = System.currentTimeMillis();
		Instant instant = Instant.ofEpochMilli(currentTime);
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		return localDateTime.format(formatter);
	}
}