Trong bài các bài viết trước, tôi đã Giới thiệu về kiểu Date Time trong Java. Trong bài này, chúng ta sẽ tìm hiểu thêm một số tính năng mới của Date Time trong Java 8.
Nội dung
Tại sao chúng ta cần API Date Time mới?
Trước khi tìm hiểu một số API mới, chúng ta hãy cùng nhình lại một số vấn đề về Date Time của phiên bản hiện tại:
- Các class Java Date Time không nhất quán: chúng ta có class Date trong cả 2 package java.util và java.sql . Trong khi class format/ parse chúng lại nằm ở trong package java.text.
- java.util.Date bao gồm cả date và time trong khi java.sql.Date chỉ bao gồm date. Cả 2 class đều có cùng tên, đây là một thiết kế khá xấu.
- Không rõ ràng trong việc định nghĩa các class cho time, timestamp, formatting và parsing. Chúng ta có lớp trừu tượng java.text.DateFormat để parse và format Date Time cần. Lớp SimpleDateFormat thường được sử dụng nhất.
- Tất cả các class Date đều mutable,do đó chúng không an toàn khi dùng chung trong môi trường đa luồng (Multi-Thread). Đây có thể coi là 1 vấn đề lớn với các class Java Date và Calendar.
- Class Date không cung cấp Internationalization và không hỗ trợ Timezone, sau đó các class java.util.Calendar và java.util.TimeZone được giới thiệu nhưng chúng cũng gặp phải các vấn đề bên trên.
Những thay đổi về Date & Time trong Java 8
API Date Time trong Java 8 cài đặt các phương thức theo chuẩn JSR-310. Nó được thiết kế để khắc phục tất cả các sai sót trong việc triển khai Date Time trước đó. Một số nguyên tắc thiết kế của API Date Time mới là:
- Khả năng immutable (Immutability): Tất cả các class trong Date Time API mới đều là immutable, điều này tốt cho môi trường đa luồng (Multi-Thread).
- Phân tách các mối quan tâm (Separation of Concerns): API mới phân chia rõ ràng giữa Date Time, hạn chế nhầm lẫn khi sử dụng. Nó định nghĩa phân biệt các class cho Date, Time, DateTime, Timestamp, Timezone, …
- Tính trong suốt (Clarity): Các method được định nghĩa 1 cách rõ ràng và thực thi các hành động giống nhau trong cùng 1 class. Ví dụ, để lấy thời gian hiện tại ta có method now(), các method format() và parse() đều được định nghĩa trong những class này. Tất cả các lớp đều sử dụng Factory Pattern và Strategy Pattern để xử lý tốt hơn. Một khi bạn đã sử dụng các phương thức trong một lớp bất kỳ, khi làm việc với các lớp khác sẽ không khó.
- Các tính năng hữu ích (Utility operations): Tất cả các class trong API Date Time đi kèm với các tác vụ phổ biến như cộng, trừ, parsing, định dạng date/time…
- Khả năng mở rộng (Extendable): API Date Time mới làm việc theo chuẩn ISO-8601 calendar, tuy nhiên chúng ta vẫn có thể sử dụng nó với các chuẩn không phải ISO.
Các package của API Date Time Java 8
- java.time : đây là 1 package chính của API Date Time. Nó gồm các class: LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration, … Tất cả các class này đều là immutable và thread safe.
- java.time.chrono: package gồm các generic API được định nghĩa cho các hệ thống có lịch không theo chuẩn ISO. Chúng ta có thể mở rộng class AbstractChronology để tạo Calendar riêng cho hệ thống của mình.
- java.time.format : package này gồm các class sử dụng cho formatting và parsing.
- java.time.temporal : package này gồm các temporal object và chúng ta có thể dùng chúng để lấy ngày cụ thể hoặc thời gian liên quan. Ví dụ, chúng ta có thể sử dụng chúng để tìm ra ngày đầu tiên hoặc ngày cuối cùng của tháng. Bạn có thể xác định các phương thức này một cách dễ dàng vì chúng luôn có định dạng withXXX().
- java.time.zone*: package này gồm các class hỗ trợ các Time zone khác nhau.
Các ví dụ với API Date/Time trong Java 8
- LocalDate : Tạo ra 1 instance của date theo tiêu chuẩn ISO 8601, không Time, không Time zone.
- LocalTime : Tạo ra 1 instance của time theo tiêu chuẩn ISO 8601, không Date, không Time zone.
- LocalDateTime : bao gồm cả 2 API trên, tạo ra instance chứa cả Date, Time và không có Time zone.
- ZonedDateTime : bao gồm API LocalDateTime có Time zone.
- Instant : hỗ trợ làm việc với timestamps, được sử dụng để ghi lại thời gian sự kiện trong ứng dụng. Nó lưu trữ dưới định dạng của unix timestamp. Ví dụ: 1970-01-01T00:00:00Z.
- Period : hỗ trợ tính toán năm/ tháng/ ngày giữa 2 Date Time.
- Duration : hỗ trợ tính toán chi tiết đến seconds and nanoseconds giữa 2 Date Time.
- Year : Tạo ra 1 instance của date theo tiêu chuẩn ISO 8601, chỉ có Year.
- YearMonth : Tạo ra 1 instance của date theo tiêu chuẩn ISO 8601, chỉ có Year và Month.
- DayOfWeek, Month Enum : các enum thể hiện các ngày trong tuần, tháng. Hỗ trợ một số thao tác tính toán, biểu diễn ngày trong tuần, tháng.
- ChronoUnit : được sử dụng để đo lượng/ tính toán thời gian như: năm, tháng, ngày, giờ, phút, giây. Ví dụ: YEARS, MONTHS, WEEKS, HOURS, …
- ChronoField : được sử dụng để truy xuất một phần phần nào đó của Date Time. Ví dụ: DAY_OF_MONTH, DAY_OF_WEEK, MONTH_OF_YEAR, YEAR, …
Sử dụng LocalDate
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.Month; import java.time.ZoneId; public class LocalDateExample { public static void main(String[] args) { // Current Date LocalDate today = LocalDate.now(); System.out.println("Current Date = " + today); // Creating LocalDate by providing input arguments LocalDate firstDay_2014 = LocalDate.of(2014, Month.JANUARY, 1); System.out.println("Specific Date = " + firstDay_2014); // Try creating date by providing invalid inputs // LocalDate feb29_2014 = LocalDate.of(2014, Month.FEBRUARY, 29); // Exception in thread "main" java.time.DateTimeException: // Invalid date 'February 29' as '2014' is not a leap year // Current date in "Asia/Ho_Chi_Minh", you can get it from ZoneId javadoc LocalDate todayHCM = LocalDate.now(ZoneId.of("Asia/Ho_Chi_Minh")); System.out.println("Current Date in IST = " + todayHCM); // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST // LocalDate todayIST = LocalDate.now(ZoneId.of("IST")); // Getting date from the base date i.e 01/01/1970 LocalDate dateFromBase = LocalDate.ofEpochDay(365); System.out.println("365th day from base date = " + dateFromBase); // Obtains an instance of LocalDate from a year and day-of-year LocalDate hundredDay2014 = LocalDate.ofYearDay(2014, 100); System.out.println("100th day of 2014 = " + hundredDay2014); } }
Output của chương trình trên:
Current Date = 2018-06-23 Specific Date = 2014-01-01 Current Date in IST = 2018-06-23 365th day from base date = 1971-01-01 100th day of 2014 = 2014-04-10
Sử dụng LocalTime
package com.gpcoder.datetime; import java.time.LocalTime; import java.time.ZoneId; public class LocalTimeExample { public static void main(String[] args) { // Current Time LocalTime time = LocalTime.now(); System.out.println("Current Time=" + time); // Creating LocalTime by providing input arguments // LocalTime.of(int hour, int minute, int second, int nanoOfSecond) LocalTime specificTime = LocalTime.of(12, 20, 25, 40); System.out.println("Specific Time of Day = " + specificTime); // Try creating time by providing invalid inputs // LocalTime invalidTime = LocalTime.of(25,20); // Exception in thread "main" java.time.DateTimeException: // Invalid value for HourOfDay (valid values 0 - 23): 25 // Current date in "Asia/Ho_Chi_Minh", you can get it from ZoneId javadoc LocalTime timeHCM = LocalTime.now(ZoneId.of("Asia/Ho_Chi_Minh")); System.out.println("Current Time in IST = " + timeHCM); // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST // LocalTime todayIST = LocalTime.now(ZoneId.of("IST")); // Getting date from the base date i.e 01/01/1970 LocalTime specificSecondTime = LocalTime.ofSecondOfDay(10000); System.out.println("10000th second time = " + specificSecondTime); } }
Output của chương trình trên:
Current Time=19:56:50.479 Specific Time of Day = 12:20:25.000000040 Current Time in IST = 19:56:50.558 10000th second time = 02:46:40
Sử dụng LocalDateTime
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.ZoneId; import java.time.ZoneOffset; public class LocalDateTimeExample { public static void main(String[] args) { // Current Date LocalDateTime today = LocalDateTime.now(); System.out.println("Current DateTime = " + today); // Current Date using LocalDate and LocalTime today = LocalDateTime.of(LocalDate.now(), LocalTime.now()); System.out.println("Current DateTime = " + today); // Creating LocalDateTime by providing input arguments // LocalDateTime.of(int year, Month month, int dayOfMonth, int hour, int minute, int second) LocalDateTime specificDate = LocalDateTime.of(2014, Month.JANUARY, 1, 10, 10, 30); System.out.println("Specific Date = " + specificDate); // Try creating date by providing invalid inputs // LocalDateTime feb29_2014 = LocalDateTime.of(2014, Month.FEBRUARY, 28, 25,1,1); // Exception in thread "main" java.time.DateTimeException: // Invalid value for HourOfDay (valid values 0 - 23): 25 // Current date in "Asia/Ho_Chi_Minh", you can get it from ZoneId javadoc LocalDateTime todayHCM = LocalDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh")); System.out.println("Current Date in IST = " + todayHCM); // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST // LocalDateTime todayIST = LocalDateTime.now(ZoneId.of("IST")); // Getting date from the base date i.e 01/01/1970 LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC); System.out.println("10000th second time from 01/01/1970 = " + dateFromBase); } }
Output của chương trình trên:
Current DateTime = 2018-06-23T18:05:28.574 Current DateTime = 2018-06-23T18:05:28.575 Specific Date = 2014-01-01T10:10:30 Current Date in IST = 2018-06-23T18:05:28.655 10000th second time from 01/01/1970 = 1970-01-01T02:46:40
Sử dụng ZonedDateTime
package com.gpcoder.datetime; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Set; public class ZonedDateTimeExample { public static void main(String[] args) { // Get all available zones Set<String> allZoneIds = ZoneId.getAvailableZoneIds(); System.out.println("allZoneIds = " + allZoneIds); ZoneId zoneHCM = ZoneId.of("Asia/Ho_Chi_Minh"); // Creating LocalDateTime by providing input arguments LocalDateTime today = LocalDateTime.now(); System.out.println("LocalDateTime = " + today); // Creating ZonedDateTime by providing input arguments ZonedDateTime hcmDateTime = ZonedDateTime.of(today, zoneHCM); System.out.println("ZonedDateTime = " + hcmDateTime); // using offsets ZoneOffset offset = ZoneOffset.of("+05:00"); System.out.println("offset = " + offset); OffsetDateTime todayPlusFive = OffsetDateTime.of(today, offset); System.out.println("todayPlusFive = " + todayPlusFive); OffsetDateTime todayMinusTwo = todayPlusFive.withOffsetSameInstant(ZoneOffset.ofHours(-2)); System.out.println("todayMinusTwo = " + todayMinusTwo); } }
Output của chương trình trên:
allZoneIds = [Asia/Aden, America/Cuiaba, Etc/GMT+9, ..., Europe/Monaco] LocalDateTime = 2018-06-23T18:15:31.015 ZonedDateTime = 2018-06-23T18:15:31.015+07:00[Asia/Ho_Chi_Minh] offset = +05:00 todayPlusFive = 2018-06-23T18:15:31.015+05:00 todayMinusTwo = 2018-06-23T11:15:31.015-02:00
Sử dụng Instant
package com.gpcoder.datetime; import java.time.Duration; import java.time.Instant; public class InstantExample { public static void main(String[] args) { // Current timestamp Instant now = Instant.now(); System.out.println("Current Timestamp = " + now); // Instant from timestamp Instant specificTime = Instant.ofEpochMilli(now.toEpochMilli()); System.out.println("Specific Time = " + specificTime); // Obtain an instance of Instant from a text string Instant specifyString = Instant.parse("2018-06-20T10:37:30.00Z"); System.out.println("specifyString = " + specifyString); // Obtains a Duration representing a number of standard 24 hour days // return Duration with format of days*24 Duration thirtyDay = Duration.ofDays(30); System.out.println(thirtyDay); // Copy of this instant with the specified amount subtracted Instant minus5 = now.minus(Duration.ofDays(5)); System.out.println("minus5 = " + minus5); // Copy of this instant with the specified amount added Instant plus5 = now.plus(Duration.ofDays(5)); System.out.println("plus5 = " + plus5); } }
Output của chương trình trên:
Current Timestamp = 2018-06-23T11:32:43.131Z Specific Time = 2018-06-23T11:32:43.131Z specifyString = 2018-06-20T10:37:30Z PT720H minus5 = 2018-06-18T11:32:43.131Z plus5 = 2018-06-28T11:32:43.131Z
Sử dụng Period
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.Period; public class PeriodExample { public static void main(String[] args) { LocalDate firstDate = LocalDate.now(); LocalDate secondDate = LocalDate.of(2017, 5, 20); System.out.println("firstDate: " + firstDate); // 2018-06-23 System.out.println("secondDate: " + secondDate); // 2017-05-20 Period period = Period.between(firstDate, secondDate); System.out.println("period: " + period); // P-1M-3D int days = period.getDays(); int months = period.getMonths(); int years = period.getYears(); boolean isNegative = period.isNegative(); System.out.println("days: " + days); // -3 System.out.println("months: " + months); // -1 System.out.println("years: " + years); // -1 System.out.println("isNegative: " + isNegative); // true Period twoMonthTenDays = Period.ofMonths(2).plusDays(10); System.out.println("twoMonthTenDays: " + twoMonthTenDays); // P2M10D LocalDate plusDate = firstDate.plus(twoMonthTenDays); System.out.println("plusDate: " + plusDate); // 2018-09-02 LocalDate minusDate = firstDate.minus(twoMonthTenDays); System.out.println("minusDate: " + minusDate); // 2018-04-13 } }
Sử dụng Duration
package com.gpcoder.datetime; import java.time.Duration; import java.time.LocalDateTime; public class DurationExample { public static void main(String[] args) { LocalDateTime firstDate = LocalDateTime.now(); LocalDateTime secondDate = LocalDateTime.of(2018, 6, 20, 0, 0, 0); System.out.println("firstDate: " + firstDate); // 2018-06-23T21:31:28.924 System.out.println("secondDate: " + secondDate); // 2018-06-20T00:00 // Obtains a Duration representing the duration between two temporal objects // The temporal objects are Instant or LocalDateTime Duration duration = Duration.between(firstDate, secondDate); System.out.println("duration: " + duration); // PT-93H-31M-28.924S long days = duration.toDays(); long hours = duration.toHours(); long minutes = duration.toMinutes(); long seconds = duration.getSeconds(); long millis = duration.toMillis(); long nanos = duration.toNanos(); System.out.println("days: " + days); // -3 System.out.println("hours: " + hours); // -93 System.out.println("minutes: " + minutes); // -5611 System.out.println("seconds: " + seconds); // -336689 System.out.println("millis: " + millis); // -336688924 System.out.println("nanos: " + nanos); // -336688924000000 Duration twoHours = Duration.ofHours(2); System.out.println("twoHours: " + twoHours); // PT2H LocalDateTime plusDate = firstDate.plus(twoHours); System.out.println("plusDate: " + plusDate); // 2018-06-23T23:35:21.045 LocalDateTime minusDate = firstDate.minus(twoHours); System.out.println("minusDate: " + minusDate); // 2018-06-23T19:35:21.045 } }
Sử dụng Year, YearMonth
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.Year; import java.time.YearMonth; public class YearMonthExample { public static void main(String[] args) { // Year Example Year currentYear = Year.now(); System.out.println("currentYear: " + currentYear); // 2018 Year specifyYear = Year.of(2016); System.out.println("specifyYear: " + specifyYear); // 2016 System.out.println("isLeap : " + specifyYear.isLeap()); // true int dayOfYear = 100; LocalDate localDate = currentYear.atDay(dayOfYear); System.out.println("localDate: " + localDate); // 2018-04-10 // YearMonth Example YearMonth currentYearMonth = YearMonth.now(); System.out.println("currentYearMonth: " + currentYearMonth); YearMonth specifyYearMonth = YearMonth.of(2016, 1); System.out.println("specifyYearMonth: " + specifyYearMonth); int dayOfMonth = 20; LocalDate localDate2 = currentYearMonth.atDay(dayOfMonth); System.out.println("localDate2: " + localDate2); // 2018-06-20 // Year -> YearMonth YearMonth ym = currentYear.atMonth(5); System.out.println("ym: " + ym); // 2018-05 } }
Sử dụng DayOfWeek, Month Enum
package com.gpcoder.datetime; import java.time.DayOfWeek; import java.time.Month; import java.time.format.TextStyle; import java.util.Locale; public class WeekMonthEnumExample { public static void main(String[] args) { // DayOfWeek Enum Example DayOfWeek monday = DayOfWeek.MONDAY; System.out.println(monday); // MONDAY System.out.println(monday.getDisplayName(TextStyle.SHORT, Locale.getDefault())); // Mon System.out.println(monday.getDisplayName(TextStyle.FULL, Locale.getDefault())); // Monday System.out.println(monday.plus(5)); // SATURDAY System.out.println(DayOfWeek.of(1)); // MONDAY System.out.println(DayOfWeek.of(7)); // SUNDAY System.out.println(DayOfWeek.valueOf("SUNDAY")); // SUNDAY System.out.println(monday.compareTo(DayOfWeek.SUNDAY)); // -6 // Month Enum Example Month april = Month.APRIL; System.out.println(april); // APRIL System.out.println(april.getDisplayName(TextStyle.SHORT, Locale.getDefault())); // Apr System.out.println(april.getDisplayName(TextStyle.FULL, Locale.getDefault())); // April System.out.println(april.plus(3)); // JULY System.out.println(Month.FEBRUARY.maxLength()); // 29 System.out.println(Month.FEBRUARY.minLength()); // 28 System.out.println(april.firstDayOfYear(true)); // 92 System.out.println(Month.of(1)); // JANUARY System.out.println(Month.of(12)); // DECEMBER System.out.println(Month.valueOf("FEBRUARY")); // FEBRUARY System.out.println(april.compareTo(Month.FEBRUARY)); // 2 } }
Sử dụng ChronoUnit, ChronoField Enum
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; public class ChronoFieldUnitExample { public static void main(String[] args) { // ====== ChronoUnit Example ====== // Get the current date LocalDate today = LocalDate.now(); System.out.println("Current date: " + today); // add 1 week to the current date LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); System.out.println("Next week: " + nextWeek); // add 1 week to the current date LocalDate previousWeek = today.minus(1, ChronoUnit.WEEKS); System.out.println("Previous week: " + previousWeek); // add 1 month to the current date LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS); System.out.println("Next month: " + nextMonth); // add 1 year to the current date LocalDate nextYear = today.plus(1, ChronoUnit.YEARS); System.out.println("Next year: " + nextYear); // add 10 years to the current date LocalDate nextDecade = today.plus(1, ChronoUnit.DECADES); System.out.println("Date after ten year: " + nextDecade); // ====== ChronoField Example ====== LocalDateTime currentDateTime = LocalDateTime.now(); System.out.println("\ncurrentDateTime: " +currentDateTime); System.out.println("Year: " + currentDateTime.get(ChronoField.YEAR)); System.out.println("Month: " + currentDateTime.get(ChronoField.MONTH_OF_YEAR)); System.out.println("Day of month: " + currentDateTime.get(ChronoField.DAY_OF_MONTH)); System.out.println("Hour of day: " + currentDateTime.get(ChronoField.HOUR_OF_DAY)); System.out.println("Minute of hour: " + currentDateTime.get(ChronoField.MINUTE_OF_HOUR)); } }
Output của chương trình:
Current date: 2018-06-23 Next week: 2018-06-30 Previous week: 2018-06-16 Next month: 2018-07-23 Next year: 2019-06-23 Date after ten years: 2028-06-23 currentDateTime: 2018-06-23T23:00:07.812 Year: 2018 Month: 6 Day of month: 23 Hour of day: 23 Minute of hour: 0
Lớp tiện ích Java 8 Date API
Như đã đề cập ở phần trên, hầu hết các lớp Date Time cung cấp các phương thức tiện ích như cộng / trừ ngày, tuần, tháng, … Một số phương thức tiện ích khác để điều chỉnh ngày sử dụng TemporalAdjuster và tính toán, so sánh khoảng thời gian giữa hai ngày.
Ví dụ bên dưới đây cho LocalDate, với LocalTime, LocalDateTime, … các bạn tìm hiểu thêm ở các link tham khảo của oracle cuối bài viết.
package com.gpcoder.datetime; import java.time.LocalDate; import java.time.LocalTime; import java.time.Period; import java.time.temporal.TemporalAdjusters; public class DateApiUtilities { public static void main(String[] args) { LocalDate today = LocalDate.now(); // Get the Year, check if it's leap year System.out.println("Year " + today.getYear() + " is Leap Year? " + today.isLeapYear()); // Compare two LocalDate for before and after System.out.println("Today is before 01/01/2018? " + today.isBefore(LocalDate.of(2018, 1, 1))); // Create LocalDateTime from LocalDate System.out.println("Current Time = " + today.atTime(LocalTime.now())); // plus and minus operations System.out.println("10 days after today will be " + today.plusDays(10)); System.out.println("3 weeks after today will be " + today.plusWeeks(3)); System.out.println("20 months after today will be " + today.plusMonths(20)); System.out.println("10 days before today will be " + today.minusDays(10)); System.out.println("3 weeks before today will be " + today.minusWeeks(3)); System.out.println("20 months before today will be " + today.minusMonths(20)); // Temporal adjusters for adjusting the dates LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); System.out.println("First date of this month= " + firstDayOfThisMonth); LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); System.out.println("Last date of this month= " + lastDayOfThisMonth); LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear()); System.out.println("Last date of this year= " + lastDayOfYear); Period period = today.until(lastDayOfYear); System.out.println("Period Format= " + period); System.out.println("Months remaining in the year= " + period.getMonths()); } }
Output của chương trình trên:
Year 2018 is Leap Year? false Today is before 01/01/2018? false Current Time = 2018-06-23T18:49:40.865 10 days after today will be 2018-07-03 3 weeks after today will be 2018-07-14 20 months after today will be 2020-02-23 10 days before today will be 2018-06-13 3 weeks before today will be 2018-06-02 20 months before today will be 2016-10-23 First date of this month= 2018-06-01 Last date of this month= 2018-06-30 Last date of this year= 2018-12-31 Period Format= P6M8D Months remaining in the year= 6
Định dạng (Format) và Phân tích (Parse) Date Time trong Java 8
Trong các API của LocalDate, LocalTime, LocalDateTime, … cung cấp 2 phương thức cho việc phân tích và định dạng Date Time:
- format(pattern) : được sử dụng để định dạng một giá trị Date Time sang chuỗi tương ứng với pattern được cung cấp.
- parse(str, pattern) : được sử dụng để phân tích chuỗi bất kỳ với pattern được cung cấp sang kiểu Date Time tương ứng.
Ví dụ:
package com.gpcoder.datetime; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateParseFormatExample { public static void main(String[] args) { // Format LocalDate examples LocalDate date = LocalDate.now(); System.out.println("Default format of LocalDate = " + date); System.out.println(date.format(DateTimeFormatter.ofPattern("d::MMM::uuuu"))); System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE)); // Format LocalDateTime examples LocalDateTime dateTime = LocalDateTime.now(); System.out.println("\nDefault format of LocalDateTime = " + dateTime); System.out.println(dateTime.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"))); System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE)); // Format Instant Example Instant timestamp = Instant.now(); System.out.println("\nDefault format of Instant = " + timestamp); // Parse examples LocalDateTime dt = LocalDateTime.parse("27::Apr::2014 21::39::48", DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss")); System.out.println("\nDefault format after parsing = " + dt); } }
Output của chương trình trên:
Default format of LocalDate = 2018-06-23 23::Jun::2018 20180623 Default format of LocalDateTime = 2018-06-23T19:10:39.309 23::Jun::2018 19::10::39 20180623 Default format of Instant = 2018-06-23T12:10:39.310Z Default format after parsing = 2014-04-27T21:39:48
Chuyển đổi qua lại giữa các kiểu dữ liệu Date Time
package com.gpcoder.datetime; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; public class DateTimeConversionExample { public static void main(String[] args) { // LocalDate/ LocalTime <-> LocalDateTime/ ZonedDateTime LocalDate date = LocalDate.now(); LocalTime time = LocalTime.now(); LocalDateTime dateTimeFromDateAndTime = LocalDateTime.of(date, time); LocalDate dateFromDateTime = dateTimeFromDateAndTime.toLocalDate(); LocalTime timeFromDateTime = dateTimeFromDateAndTime.toLocalTime(); ZonedDateTime hcmDateTime = ZonedDateTime.of(dateTimeFromDateAndTime, ZoneId.of("Asia/Ho_Chi_Minh")); // Convert old classes to Java 8 Date Time Instant instantFromDate = new Date().toInstant(); ZoneId zoneId = TimeZone.getDefault().toZoneId(); Instant instantFromCalendar = Calendar.getInstance().toInstant(); ZonedDateTime zonedDateTime = new GregorianCalendar().toZonedDateTime(); // Instant <-> LocalDateTime Instant instant = Instant.now(); LocalDateTime dateTimeFromInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); Instant instantFromLocalDateTime = dateTimeFromInstant.toInstant(ZoneOffset.ofHours(+7)); // Instant <-> LocalDate LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate(); Instant instantFromLocalDate = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant(); // Convert Java 8 Date Time to old classes Date dateFromInstant = Date.from(Instant.now()); TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Ho_Chi_Minh")); GregorianCalendar gregorianCalendar = GregorianCalendar.from(ZonedDateTime.now()); } }
Tài liệu tham khảo:
- https://www.journaldev.com/2800/java-8-date-localdate-localdatetime-instant
- https://www.javatpoint.com/java-date
- http://www.mkyong.com/tutorials/java-date-time-tutorials/
- https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Date.htm