更深入地了解Java 8 Date and Time API
在這篇文章中,我們將更深入地了解通過Java 8獲得的新的Date / Time API(
JSR 310 )。 請注意,本文主要由顯示新API功能的代碼示例驅動。 我認為這些示例是不言自明的,因此我并沒有花太多時間在它們周圍寫文本:-)
讓我們開始吧!
處理日期和時間對象
Java 8 Date / Time API的所有類都位于java.time包內。 我們要看的第一類是java.time.LocalDate。 LocalDate表示沒有時間的年月日日期。 我們從創建新的LocalDate實例開始:
//?the?current?date LocalDate?currentDate?=?LocalDate.now();//?2014-02-10 LocalDate?tenthFeb2014?=?LocalDate.of(2014,?Month.FEBRUARY,?10);//?months?values?start?at?1?(2014-08-01) LocalDate?firstAug2014?=?LocalDate.of(2014,?8,?1);//?the?65th?day?of?2010?(2010-03-06) LocalDate?sixtyFifthDayOf2010?=?LocalDate.ofYearDay(2010,?65);LocalTime和LocalDateTime是我們要研究的下一個類。 兩者的工作都類似于LocalDate。 LocalTime可用于時間(無日期),而LocalDateTime可將日期和時間組合在一個類中:
LocalTime?currentTime?=?LocalTime.now();?//?current?time LocalTime?midday?=?LocalTime.of(12,?0);?//?12:00 LocalTime?afterMidday?=?LocalTime.of(13,?30,?15);?//?13:30:15//?12345th?second?of?day?(03:25:45) LocalTime?fromSecondsOfDay?=?LocalTime.ofSecondOfDay(12345);//?dates?with?times,?e.g.?2014-02-18 19:08:37.950 LocalDateTime?currentDateTime?=?LocalDateTime.now();//?2014-10-02?12:30 LocalDateTime?secondAug2014?=?LocalDateTime.of(2014,?10,?2,?12,?30);//?2014-12-24?12:00 LocalDateTime?christmas2014?=?LocalDateTime.of(2014,?Month.DECEMBER,?24,?12,?0);默認情況下,LocalDate / Time類將使用默認時區中的系統時鐘。 我們可以通過提供時區或其他Clock實現來更改此設置:
//?current?(local)?time?in?Los?Angeles LocalTime?currentTimeInLosAngeles?=?LocalTime.now(ZoneId.of("America/Los_Angeles"));//?current?time?in?UTC?time?zone LocalTime?nowInUtc?=?LocalTime.now(Clock.systemUTC());從LocalDate / Time對象中,我們可以獲得所需的各種有用信息。 一些例子:
LocalDate?date?=?LocalDate.of(2014,?2,?15);?//?2014-02-15boolean?isBefore?=?LocalDate.now().isBefore(date);?//?false//?information?about?the?month Month?february?=?date.getMonth();?//?FEBRUARY int?februaryIntValue?=?february.getValue();?//?2 int?minLength?=?february.minLength();?//?28 int?maxLength?=?february.maxLength();?//?29 Month?firstMonthOfQuarter?=?february.firstMonthOfQuarter();?//?JANUARY//?information?about?the?year int?year?=?date.getYear();?//?2014 int?dayOfYear?=?date.getDayOfYear();?//?46 int?lengthOfYear?=?date.lengthOfYear();?//?365 boolean?isLeapYear?=?date.isLeapYear();?//?falseDayOfWeek?dayOfWeek?=?date.getDayOfWeek(); int?dayOfWeekIntValue?=?dayOfWeek.getValue();?//?6 String?dayOfWeekName?=?dayOfWeek.name();?//?SATURDAYint?dayOfMonth?=?date.getDayOfMonth();?//?15 LocalDateTime?startOfDay?=?date.atStartOfDay();?//?2014-02-15 00:00//?time?information LocalTime?time?=?LocalTime.of(15,?30);?//?15:30:00 int?hour?=?time.getHour();?//?15 int?second?=?time.getSecond();?//?0 int?minute?=?time.getMinute();?//?30 int?secondOfDay?=?time.toSecondOfDay();?//?55800無需提供特定日期即可獲得某些信息。 例如,如果我們需要有關特定年份的信息,則可以使用Year類:
Year?currentYear?=?Year.now(); Year?twoThousand?=?Year.of(2000); boolean?isLeap?=?currentYear.isLeap();?//?false int?length?=?currentYear.length();?//?365//?sixtyFourth?day?of?2014?(2014-03-05) LocalDate?date?=?Year.of(2014).atDay(64);我們可以使用加號和減號方法來添加或減去特定的時間量。 請注意,這些方法總是返回一個新實例(Java 8日期/時間類是不可變的)。
LocalDate?tomorrow?=?LocalDate.now().plusDays(1);//?before?5?houres?and?30?minutes LocalDateTime?dateTime?=?LocalDateTime.now().minusHours(5).minusMinutes(30);TemporalAdjusters是日期處理的另一種不錯的方法。 TemporalAdjuster是一個單一方法接口,用于將調整過程與實際日期/時間對象分開。 可以使用TemporalAdjusters類的靜態方法來訪問一組常見的TemporalAdjusters 。
LocalDate?date?=?LocalDate.of(2014,?Month.FEBRUARY,?25);?//?2014-02-25//?first?day?of?february?2014?(2014-02-01) LocalDate?firstDayOfMonth?=?date.with(TemporalAdjusters.firstDayOfMonth());//?last?day?of?february?2014?(2014-02-28) LocalDate?lastDayOfMonth?=?date.with(TemporalAdjusters.lastDayOfMonth());靜態導入使它更通俗易懂:
import?static?java.time.temporal.TemporalAdjusters.*;...//?last?day?of?2014?(2014-12-31) LocalDate?lastDayOfYear?=?date.with(lastDayOfYear());//?first?day?of?next?month?(2014-03-01) LocalDate?firstDayOfNextMonth?=?date.with(firstDayOfNextMonth());//?next?sunday?(2014-03-02) LocalDate?nextSunday?=?date.with(next(DayOfWeek.SUNDAY));時區
使用時區是新API簡化的另一個重要主題。 到目前為止,我們已經看到的LocalDate / Time類不包含有關時區的信息。 如果我們要使用某個時區中的日期/時間,可以使用ZonedDateTime或OffsetDateTime :
ZoneId?losAngeles?=?ZoneId.of("America/Los_Angeles"); ZoneId?berlin?=?ZoneId.of("Europe/Berlin");//?2014-02-20?12:00 LocalDateTime?dateTime?=?LocalDateTime.of(2014,?02,?20,?12,?0);//?2014-02-20?12:00,?Europe/Berlin?(+01:00) ZonedDateTime?berlinDateTime?=?ZonedDateTime.of(dateTime,?berlin);//?2014-02-20?03:00,?America/Los_Angeles?(-08:00) ZonedDateTime?losAngelesDateTime?=?berlinDateTime.withZoneSameInstant(losAngeles);int?offsetInSeconds?=?losAngelesDateTime.getOffset().getTotalSeconds();?//?-28800//?a?collection?of?all?available?zones Set<String>?allZoneIds?=?ZoneId.getAvailableZoneIds();//?using?offsets LocalDateTime?date?=?LocalDateTime.of(2013,?Month.JULY,?20,?3,?30); ZoneOffset?offset?=?ZoneOffset.of("+05:00");//?2013-07-20 03:30?+05:00 OffsetDateTime?plusFive?=?OffsetDateTime.of(date,?offset);//?2013-07-19?20:30?-02:00 OffsetDateTime?minusTwo?=?plusFive.withOffsetSameInstant(ZoneOffset.ofHours(-2));時間戳記
諸如LocalDate和ZonedDateTime之類的類提供了對時間的直觀了解。 但是,通常我們需要從機器角度來看待時間。 為此,我們可以使用表示時間戳的Instant類。 Instant會計算從1970年1月1日(1970-01-01 00:00:00)的第一秒(也稱為EPOCH )開始的時間。 如果即時值出現在紀元之前,則它們可以為負。 它們遵循ISO 8601表示日期和時間的標準。
//?current?time Instant?now?=?Instant.now();//?from?unix?timestamp,?2010-01-01?12:00:00 Instant?fromUnixTimestamp?=?Instant.ofEpochSecond(1262347200);//?same?time?in?millis Instant?fromEpochMilli?=?Instant.ofEpochMilli(1262347200000l);//?parsing?from?ISO?8601 Instant?fromIso8601?=?Instant.parse("2010-01-01T12:00:00Z");//?toString()?returns?ISO?8601?format, e.g. 2014-02-15T01:02:03Z String?toIso8601?=?now.toString();//?as?unix?timestamp long?toUnixTimestamp?=?now.getEpochSecond();//?in?millis long?toEpochMillis?=?now.toEpochMilli();// plus/minus methods are available too Instant?nowPlusTenSeconds?=?now.plusSeconds(10);期限和期限
期間和持續時間是另外兩個重要的類別。 就像名稱所暗示的那樣,它們代表時間或數量。 期間使用基于日期的值(年,月,日),而期間使用秒或納秒來定義時間量。 持續時間最適合使用Instants和機器時間。 如果終點發生在起點之前,則“期間”和“持續時間”可以包含負值。
//?periodsLocalDate?firstDate?=?LocalDate.of(2010,?5,?17);?//?2010-05-17 LocalDate?secondDate?=?LocalDate.of(2015,?3,?7);?//?2015-03-07 Period?period?=?Period.between(firstDate,?secondDate);int?days?=?period.getDays();?//?18 int?months?=?period.getMonths();?//?9 int?years?=?period.getYears();?//?4 boolean?isNegative?=?period.isNegative();?//?falsePeriod?twoMonthsAndFiveDays?=?Period.ofMonths(2).plusDays(5); LocalDate?sixthOfJanuary?=?LocalDate.of(2014,?1,?6);//?add?two?months?and?five?days?to?2014-01-06,?result?is?2014-03-11 LocalDate?eleventhOfMarch?=?sixthOfJanuary.plus(twoMonthsAndFiveDays);//?durationsInstant?firstInstant=?Instant.ofEpochSecond(?1294881180?);?//?2011-01-13?01:13 Instant?secondInstant?=?Instant.ofEpochSecond(1294708260);?//?2011-01-11?01:11Duration?between?=?Duration.between(firstInstant,?secondInstant);//?negative?because?firstInstant?is?after?secondInstant?(-172920) long?seconds?=?between.getSeconds();//?get?absolute?result?in?minutes?(2882) long?absoluteResult?=?between.abs().toMinutes();//?two?hours?in?seconds?(7200) long?twoHoursInSeconds?=?Duration.ofHours(2).getSeconds();格式化和解析
在處理日期和時間時,格式化和解析是另一個大主題。 在Java 8中,這可以通過使用format()和parse()方法來實現:
//?2014-04-01?10:45 LocalDateTime?dateTime?=?LocalDateTime.of(2014,?Month.APRIL,?1,?10,?45);//?format?as?basic?ISO?date?format?(20140220) String?asBasicIsoDate?=?dateTime.format(DateTimeFormatter.BASIC_ISO_DATE);//?format?as?ISO?week?date?(2014-W08-4) String?asIsoWeekDate?=?dateTime.format(DateTimeFormatter.ISO_WEEK_DATE);//?format?ISO?date?time?(2014-02-20T20:04:05.867) String?asIsoDateTime?=?dateTime.format(DateTimeFormatter.ISO_DATE_TIME);//?using?a?custom?pattern?(01/04/2014) String?asCustomPattern?=?dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));//?french?date?formatting?(1.?avril?2014) String?frenchDate?=?dateTime.format(DateTimeFormatter.ofPattern("d.?MMMM?yyyy",?new?Locale("fr")));//?using?short?german?date/time?formatting?(01.04.14?10:45) DateTimeFormatter?formatter?=?DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(new?Locale("de")); String?germanDateTime?=?dateTime.format(formatter);//?parsing?date?strings LocalDate?fromIsoDate?=?LocalDate.parse("2014-01-20"); LocalDate?fromIsoWeekDate?=?LocalDate.parse("2014-W14-2",?DateTimeFormatter.ISO_WEEK_DATE); LocalDate?fromCustomPattern?=?LocalDate.parse("20.01.2014",?DateTimeFormatter.ofPattern("dd.MM.yyyy"));轉換次數
當然,我們并不總是擁有所需類型的對象。 因此,我們需要一個選項來在彼此之間轉換不同的日期/時間相關對象。 以下示例顯示了一些可能的轉換選項:
//?LocalDate/LocalTime?<->?LocalDateTime LocalDate?date?=?LocalDate.now(); LocalTime?time?=?LocalTime.now(); LocalDateTime?dateTimeFromDateAndTime?=?LocalDateTime.of(date,?time); LocalDate?dateFromDateTime?=?LocalDateTime.now().toLocalDate(); LocalTime?timeFromDateTime?=?LocalDateTime.now().toLocalTime();//?Instant?<->?LocalDateTime Instant?instant?=?Instant.now(); LocalDateTime?dateTimeFromInstant?=?LocalDateTime.ofInstant(instant,?ZoneId.of("America/Los_Angeles")); Instant?instantFromDateTime?=?LocalDateTime.now().toInstant(ZoneOffset.ofHours(-2));//?convert old?date/calendar/timezone?classes Instant?instantFromDate?=?new?Date().toInstant(); Instant?instantFromCalendar?=?Calendar.getInstance().toInstant(); ZoneId?zoneId?=?TimeZone.getDefault().toZoneId(); ZonedDateTime?zonedDateTimeFromGregorianCalendar?=?new?GregorianCalendar().toZonedDateTime();// convert to old classes Date?dateFromInstant?=?Date.from(Instant.now()); TimeZone?timeZone?=?TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles")); GregorianCalendar?gregorianCalendar?=?GregorianCalendar.from(ZonedDateTime.now());結論
使用Java 8,我們可以在java.time包中獲得非常豐富的API,用于處理日期和時間。 該API可以用更新,更靈活的類完全替代舊類,例如java.util.Date或java.util.Calendar。 由于大多數類都是不可變的,因此新的API有助于構建線程安全的系統。
- 示例的源代碼可以在GitHub上找到 。
翻譯自: https://www.javacodegeeks.com/2014/03/a-deeper-look-into-the-java-8-date-and-time-api.html
總結
以上是生活随笔為你收集整理的更深入地了解Java 8 Date and Time API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Setter依赖注入示例
- 下一篇: 海南省面积 海南省有多大面积