Manipulate date and time in Java 8 - Các thao tác so sánh, chỉnh sửa, chuyển đổi, định dạng với date trong java 8
Dữ liệu kiểu date, time là kiểu dữ liệu cơ bản, thường xuyên được sử dụng trong nhiều lĩnh vực ứng dụng khác nhau. Trước đây để thao tác với kiểu date trong java, chúng ta thường sử dụng 2 class là Calendar và SimpleDateFormat. Để viết các method utility thao ...
Dữ liệu kiểu date, time là kiểu dữ liệu cơ bản, thường xuyên được sử dụng trong nhiều lĩnh vực ứng dụng khác nhau.
Trước đây để thao tác với kiểu date trong java, chúng ta thường sử dụng 2 class là Calendar và SimpleDateFormat.
Để viết các method utility thao tác với date mà dùng các method của 2 class này khá là rắc rối, lòng vòng.
Ngoài ra 1 vài date và time class trong java 7 trở xuống được design không tốt và không đồng nhất.
Ví dụ: năm trong class java.util.Date bắt đầu từ năm 1900, tháng bắt đầu từ 1, ngày bắt đầu từ 0 Hoặc trong tham số tháng khi thao tác với Calendar thì tháng lại bắt đầu từ 0
Calendar fromCalendar = Calendar.getInstance(); fromCalendar.set(2015, 11, 27); // tương đương với 2015-12-27
Sau này với sự ra đời của thư viện Joda-time, khi cần thao tác với kiểu date nhiều và phức tạp. Joda-time là sự lựa chọn tốt nhất.
Khi Java 8 được release, nó cải thiện và thay đổi rất nhiều so với các version trước đây. Những cái mới Java 8 đem lại làm thay đổi về tư tưởng code, cách thức code của Java Developer. Date time trong java 8 cũng là phần được thay đổi khá nhiều. Gần như là 1 sự lột xác. Có 1 lưu ý là: quá trình phát triển date, time API mới cho Java 8 có sự tham gia của Stephen Colebourne - tác giả của Joda time Vậy là với java 8, bạn sẽ không cần dùng thêm bất kỳ date-time thư viện của hãng thứ 3 nào để thao tác với kiểu dữ liệu date
Những ví dụ sau đây sẽ hướng dẫn sử dụng date, time API trong java 8 để giải quyết các use-case thường gặp.
1. Các class date, time chính nên biết trong Java 8
- LocalDate: mô tả kiểu dữ liệu date chỉ bao gồm ngày, tháng, năm. Thường được sử dụng để lưu trữ, mô tả: ngày sinh, ngày tốt nghiệp hay ngày vào 1 cty. Ví dụ 2016-01-14
- LocalTime: kiểu dữ liệu chỉ bao gồm giờ, phút, giây. Thường sử dụng khi cần thao tác với thời gian trong 1 ngày
- LocalDateTime: kiểu dữ liệu gồm đầy đủ ngày tháng năm, giờ phút giây nhưng không có mô tả time-zone. Nên dùng kiểu dữ liệu này trong các trường hợp khi thao tác với date mà ko muốn bị ảnh hưởng bởi time-zone giữa các vùng, quốc gia khác nhau
- ZonedDateTime: kiểu dữ liệu đẩy đủ và bao gồm cả time-zone
2. Use case 1- get today date in Java 8: lấy giá trị của ngày hiện tại
-Đầu tiên là lấy giá trị của thời gian hiện tại của hệ thống
// Today for short time LocalDate nowShort = LocalDate.now(); System.out.println("Current time system: " + nowShort); // Today for full time LocalDateTime nowFull = LocalDateTime.now(); System.out.println("Full current time: " + nowFull);
-Lấy thời gian hiện tại của 1 múi giờ cụ thể
List Zone Id https://garygregory.wordpress.com/2013/06/18/what-are-the-java-timezone-ids/
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ZoneId vietnam = ZoneId.of("Asia/Ho_Chi_Minh"); ZoneId hawaii = ZoneId.of("US/Hawaii"); LocalDate nowVietNam = LocalDate.now(vietnam); System.out.println("Current time of Viet Nam: " + nowVietNam); LocalDateTime fullVietNam = LocalDateTime.now(vietnam); // get today time of Hawaii USA LocalDateTime fullHawaii = LocalDateTime.now(hawaii); System.out.println("Full current time of Viet Nam: " + fullVietNam); System.out.println("Full current time of Hawaii: " + fullHawaii);
3. Use case 2 - get components year, month, day in date time type in Java 8: lấy các đơn vị ngày tháng năm từ dữ liệu date trong Java 8
LocalDate localDate = LocalDate.now(); System.out.printf("Ngay: %d - Thang: %d - Nam: %d %n", localDate.getDayOfMonth(), localDate.getMonthValue(), localDate.getYear()); System.out.println("Note that: dont need plus 1 when get month as java 7 "); LocalDateTime localDateTime = LocalDateTime.now(); System.out.printf("Ngay: %d - Thang: %d - Nam: %d Gio: %d - Phut: %d - Giay: %d %n", localDateTime.getDayOfMonth(), localDateTime.getMonthValue(), localDateTime.getYear() , localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond());
4. Use case 3 - get a specific date
LocalDate birthdayOfHoChiMinh = LocalDate.of(1890, 5, 19); System.out.println("Birth of Ho Chi Minh: " + birthdayOfHoChiMinh); // year, month, day, hour, minute , second LocalDateTime newYear2010 = LocalDateTime.of(2010, 1, 1, 0, 0, 0); System.out.println("Happy new year: " + newYear2010);
5. Use case 4 - Compare date in Java 8: so sánh date trong java 8
-Compare equal date: so sánh bằng giữa 2 đối tượng date. Sử dụng method equals, điều này sẽ không thể thực hiện tương tự như trong java 7 trở xuống
System.out.println("-------------------- Compare equal -------------------"); LocalDate localDate1 = LocalDate.of(1985, 8 ,22); LocalDate localDate2 = LocalDate.of(1985, 8 ,22); LocalDate localDate3 = LocalDate.of(1985, 8, 20); System.out.printf("Is equal between %s and %s : %b %n", localDate1, localDate2, localDate1.equals(localDate2)); System.out.printf("Is equal between %s and %s : %b %n", localDate1, localDate3, localDate1.equals(localDate3)); LocalDateTime localDateTime1 = LocalDateTime.of(2010, 10, 10, 10 , 10, 10); LocalDateTime localDateTime2 = LocalDateTime.of(2010, 10, 10, 10 , 10, 10); System.out.printf("Is equal between %s and %s : %b %n", localDateTime1, localDateTime2, localDateTime1.equals(localDateTime2));
-Compare greater or less two dates: so sánh lớn hơn hoặc nhỏ hơn giữa 2 đối tượng date Sử dụng các method isAfter, isBefore, hoặc compareTo
LocalDate oldLocalDate = LocalDate.of(2010, 10, 10); LocalDate newLocalDate = LocalDate.of(2020, 10, 10); System.out.printf("%s after %s : %b %n", oldLocalDate, newLocalDate, oldLocalDate.isAfter(newLocalDate)); System.out.printf("%s before %s : %b %n", oldLocalDate, newLocalDate, oldLocalDate.isBefore(newLocalDate)); System.out.printf("%s compare to %s : %d %n", oldLocalDate, newLocalDate, oldLocalDate.compareTo(newLocalDate)); System.out.printf("%s compare to %s : %d %n", newLocalDate, oldLocalDate, newLocalDate.compareTo(oldLocalDate)); // compare full time System.out.println("-------------------- Compare greater, less full time -------------------"); LocalDateTime oldLocalDateTime = LocalDateTime.of(2010, 10, 10, 10, 10, 10); LocalDateTime newLocalDateTime = LocalDateTime.of(2010, 10, 10, 10, 10, 20); System.out.printf("%s after %s : %b %n", oldLocalDateTime, newLocalDateTime, oldLocalDateTime.isAfter(newLocalDateTime)); System.out.printf("%s before %s : %b %n", oldLocalDateTime, newLocalDateTime, oldLocalDateTime.isBefore(newLocalDateTime)); System.out.printf("%s compare to %s : %d %n", oldLocalDateTime, newLocalDateTime, oldLocalDateTime.compareTo(newLocalDateTime)); System.out.printf("%s compare to %s : %d %n", newLocalDateTime, oldLocalDateTime, newLocalDateTime.compareTo(oldLocalDateTime));
6. Use case 5 - check events : kiểm tra các ngày đặc biệt events xảy ra trong năm ví dụ giáng sinh, lễ tình yêu Sử dụng class MonthDay để check ngày hiện tại có phải là giáng sinh hay không để chạy chương trình sale
MonthDay currentMonthDay = MonthDay.from(LocalDate.now()); MonthDay christmasDay = MonthDay.of(12, 25); if(currentMonthDay.equals(christmasDay)) System.out.println("Special sale"); else System.out.println("Normally");
7. Use case 6 - modify with date: chỉnh sửa date
Sử dụng các method như plusDays, plusMonths hoặc minusDays, minusSeconds với 1 tham số, hoặc sử dụng minus, plus với 2 tham số số lượng và đơn vị muốn thao tác
LocalDateTime dateTime = LocalDateTime.now(); // Or LocalDateTime dateTime = LocalDateTime.of(2015,10,10,10,10,10); // plus day, month, year, week System.out.println("-------------------- Plus method --------------"); System.out.println("Plus a day: " + dateTime.plusDays(1)); System.out.println("Plus two months: " + dateTime.plusMonths(2)); System.out.println("Plus three weeks: " + dateTime.plusWeeks(3)); System.out.println("Plus 4 years: " + dateTime.plusYears(4)); // minus day, month, year, week. Use minusMethod or pass negative number with plus method System.out.println("-------------------- Minus method --------------"); System.out.println("Minus a day: " + dateTime.minusDays(1)); System.out.println("Minus a day: " + dateTime.plusDays(-1)); System.out.println("Minus two months: " + dateTime.minusMonths(2)); System.out.println("Minus 60 seconds: " + dateTime.minusSeconds(60)); // Or use general method with type of field System.out.println("Minus 60 seconds: " + dateTime.minus(60, ChronoUnit.SECONDS)); System.out.println("Minus two months: " + dateTime.minus(2, ChronoUnit.MONTHS));
8. Use Period to calculte number of month, day between two dates: sử dụng Period để tính toán số ngày hoặc số tháng giữa 2 date
LocalDate augustDate = LocalDate.of(2014, 8, 20); LocalDate novemberDate = LocalDate.of(2016, Month.NOVEMBER, 14); Period periodToNextJavaRelease = Period.between(augustDate, novemberDate); System.out.println("Months left between two dates : " + periodToNextJavaRelease.getMonths() ); System.out.println("Days left between two dates : " + periodToNextJavaRelease.getDays() ); System.out.println("Years left between two dates : " + periodToNextJavaRelease.getYears() );
9. Check leap year in Java 8: kiểm tra 1 đối tượng date có thuộc năm nhuận hay không
LocalDate today = LocalDate.now(); System.out.println("Is leap year " + today.isLeapYear());
10. Parse String to date in Java 8: chuyển từ 1 string sang kiểu date
// parse with predefined String dateStr = "20160816"; LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.BASIC_ISO_DATE); System.out.println("Local Date value: " + localDate); String dateTimeStr = "2016-08-03T12:12:30"; LocalDateTime localDateTime = LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME); System.out.println("Local Date Time value " + localDateTime); // parse with format of user String dateTimeStr2 = "2016-08-03 12:12"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); System.out.println("Local Date Time value " + LocalDateTime.parse(dateTimeStr2, formatter));
11. Format Date to String in Java 8:
LocalDateTime localDateTime = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy"); DateTimeFormatter formatterFull = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); System.out.println("Date string: " + localDateTime.format(formatter)); System.out.println("Date string full: " + localDateTime.format(formatterFull));
Reference link
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html