[Java] Java 8 DateTime ใหม่ ไฉไลกว่าเดิม
Hi, I'm Duke. |
Java 8 นอกจาก lambda expression ที่สร้างความโกลาหลให้กับชีวิต Java Programmer ที่เป็นมือใหม่ในวงการ functional language แล้ว ยังมีการปรับปรุง library เกี่ยวกับ Date, Time ด้วย
เปลี่ยน package ในการใช้งาน เพื่อป้องกันการสับสน
(ก่อนหน้านี้จะมี java.sql.Date กับ java.util.Date ให้งงเล่นๆ)java.util.Date; java.time.*;เราเคยเจ็บปวดกับ date, time กันมาพอสมควร ถึงเวลาแล้วที่ Java จะช่วยให้ชีวิตเราดีขึ้น โดย... แยก class ซะเลย
LocalDate LocalTime LocalDateTimeดูชื่อทั้ง 3 ตัวแล้วคงไม่ต้องเล่าอะไรมาก Date มีแค่วันที่ Time มีแค่เวลา ถ้าสนใจทั้งวันและเวลาก็เอา DateTime ไปใช้ ส่วนที่ต้อง Local เพราะมี Zoned อยู่ด้านล่างพร้อมคำอธิบายครับ
การดึงวันเวลาปัจจุบันก็ถูกทำให้เข้าใจมากขึ้น ไม่ใช่ new Date() อีกต่อไป
LocalDate.now() //2016-11-19 LocalTime.now() //20:00:01.635 LocalDateTime.now() //2016-11-19T20:00:01.635
การสร้าง object date,time โดยระบุค่าเอง
LocalDate.of(int year, Month month, int dayOfMonth); LocalTime.of(int hour, int minute, int second, int nanoOfSecond); LocalDateTime.of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond);
Month เป็น enum ถูกสร้างมาเพื่อให้อ่านง่ายขึ้น แทน Calendar ที่เป็น zero-based ไม่ต้องมา +1 -1 อีกต่อไปแล้ว มาลองเข้าไปดูความแตกต่างของ code กัน
//java.util.Calendar (Legacy way) public final static int JANUARY = 0; //java.time.Month (Java 8) public int getValue() { return ordinal() + 1; }สังเกตว่า Month จะสามารถนำไปใช้ได้ make sense กว่า เพราะเดือนจะตรงกับรูปแบบที่เข้าใจได้จริง คือเป็น 1 - 12 ไม่ใช่ 0 - 11
java.time.DateTimeException
นอกจากนี้ยังมีการทำ Exception มาให้ด้วย ซึ่งร่ำลือกันว่ามันทำให้อ่านได้รู้เรื่องกว่าเดิมมาก ของเก่าอาจแปลงค่าผิด หรือทำให้เกิด RuntimeException ไปเลย
Manipulating
ผมคงไม่พูดถึงการยุ่งกับ object date,time แบบเก่า เพราะมันช่างวุ่นวายเหลือเกิน ไหน Calendar ไหนจะ Date แปลงไปแปลงมา วันนี้ Java 8 เตรียม method เกี่ยวกับการเพิ่มลบวันมาให้แล้ว และมันถูกออกแบบมาให้ทำ channing methods ได้ (Mutable)plusYears minusYears plusMonths minusMonths .... .. minusNanos
Period & Duration
manipulating ไม่ได้ทำเพียงแค่จาก class ตัวเองเพียงอย่างเดียว ยังมี Period และ Duration มาช่วยอีก เพื่อเพิ่มความยืดหยุ่นให้กับการเล่น date, timePeriod period = Period.between(LocalDate.now().plusDays(40), LocalDate.now()); System.out.println(period); //P-1Y-1M-5D Duration duration = Duration.between(LocalDateTime.now().plusSeconds(70), LocalDateTime.now()); System.out.println(duration); //PT-1M-10Sทั้งสองตัวมีความแตกต่างกัน Period ใช้กับวัน Duration ใช้กับเวลา ซึ่งผลจากตัวอย่างด้านบนพอทำให้เห็นได้ว่าจะเป็นรูปย่อของวันเวลาที่ต่างกัน แล้วยังเอาไป plus/minus โดยใช้ Period ได้ด้วย แต่การเอาไปใช้ไม่ใช่ตัด String ตามที่ print ด้านบนแน่ ๆ
Formatting & Parsing
การปรับปรุงเรื่อง Formatter จะใช้ class DateTimeFormatter เพียงอย่างเดียว และยังมี pattern style ที่เตรียมมาให้บ้างการแปลงการ date ให้เป็น string (Formatting)
//using prepared pattern DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); dateFormatter.format(LocalDate.now()); timeFormatter.format(LocalTime.now()); dateTimeFormatter.format(LocalDateTime.now()); //using pattern DateTimeFormatter patternFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); System.out.println(patternFormatter.format(LocalDateTime.now()));การแปลงจาก string ให้เป็น date (Parsing)
LocalDate date = LocalDate.parse("19/11/2016", formatter); LocalTime time = LocalTime.parse("20:00");
นอกจากนี้ยังมี Chronology เพื่อให้เราสามารถเล่นกับปีพ.ศ. ปีค.ศ. ได้โดยที่ไม่ต้องเสี่ยงเจอบั๊กด้วยวิธี +543 อีกแล้ว
LocalDate date = LocalDate.of(2016,11,19); DateTimeFormatter toThai = DateTimeFormatter.ofPattern("dd-MM-yyyy") .withChronology(ThaiBuddhistChronology.INSTANCE); System.out.println(toThai.format(date)); //19-11-2559
ZonedDateTime
ยกมาพูดทีหลังเพราะ date,time library ใน Java 8 แนะนำให้หลีกเลี่ยงการเล่นกับ timezone ถ้าจำเป็นต้องใช้จริงๆ ZonedDateTime ตัวนี้คือทางออกที่ Java เตรียมไว้ให้ โดยที่ตัวอื่นๆ ด้านบนนั้นจะไม่มี method เกี่ยวกับ timezone เลย ตัวอย่างที่ชัดที่สุด คือ นาฬิการที่แสดงเวลาประเทศต่าง ๆ access_timeaccess_timeaccess_time...จบแล้ว สำหรับ Date & Time ใน Java 8 อันที่จริงของเก่ายังไม่ deprecate ก็ยังใช้ต่อไปได้ไม่มีปัญหา(ไม่มีขีดฆ่า ณ ตอนนี้) มือใหม่มือเก่าอยากลองก็ไปลองใช้กัน ส่วนถ้าเขียนเว็บอย่าลืมเช็ค appserv ด้วยว่ารองรับหรือยังนะครับ