下面將依次介紹
- Date轉Java8時間類操作 ,Java8時間類LocalDate常用操作(如獲得當前日期,兩個日期相差多少天,下個星期的日期,下個月第一天等)
- 解析不同時間字符串成對應的Java8中的類,如Instant、LocalDateTime、ZonedDateTime
- 時區ZoneId的使用場景、方式(根據ZoneId可將普通日期時間轉化帶有時區的日期時間,如2018-12-07T09:33:38Z,2018-10-08T18:12:38.547+08:00[Asia/Shanghai])。
java.time包中的是類是不可變且線程安全的。
新的時間及日期API位於java.time中,下面是一些關鍵類
●Instant——它代表的是時間戳,注意這里默認的Instant是0時區,比北京少8個時區,例子:2018-10-08T09:50:21.852Z,相當於當天北京時間的17:50:21.852
●LocalDate——不包含具體時間的日期,比如2014-01-14。它可以用來存儲生日,周年紀念日,入職日期等。
●LocalTime——它代表的是不含日期的時間
●LocalDateTime——它包含了日期及時間,不過還是沒有偏移信息或者說時區。
●ZonedDateTime——這是一個包含時區的完整的日期時間,偏移量是以UTC/格林威治時間為基准的,如:2018-10-08T18:12:38.547+08:00[Asia/Shanghai]。
一個例子:給出一個時間段,計算該時間范圍由哪些日期(天)和月份組成。
一 、先主要是Java8中LocalDate日期的操作
1. Date轉LocalDate、LocalDateTime
Date轉化為Instant時間戳,然后instant和系統默認時區轉化成LocalDate
/** * Date轉LocalDate: Date -> Instant + System default time zone = LocalDate */ @Test public void dateToLocalDateAndLocalDateTime(){ Date date = new Date(); Instant instant = date.toInstant(); /** * instant : 2018-10-08T09:50:21.852Z * Zone : UTC+0 * 注意這里默認的Instant是比北京少8個時區 */
//獲得本地默認時區
ZoneId defaultZoneId = ZoneId.systemDefault(); LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate(); System.out.println(localDate);
//2018-10-08 }
Date轉化成本地系統時區的LocalDateTime
@Test public void dateToLocalDateTime(){ Date date = new Date(); Instant instant = date.toInstant(); //系統默認的時區 ZoneId zoneId = ZoneId.systemDefault(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId); System.out.println(localDateTime); }
2. 13位long類型轉LocalDate
long -> Instant +System default time zone = LocalDate
public LocalDate longToLocalDate(Long time){ //System Default TimeZone : Asia/Shanghai
ZoneId defaultZoneId = ZoneId.systemDefault(); //2018-01-04T16:00:00Z //時間戳
Instant instant = Instant.ofEpochMilli(time); //2018-01-05
LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate(); return localDate; }
3. 獲取現在的日期
Java8中有個叫LocalDate的類,能用來表示日期。這個類與java.util.Date略有不同,因為它只包含日期,沒有時間。
4. 獲取年月日
5. 判斷兩個日期之間相差多少天
/** * 判斷兩個日期相差多少天 */ @Test public void localDateDiff(){ LocalDate date1 = LocalDate.of(2018,9,20); LocalDate date2 = LocalDate.of(2018,10,3); long l = date2.toEpochDay() - date1.toEpochDay(); System.out.println(l); }
6. 獲得某個日期所在月的第一天、最后一天
/** * 獲得某個日期所在月的第一天、最后一天 */ @Test public void firstLastDay(){ LocalDate localDate = LocalDate.of(2018, 2, 22); LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth()); LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth()); System.out.println("firstDay: "+firstDay+" lastDay: "+lastDay); //firstDay: 2018-02-01 lastDay: 2018-02-28
}
7. 某個月有多少天
先獲取該月的最后一天的LocalDate,再調用getDayOfMonth()方法
/** * 某個月有多少天 */ @Test public void getDayOfMonth(){ LocalDate localDate = LocalDate.of(2018, 2, 22); LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth()); int dayOfMonth = lastDay.getDayOfMonth(); System.out.println(dayOfMonth); //28
}
8. 比較兩個LocalDate的大小
/** * 比較兩個LocalDate的大小 */ @Test public void localDateCompareTo(){ LocalDate date1 = LocalDate.of(2018,9,20); LocalDate date2 = LocalDate.of(2018,10,3); int i = date1.compareTo(date2); System.out.println(i); //-1 小
int i1 = date2.compareTo(date1); System.out.println(i1); //1 大
int i2 = date1.compareTo(date1); System.out.println(i2); //0 等於
}
9. 獲取下一周的該星期、下個月的這天、下個月的1號
/** * 獲取下一周的該星期、下個月的這天、下個月的1號 */ @Test public void nextMonth(){ LocalDate localDate = LocalDate.of(2018, 2, 12); //下一周的該星期
LocalDate localDate1 = localDate.minusWeeks(-1); System.out.println(localDate1); //2018-02-19 //獲取下個月的這天
LocalDate localDate2 = localDate.minusMonths(-1); System.out.println(localDate2); //2018-03-12 //下個月的1號
LocalDate localDate3 = LocalDate.of(localDate.getYear(), localDate.getMonthValue()+1, 1); System.out.println(localDate3); //2018-03-01
}
10. 比較兩個LocalDate相差多少年、月、天
Period這個類,這里比較的是兩個日期,相差多少年、多少個月、多少天;
比如下面的這個例子中,2018.10.9 比 2019.4.1相差 0年 5個月 23天
/** * 比較兩個LocalDate相差多少年、月、日 */ @Test public void localDatePeriod(){ LocalDate date1 = LocalDate.of(2018,10,9); LocalDate date2 = LocalDate.of(2019,4,1); Period period = Period.between(date1, date2); int years = period.getYears(); int months = period.getMonths(); int days = period.getDays(); System.out.println("years:"+years+", months:"+months+", days:"+days); //years:0, months:5, days:23
}
11. 通過10位或13位時間戳構建Instant
ofEpochSecond()參數是10位時間戳,精確到秒;
ofEpochMilli()參數是13位時間戳,精確到毫秒。
@Test public void ofEpochSecond(){ Instant now = Instant.now(); System.out.println(now); //2019-03-13T06:41:32.865Z //去除毫秒 long l = now.toEpochMilli() / 1000; //通過秒構建Instant對象 Instant instant = Instant.ofEpochSecond(l); System.out.println(instant); //2019-03-13T06:41:32Z }
二、 將特殊格式的字符串解析成對應的時間類
由下面例子總結:
Instant只能解析"**T**Z”這種格式的時間,即UTC字符串;
ZonedDateTime解析的時間字符串必須是要有年月日時分秒以及時區;
LocalDateTime解析的時間字符串必須要有年月日時分秒,但是不能有時區,例如末尾有"Z"的時間表示UTC的0時區就不能解析;
LocalDate解析的時間字符串必須只能有年月日,格式如"2018-12-07",多任何其他字符都不能解析。
1.格式:2018-12-07T09:33:38+00:00
/** * 解析字符串:2018-12-07T09:33:38+00:00 * ZonedDateTime必須解析有時區的時間 */ @Test public void stringToZonedDateTime(){ final String string ="2018-12-07T09:33:38+00:00"; ZonedDateTime parse = ZonedDateTime.parse(string); System.out.println(parse.toString()); //結果是2018-12-07T09:33:38Z ZoneId zone = parse.getZone(); System.out.println(zone); }
2.2018-12-07T09:33:38Z
/** * 解析字符串:2018-12-07T09:33:38Z,無法解析2018-12-07T09:33:38+00:00 * Instant只能解析"**T**Z”這種格式的時間 */ @Test public void stringToInstant(){ final String string ="2018-12-07T09:33:38Z"; Instant parse = Instant.parse(string); System.out.println(parse); //2018-12-07T09:33:38Z }
/** * 解析字符串:2018-12-07T09:33:38Z * 表示的是0時區的時間 */ @Test public void stringToZonedDateTime1(){ final String string ="2018-12-07T09:33:38Z"; ZonedDateTime parse = ZonedDateTime.parse(string); System.out.println(parse.toString()); //結果是2018-12-07T09:33:38Z ZoneId zone = parse.getZone(); System.out.println(zone); }
3.2018-12-07T09:33:38,末尾無Z,沒有時區
/** * 解析字符串:2018-12-07T09:33:38,末尾不能有Z,有T有Z代表了UTC 0時區的時間,還必須要有"T時分秒"這一截字符串 * LocaDateTime無法解析帶有時區的字符串時間 */ @Test public void stringToLocalDateTime(){ final String string ="2018-12-07T09:33:38"; LocalDateTime parse = LocalDateTime.parse(string); System.out.println(parse.toString()); //結果是2018-12-07T09:33:38 }
4.2018-12-07
/** * 解析字符串:2018-12-07,只能解析該格式字符串 * LocaDate無法解析帶有時區的字符串時間 */ @Test public void stringToLocalDate(){ final String string ="2018-12-07"; LocalDate parse = LocalDate.parse(string); System.out.println(parse.toString()); //結果是2018-12-07 }
三、 時區ZoneID相關操作
ZoneID.of(String zoneId) 時區參數
這里的zoneId字符串可以傳入"Asia/Shanghai",字符串如下:
- EST - -05:00
- HST - -10:00
- MST - -07:00
- ACT - Australia/Darwin
- AET - Australia/Sydney
- AGT - America/Argentina/Buenos_Aires
- ART - Africa/Cairo
- AST - America/Anchorage
- BET - America/Sao_Paulo
- BST - Asia/Dhaka
- CAT - Africa/Harare
- CNT - America/St_Johns
- CST - America/Chicago
- CTT - Asia/Shanghai
- EAT - Africa/Addis_Ababa
- ECT - Europe/Paris
- IET - America/Indiana/Indianapolis
- IST - Asia/Kolkata
- JST - Asia/Tokyo
- MIT - Pacific/Apia
- NET - Asia/Yerevan
- NST - Pacific/Auckland
- PLT - Asia/Karachi
- PNT - America/Phoenix
- PRT - America/Puerto_Rico
- PST - America/Los_Angeles
- SST - Pacific/Guadalcanal
- VST - Asia/Ho_Chi_Minh
將不帶時區LocalDateTime轉化為帶時區的ZonedDateTime
/** * 把無時區的時間LocaDateTime解析成有時區的ZonedDateTime */ @Test public void localDateTimeToZonedDateTime(){ final String string ="2018-12-07T09:33:38"; LocalDateTime parse = LocalDateTime.parse(string); ZonedDateTime z1 = ZonedDateTime.of(parse, ZoneId.of("Asia/Shanghai")); System.out.println(z1.toString()); //2018-12-07T09:33:38+08:00[Asia/Shanghai] ZonedDateTime z2 = ZonedDateTime.of(parse, ZoneId.of("Z")); System.out.println(z2.toString()); //2018-12-07T09:33:38Z ZonedDateTime z3 = ZonedDateTime.of(parse, ZoneId.of("UTC")); System.out.println(z3.toString()); //2018-12-07T09:33:38Z[UTC] ZonedDateTime z4 = ZonedDateTime.of(parse, ZoneId.of("UTC+08:00")); System.out.println(z4.toString()); //2018-12-07T09:33:38+08:00[UTC+08:00] ZonedDateTime z5 = ZonedDateTime.of(parse, ZoneId.of("+08:00")); System.out.println(z5.toString()); //2018-12-07T09:33:38+08:00 ZonedDateTime z6 = ZonedDateTime.of(parse, ZoneId.of("+00:00")); System.out.println(z6.toString()); //2018-12-07T09:33:38Z }
由結果可知,String zoneId的字符串值,如果為:
"Asia/Shanghai"例子為"2018-12-07T09:33:38+08:00[Asia/Shanghai]" ;
"Z"和"+00:00"表示的是"2018-12-07T09:33:38Z"這種格式的時間;
"UTC"表示的是"2018-12-07T09:33:38Z[UTC]" ;
"UTC+08:00" 例子:"2018-12-07T09:33:38+08:00[UTC+08:00]" ;
"+08:00" 例子:"2018-12-07T09:33:38+08:00"
部分參考:
https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html
http://www.mkyong.com/java8/java-8-convert-date-to-localdate-and-localdatetime/
https://www.cnblogs.com/comeboo/p/5378922.html