java年份换算_java中日期的换算处理
JAVA8中的日期API是JSR-310的實現,并且是工作在ISO-8601日歷系統基礎上的,但我們也可以在非ISO的日歷上。
JDK8的日期API大致分為以下幾個包:
1 java.time包:JDK8中的基礎包,所有常用的基礎類都是這個包的一部分,如LocalDate,LocalTime,LocalDateTime等等,所有這些類都是不可變且線程安全的;2 java.time.chrono包:這個包為非ISO的日歷系統定義了一些API,我們可以在借助這個包中的一些類擴展我們自己的日歷系統;3 java.time.format包:這個包很明顯了,格式化和解析日期時間對象,一般java.time包中的類都差不多能滿足我們的需求了,如果有需要,可以調用這個包下的類自定義解析方式;4 java.time.temporal包:這個包很有意思,封裝了一些獲取某個特定日期和時間的接口,比如某月的第一天或最后一天,并且這些方法都是屬于特別好認的方法。5 java.time.zone包:這個包就是時區相關的類了。
在JDK1.8中,我們經常使用的大約有如下幾個類:LocalDate, LocalTime, LocalDateTime, DateTimeFormatter等,所以我們主要看一下這幾個類的相關方法。
1. 日期API
1.1 LocalDate
java.time.LocalDate這個類,是用來表示日期的,也僅包含日期,用起來十分方便,方法也十分簡單。我們來看一些小例子:
public static voidtestDate() {//1. 獲取當前日期(年月日) -----打印輸出-----2018-01-29
LocalDate localDate =LocalDate.now();
System.out.println(localDate.toString());//2. 根據年月日構建Date ----打印輸出-----2018-01-30
LocalDate localDate1 = LocalDate.of(2018, 01, 30);//3. 字符串轉換日期,嚴格按照yyyy-MM-dd格式,02寫成2都不行,也可以自定義格式 -----打印輸出-----2018-01-30。無效日期無法通過:DateTimeParseException: Invalid date
LocalDate localDate2 = LocalDate.parse("2018-01-30");//4. 獲取本月第一天 -----打印輸出-----2018-01-01
LocalDate firstDayOfMonth =localDate.with(TemporalAdjusters.firstDayOfMonth());//5. 獲取本月第二天 -----打印輸出-----2018-01-02
LocalDate secondDayOfMonth = localDate.withDayOfMonth(2);//6. 獲取本月最后一天,再也不用計算是28,29,30還是31-----打印輸出-----2018-01-31
LocalDate lastDayOfMonth =localDate.with(TemporalAdjusters.lastDayOfMonth());//7. 明天 -----打印輸出----- 2018-01-30
LocalDate tomorrowDay = localDate.plusDays(1L);//8. 昨天 -----打印輸出----- 2018-01-28
LocalDate yesterday = localDate.minusDays(1L);//9. 獲取本年第120天 -----打印輸出----- 2018-04-30
LocalDate day = localDate.withDayOfYear(120);//10. 計算兩個日期間的天數
long days =localDate.until(localDate1, ChronoUnit.DAYS);
System.out.println(days);//11. 計算兩個日期間的周數
long weeks =localDate.until(localDate1, ChronoUnit.WEEKS);
System.out.println(weeks);//12. 取2015年1月第一個周一,這個計算用Calendar要死掉很多腦細胞:
LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); //2015-01-05
}
1.2 LocalTime
同樣,和LocalDate相對應的另一個類就是LocalTime,這個類恰好和LocalDate相反,它表示的全是時間,不包含日期。例子如下:
public static voidtestTime() {//1. 獲取當前時間,包含毫秒數 -----打印輸出----- 21:03:26.315
LocalTime localTime =LocalTime.now();//2. 你可能想清除毫秒數:
LocalTime now = LocalTime.now().withNano(0)); //11:09:09//3. 構建時間 -----打印輸出----- 12:15:30
LocalTime localTime1 = LocalTime.of(12, 15, 30);//4. 獲取當前時間,不包含毫秒數 -----打印輸出----- 21:01:56
LocalTime localTime2 = localTime.withNano(0);//5. 字符串轉為時間,還可以有其他格式,比如12:15, 12:15:23.233//-----打印輸出----- 12:15:30
LocalTime localTime3 = LocalTime.parse("12:15:30");
}
1.3 LocalDateTime
LocalDateTime就和原先的java.util.Date很像了,既包含日期,又包含時間,它經常和DateTimeFormatter一起使用。
public static voidtestDateTime() {//1. 獲取當前年月日 時分秒 -----打印輸出----- 2018-01-29T21:23:26.774
LocalDateTime localDateTime =LocalDateTime.now();//2. 通過LocalDate和LocalTime構建 ----- 打印輸出----- 2018-01-29T21:24:41.738
LocalDateTime localDateTime1 =LocalDateTime.of(LocalDate.now(), LocalTime.now());//3. 構建年月日 時分秒 -----打印輸出----- 2018-01-29T19:23:13
LocalDateTime localDateTime2 = LocalDateTime.of(2018, 01, 29, 19, 23, 13);//4. 格式化當前時間 ----打印輸出----- 2018/01/29
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(formatter.format(localDateTime2));
}
使用LocalDateTime的with開頭的方法可以設置相應的時間,小時,分鐘等,比如:
//設置分鐘數
LocalDateTime localDateTime = LocalDateTime.now().withMinute(23);
需要注意的有兩點:
1 LocalDateTime默認的格式是 2018-01-29T21:23:26.774 這種格式,這可能與我們經常使用的格式不太符合,所以我們可以指定格式。2 DateTimeFormatter本身提供了許多靜態格式化常量,我們可以參考使用,如果不能滿足我們的需求的話,我們可以自定義;
1.4 TemporalAdjusters
該類是一個計算用的類,提供了各種各樣的計算方法。比如某個月的第一天,某個月的最后一天,某一年的第一天,某一年的第幾天等各種計算方法。該類內部實現基本上全都是通過JDK8的Lambda表達式來實現的。隨便舉一些例子,都很簡單。
LocalDate localDate =LocalDate.now();//1. 本月第一天
LocalDate firstDayOfMonth =localDate.with(TemporalAdjusters.firstDayOfMonth());//2. 本月最后一天
LocalDate lastDayOfMonth =localDate.with(TemporalAdjusters.lastDayOfMonth());//3. 本年第一天
LocalDate firstDayOfYear =localDate.with(TemporalAdjusters.firstDayOfYear());//4. 下個月第一天
LocalDate firstDayOfNextMonth =localDate.with(TemporalAdjusters.firstDayOfNextMonth());//5. 本年度最后一天
LocalDate lastDayOfYear =localDate.with(TemporalAdjusters.lastDayOfYear());
System.out.println(firstDayOfMonth);
System.out.println(lastDayOfMonth);
System.out.println(firstDayOfYear);
System.out.println(firstDayOfNextMonth);
System.out.println(lastDayOfYear);
打印輸出:
2018-01-01
2018-01-31
2018-01-01
2018-02-01
2018-12-31
1.5 Period和Duration
Period是基于ISO-8601標準的日期系統,用于計算兩個日期間的年,月,日的差值。比如'2年,3個月,4天';而Duration和Period很像,但Duration計算的是兩個日期間的秒,納秒的值,是一種更為精確的計算方式;而ISO-8601系統是當今世界大部分地區采用的現代日歷的陽歷系統。
LocalDate localDate =LocalDate.now();
LocalDate localDate1= LocalDate.of(2018, 3, 28);
Period period=Period.between(localDate, localDate1);
System.out.println(period.getDays());
System.out.println(period.getMonths());
當然如果我們看一下Period的between方法實現,就知道底層是通過LocalDate.until方法來實現的。同樣,Period的between方法也就等同于LocalDate.until方法。
但這里有一個問題,就是Period的getDays方法返回的不是兩個日期間總的天數,有點像月計算后剩余的天數,但也不完全是,所以不太清楚這個類實際的意義。看個例子:
LocalDate localDate1 = LocalDate.of(2018, 01, 30);
LocalDate localDate2= LocalDate.of(2018, 03, 01);
Period period=Period.between(localDate1, localDate2);
System.out.println(period.getDays());
打印:1
我們把第一行代碼換一下值,再看一下:
LocalDate localDate1 = LocalDate.of(2018, 01, 29);
結果還是打印1。再換:
LocalDate localDate1 = LocalDate.of(2018, 01, 28);
LocalDate localDate1= LocalDate.of(2018, 01, 27);
上面兩個分別打印1,2。
所以說,在沒搞清楚上面的方法之前,還是不要貿然使用,而如果要計算兩個日期間的總的天數,可以用如下方法來計算:
System.out.println(localDate1.until(localDate2, ChronoUnit.DAYS));
System.out.println(ChronoUnit.DAYS.between(localDate1, localDate2));
而對于Duration來說,就更簡單了,計算兩個時間之間的秒數,納秒數:
LocalTime localTime1 = LocalTime.of(12, 12, 12);
LocalTime localTime2= LocalTime.of(12, 13, 27);
Duration duration=Duration.between(localTime1, localTime2);
System.out.println(duration.getSeconds());//75
但有一點需要注意,Duration中必須要支持秒數,如果沒有的話,將會報錯,如:
LocalDate localDate1 = LocalDate.of(2018, 02, 28);
LocalDate localDate2= LocalDate.of(2018, 02, 27);
Duration duration=Duration.between(localDate1, localDate2);
System.out.println(duration.getSeconds());
將會直接提示:
Exception in thread "main"java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds
at java.time.LocalDate.until(LocalDate.java:1614)
at java.time.Duration.between(Duration.java:475)
at com.jdk8.DateTest.testPeriod(DateTest.java:40)
at com.jdk8.DateTest.main(DateTest.java:23)
1.6 ChronoUnit
這個是個枚舉類型,實現功能類型Period和Duration,但如果我們看它的底層實現,就可以看到它基本是基于Duration來實現的。這個枚舉很簡單,我們直接看一些例子就可以了:
LocalDateTime oldDate = LocalDateTime.of(2017, Month.AUGUST, 31, 10, 20, 55);
LocalDateTime newDate= LocalDateTime.of(2018, Month.NOVEMBER, 9, 10, 21, 56);
System.out.println(oldDate);
System.out.println(newDate);//count between dates
long years =ChronoUnit.YEARS.between(oldDate, newDate);long months =ChronoUnit.MONTHS.between(oldDate, newDate);long weeks =ChronoUnit.WEEKS.between(oldDate, newDate);long days =ChronoUnit.DAYS.between(oldDate, newDate);long hours =ChronoUnit.HOURS.between(oldDate, newDate);long minutes =ChronoUnit.MINUTES.between(oldDate, newDate);long seconds =ChronoUnit.SECONDS.between(oldDate, newDate);long milis =ChronoUnit.MILLIS.between(oldDate, newDate);long nano =ChronoUnit.NANOS.between(oldDate, newDate);
System.out.println("\n--- Total --- ");
System.out.println(years+ " years");
System.out.println(months+ " months");
System.out.println(weeks+ " weeks");
System.out.println(days+ " days");
System.out.println(hours+ " hours");
System.out.println(minutes+ " minutes");
System.out.println(seconds+ " seconds");
System.out.println(milis+ " milis");
System.out.println(nano+ " nano");
打印結果:
2017-08-31T10:20:55
2018-11-09T10:21:56
--- Total ---
1years14months62weeks435days10440hours626401minutes37584061seconds37584061000milis37584061000000000 nano
1.7 Clock
時鐘系統,用于查找當前時刻。通過指定一個時區,我們可以獲取到當前的時刻,日期,時間。所以可以使用一個時鐘來代替System.currenttimemillis() 和 TimeZone.getDefault()。
在應用程序的最佳實踐是將時鐘傳遞給任何需要當前即刻的方法:
public classMyBean {private Clock clock; //dependency inject
...public voidprocess(LocalDate eventDate) {if(eventDate.isBefore(LocalDate.now(clock)) {
...
}
}
}
我們可以簡單測試一下:
//系統默認
Clock systemDefaultClock =Clock.systemDefaultZone();
System.out.println("Current DateTime with system default clock: " +LocalDateTime.now(systemDefaultClock));
System.out.println(systemDefaultClock.millis());//世界協調時UTC
Clock systemUTCClock =Clock.systemUTC();
System.out.println("Current DateTime with UTC clock: " +LocalDateTime.now(systemUTCClock));
System.out.println(systemUTCClock.millis());//芝加哥
Clock clock = Clock.system(ZoneId.of(ZoneId.SHORT_IDS.get("CST")));
System.out.println("Current DateTime with CST clock: " +LocalDateTime.now(clock));
System.out.println(clock.millis());
打印:
Current DateTime with system default clock: 2018-02-02T16:26:07.665
1517559967665Current DateTime with UTC clock:2018-02-02T08:26:07.665
1517559967665Current DateTime with CST clock:2018-02-02T02:26:07.667
1517559967667
并且我們可以使用 millis 方法來代替 System.currenttimemillis()。
更多有關Clock方法實例可以參考下面鏈接(沒找到JDK8的,不過可以參考JDK9的):
https://www.concretepage.com/java/java-9/java-clock
1.8 其他
其中還有一些類沒有詳細說明,比如:
1 Instant,表示的是時間戳,用于記錄某一時刻的更改(JDK8之前的Timestamp);2 ZoneId 時區標志,比如用于標志歐洲/巴黎;3 ZoneOffset 時區偏移量,與UTC的偏移量;4 ZonedDateTime 與時區有關的日歷系統,比如2007-12 03t10:15:30+01歐洲/巴黎;5 OffsetDateTime 用于與UTC偏移的日期時間,如如2007-12 03t10:15:30+01:00。
2. 轉換
2.1 java.util.Date與LocalDate,LocalTime,LocalDateTime替換
將Date轉換為LocalDate,LocalTime,LocalDateTime可以借助于ZonedDateTime和Instant,實現如下:
Date date = newDate();
System.out.println("current date: " +date);//Date -> LocalDateTime
LocalDateTime localDateTime =date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println("localDateTime by Instant: " +localDateTime);//Date -> LocalDate
LocalDate localDate =date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println("localDate by Instant: " +localDate);//Date -> LocalTime
LocalTime localTime =date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
System.out.println("localTime by Instant: " +localTime);//2. Date -> LocalDateTime
localDateTime =LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
System.out.println("localDateTime by ofInstant: " + localDateTime);
output:
current date: Fri Feb 02 16:43:13 CST 2018localDateTime by Instant:2018-02-02T16:43:13.073localDateTime by ofInstant:2018-02-02T16:43:13.073localDate by Instant:2018-02-02localTime by Instant:16:43:13.073
由于JDK8實現了向下兼容,所以Date里在JDK8版本引入了2個方法,from 和
toInstant,所以我們可以借助這兩個方法來實現LocalDateTime到Date的轉換。將LocalDateTime轉為Date如下:
LocalDateTime localDateTime =LocalDateTime.now();
System.out.println("localDateTime: " +localDateTime);//LocalDateTime -> Date
Date date =Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDateTime -> current date: " +date);//LocalDate -> Date,時間默認都是00
LocalDate localDate =LocalDate.now();
date=Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDate -> current date: " + date);
output:
localDateTime: 2018-02-02T16:55:52.464LocalDateTime-> current date: Fri Feb 02 16:55:52 CST 2018LocalDate-> current date: Fri Feb 02 00:00:00 CST 2018
而單獨的LocalTime轉為Date沒什么意義,所以如果LocalTime要轉為Date,一般借助于LocalDate和LocalDateTime來實現就可以了。
2.2 日期與字符串的轉換
日期與字符串的轉換比較簡單。先說轉換成日期格式,通過LocalDate,LocalTime,LocalDateTime的parse方法和DateTimeFormatter來實現:
LocalDate localDate = LocalDate.parse("2018-09-09", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime localDateTime= LocalDateTime.parse("2018-09-10 12:12:12", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss:mm"));
而將日期轉為字符串,可以通過format方法和DateTimeFormatter來實現:
String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String localDateTime= LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss:mm"));
總結
1 java.time包下其實還有一些其他的類與方法,如查詢是否是閏年,日期比較,獲取某一年的某一天等等,我們可以等用到的時候再去查看不遲。并且我們可以將我們常用的方法封裝成util包供我們在使用的時候直接調用。2 JDK8提供的這套API接口基本上封裝了我們平時常用的所有與日期時間的相關操作,所以如果升級了JDK8,在處理日期和時間的時候盡量多用新的API。3 JDK8中新的日期不但命名優雅,通俗易懂,而且提供了向下兼容的能力,可以無縫連接。4 如果用到了Period,注意它的getDays方法。
總結
以上是生活随笔為你收集整理的java年份换算_java中日期的换算处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: uboot下nand flash读写方法
- 下一篇: elementui分页组件按钮样式修改_