Date
Date date = new Date(); //獲取當前時間? ? ? ??
System.out.println(date.getYear() + 1900); // 必須加上1900 ? ? ? ? System.out.println(date.getMonth() + 1); // 0~11,必須加上1 ? ? ? ? System.out.println(date.getDate()); // 1~31,不能加1
Calendar
可以用于獲取并設置年、月、日、時、分、秒,它和Date比,主要多了一個可以做簡單的日期和時間運算的功能。
?// 獲取當前時間: ? ? ? ?
Calendar c = Calendar.getInstance(); ? ? ? ?
int y = c.get(Calendar.YEAR); ? ? ? ? i
nt m = 1 + c.get(Calendar.MONTH); ? ? ?
int d = c.get(Calendar.DAY_OF_MONTH);? ? ? ? ?
int w = c.get(Calendar.DAY_OF_WEEK); ? ? ? ?
int hh = c.get(Calendar.HOUR_OF_DAY); ? ? ? ?
int mm = c.get(Calendar.MINUTE); ? ? ? ?
int ss = c.get(Calendar.SECOND); ? ? ? ?
int ms = c.get(Calendar.MILLISECOND); ? ? ? ?
System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);
TimeZone
Calendar和Date相比,它提供了時區轉換的功能。
? TimeZone tzDefault = TimeZone.getDefault(); // 當前時區? ? ? ?
?TimeZone tzGMT9 = TimeZone.getTimeZone("GMT+09:00"); // GMT+9:00時區 ? ? ? ?
TimeZone tzNY = TimeZone.getTimeZone("America/New_York"); // 紐約時區 ? ? ? ? System.out.println(tzDefault.getID()); // Asia/Shanghai
時區的唯一標識是以字符串表示的ID,我們獲取指定TimeZone對象也是以這個ID為參數獲取,GMT+09:00、Asia/Shanghai都是有效的時區ID。要列出系統支持的所有ID,請使用TimeZone.getAvailableIDs()。
LocalDateTime
是java8,java.time提供新的API
?LocalDate d = LocalDate.now(); // 當前日期 ? ? ? ?
LocalTime t = LocalTime.now(); // 當前時間 ? ? ? ?
LocalDateTime dt = LocalDateTime.now(); // 當前日期和時間
提供了對日期和時間進行加減的非常簡單的鏈式調用
?LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59); ? ? ? ?
System.out.println(dt); ? ? ? ?
// 加5天減3小時: ? ? ? ?
LocalDateTime dt2 = dt.plusDays(5).minusHours(3); ? ? ? ?
System.out.println(dt2); // 2019-10-31T17:30:59 ? ? ? ?
// 減1月: ? ? ? ?
LocalDateTime dt3 = dt2.minusMonths(1); ? ? ? ?
System.out.println(dt3); // 2019-09-30T17:30:59
對時間和日期進行調整
?LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59); ? ? ? ?
System.out.println(dt); ? ? ? ?
// 日期變為31日: ? ? ? ?
LocalDateTime dt2 = dt.withDayOfMonth(31); ? ? ? ?
System.out.println(dt2);
// 2019-10-31T20:30:59 ? ? ? ?
// 月份變為9: ? ? ? ?
LocalDateTime dt3 = dt2.withMonth(9); ? ? ? ?
System.out.println(dt3); // 2019-09-30T20:30:59
LocalDateTime還有一個通用的with()方法允許我們做更復雜的運算
?// 本月第一天0:00時刻: ? ? ? ?
LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay(); ? ? ? ? System.out.println(firstDay); ? ? ? ?
// 本月最后1天: ? ? ? ?
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()); ? ? ? ? System.out.println(lastDay); ? ? ? ?
// 下月第1天: ? ? ? ?
LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()); ? ? ? ? System.out.println(nextMonthFirstDay); ? ? ? ?
// 本月第1個周一: ? ? ? ?
LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); ?System.out.println(firstWeekday);
要判斷兩個LocalDateTime的先后,可以使用isBefore()、isAfter()方法,對于LocalDate和LocalTime
? LocalDateTime now = LocalDateTime.now(); ? ? ? ?
LocalDateTime target = LocalDateTime.of(2019, 11, 19, 8, 15, 0); ? ? ? ? System.out.println(now.isBefore(target)); ? ? ? ? System.out.println(LocalDate.now().isBefore(LocalDate.of(2019, 11, 19))); ? ? ? ? System.out.println(LocalTime.now().isAfter(LocalTime.parse("08:15:00")));
DateTimeFormatter
如果要自定義輸出的格式,或者要把一個非ISO 8601格式的字符串解析成LocalDateTime
? // 自定義格式化: ? ? ? ?
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); ? ? ? ? System.out.println(dtf.format(LocalDateTime.now())); ? ? ? ?
// 用自定義格式解析: ? ? ? ?
LocalDateTime dt2 = LocalDateTime.parse("2019/11/30 15:16:17", dtf); ? ? ? ? System.out.println(dt2);
Duration
表示兩個時刻得時間間隔
? LocalDateTime start = LocalDateTime.of(2019, 11, 19, 8, 15, 0); ? ? ? ?
LocalDateTime end = LocalDateTime.of(2020, 1, 9, 19, 25, 30); ? ? ? ?
Duration d = Duration.between(start, end); ? ? ? ?
System.out.println(d); // PT1235H10M30S
Period
表示兩個日期間隔的天數
Period p = LocalDate.of(2019, 11, 19).until(LocalDate.of(2020, 1, 9)); ? ? ? ?
System.out.println(p); // P1M21D
ZonedDateTime
和LocalDateTime相比,增加了時區,可以理解為LocalDateTime+ZonedId
? ZonedDateTime zbj = ZonedDateTime.now(); // 默認時區 ? ? ? ?
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); // 用指定時區獲取當前時間
另一種方式是通過給一個LocalDateTime附加一個ZoneId,就可以變成ZonedDateTime
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17); ? ? ? ? ZonedDateTime zbj = ldt.atZone(ZoneId.systemDefault()); ? ? ? ?
ZonedDateTime zny = ldt.atZone(ZoneId.of("America/New_York"));
要轉換時區,首先我們需要有一個ZonedDateTime對象,然后,通過withZoneSameInstant()將關聯時區轉換到另一個時區,轉換后日期和時間都會相應調整。
?// 以中國時區獲取當前時間: ? ? ? ?
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); ? ? ? ?
// 轉換為紐約時間: ? ? ? ?
ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("America/New_York"));
DateTimeFormatter
使用舊的Date對象時,我們用SimpleDateFormat進行格式化顯示。使用新的LocalDateTime或ZonedDateTime時,我們要進行格式化顯示,就要使用DateTimeFormatter。
和SimpleDateFormat不同的是,DateTimeFormatter不但是不變對象,它還是線程安全的。因為SimpleDateFormat不是線程安全的,使用的時候,只能在方法內部創建新的局部變量。而DateTimeFormatter可以只創建一個實例,到處引用。
創建DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
另一種是加入時區
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.US);
?ZonedDateTime zdt = ZonedDateTime.now(); ? ? ? ?
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm ZZZZ"); ? ? ? ? System.out.println(formatter.format(zdt)); ? ? ? ?
var zhFormatter = DateTimeFormatter.ofPattern("yyyy MMM dd EE HH:mm", Locale.CHINA); ? ? ? ? System.out.println(zhFormatter.format(zdt)); ? ? ? ?
var usFormatter = DateTimeFormatter.ofPattern("E, MMMM/dd/yyyy HH:mm", Locale.US); ? ? ? ? System.out.println(usFormatter.format(zdt));
輸出結果為
2019-09-15T23:16 GMT+08:00
2019 9月 15 周日 23:16 Sun
September/15/2019 23:16