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);
}
}