Java 8: new Date/Time APIs

Converting between java.time.LocalDateTime and java.util.Date

Java 8 Date – LocalDate, LocalDateTime, Instant

Java 8 has also introduced brand new Date and Time API. Java’s handling of Date, Calendar and Time is long been criticized by the community, which is not helped by Java’s decision of making java.util.Date mutable and SimpleDateFormat not thread-safe.

Seems, Java has realized a need for better date and time support, which is good for a community which already used to of Joda Date and Time API.

One of the many good things about new Date and Time API is that now it defines principle date-time concepts e.g. instants, duration, dates, times, timezones and periods. It also follows good thing from Joda library about keeping human and machine interpretation of date time separated.

They are also based on the ISO Calendar system and unlike their predecessor, class in java.time packages are both immutable and thread-safe. New date and time API is located inside java.time package and some of the key classes are following :

  • Instant - It represents a timestamp.
  • LocalDate - a date without time e.g. 2014-01-14. It can be used to store birthday, anniversary, date of joining etc.
  • LocalTime - represents time without a date.
  • LocalDateTime - is used to combine date and time, but still without any offset or time-zone.
  • ZonedDateTime - a complete date-time with time-zone and resolved offset from UTC/Greenwich

They are also coming with better time zone support with ZoneOffSet and ZoneId.

Parsing and Formatting of Dates are also revamped with new DateTimeFormatter class.

Joda Date and Time API
http://www.joda.org/joda-time/

1. How to get today’s date in Java 8
Java 8 has a class called java.time.LocalDate which can be used to represent today’s date. This class is little different than java.util.Date, because it only contains the date, no time part. So anytime if you just to represent date without time, use this class.

It also prints the date in a nicely formatted way, unlike previous Date class which print data non-formatted.

LocalDate today = LocalDate.now(); 
System.out.println("Today's Local date : " + today);

2. How to get current day, month and year in Java 8
The LocalDate class has a convenient method to extract year, month, the day of the month and several other date attributes from an instance of LocalDate class. By using these methods, you can get whatever property of date you want, no need to use a supporting class like java.util.Calendar :

LocalDate today = LocalDate.now(); 
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.printf("Year : %d Month : %d day : %d \t %n", year, month, day);

Compare this with the older way of getting the current date, month, and year in Java:

Calendar localCalendar = Calendar.getInstance(TimeZone.getDefault());
Date currentTime = localCalendar.getTime();
int currentDay = localCalendar.get(Calendar.DATE);
int currentMonth = localCalendar.get(Calendar.MONTH) + 1;
int currentYear = localCalendar.get(Calendar.YEAR);
int currentDayOfWeek = localCalendar.get(Calendar.DAY_OF_WEEK);
int currentDayOfMonth = localCalendar.get(Calendar.DAY_OF_MONTH);
int currentDayOfYear = localCalendar.get(Calendar.DAY_OF_YEAR);

System.out.println("Current Date and time details in local timezone");
System.out.println("Current Date: " + currentTime);
System.out.println("Current Day: " + currentDay);
System.out.println("Current Month: " + currentMonth);
System.out.println("Current Year: " + currentYear);
System.out.println("Current Day of Week: " + currentDayOfWeek);
System.out.println("Current Day of Month: " + currentDayOfMonth);
System.out.println("Current Day of Year: " + currentDayOfYear);

3. How to get a particular date in Java 8
In the first example, we have seen that creating today’s date was very easy because of static factory method now(), but you can also create a date from any arbitrary date by using another useful factory method called LocalDate.of(), this takes a year, month and date and return an equivalent LocalDate instance.

The good thing about this method is that it has not repeated mistake done in previous API e.g. year started from 1900, months starting from zero etc. Here dates are represented in the way you write it e.g. in the following example it will represent 14th January, nothing is hidden about it.

LocalDate dateOfBirth = LocalDate.of(2016, 10, 10);
System.out.println("Your Date of birth is : " + dateOfBirth);

4. How to check if two dates are equal in Java 8
Talking about real world date time task, one of them is to checking whether two dates are same or not. Many times you would like to check whether today is that special day, your birthday, anniversary or a trading holiday or not. Sometimes, you will get an arbitrary date and you need to check against certain date e.g. holidays to confirm whether given date is a holiday or not.

This example will help you to accomplish those task in Java 8. Just like you thought, LocalDate has overridden equal method to provide date equality, as shown in the following example :

LocalDate today = LocalDate.now();
LocalDate date1 = LocalDate.of(2016, 10, 15);
if (date1.equals(today)) {
    System.out.printf("Today %s and date1 %s are same date %n", today, date1);
}

In this example the two dates we compared are equal. BTW, If you get a formatted date String in your code, you will have to parse that into a date before checking equality. Just compare this with the older way of comparing dates in Java, you will find it a fresh breeze.

5. How to check for recurring events e.g. birthday in Java 8
Another practical task related to date and time in Java is checking for recurring events e.g. monthly bills, wedding anniversary, EMI date or yearly insurance premium dates. If you are working for an E-commerce site, you would definitely have a module which sends birthday wishes to your customer and seasons greetings on every major holiday e.g. Christmas, Thanksgiving date or Deepawali in India.

How do you check for holidays or any other recurring event in Java? By using MonthDay class. This class is a combination of month and date without a year, which means you can use it for events which occur every year.

There are similar classes exists for other combination as well e.g. YearMonth. Like other classes in new date and time API, this is also immutable and thread-safe and it is also a value class. Now let’s see example of how to use MonthDay class for checking recurring date time events :

LocalDate today = LocalDate.now();
MonthDay currentMonthDay = MonthDay.from(today);

LocalDate dateOfBirth = LocalDate.of(2010, 10, 15);
MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());

if(currentMonthDay.equals(birthday)){ 
    System.out.println("Many Many happy returns of the day !!"); 
}else{ 
    System.out.println("Sorry, today is not your birthday"); 
} 

Since today’s date matches with the birthday, irrespective of year you have seen the birthday greeting as output. You can run this program by advancing your windows date and time clock and see if it alerts you on your next birthday or not, or you can write a JUnit test with the date of your next year birthday and see if your code runs properly or not.

6. How to get current Time in Java 8
This is very similar to our first example of getting the current date in Java 8. This time, we will use a class called LocalTime, which is the time without date and a close cousin of LocalDate class. Here also you can use static factory method now() to get the current time. The default format is hh:mm:ss:nnn where nnn is nanoseconds. BTW, compare this how to get current time before Java 8.

LocalTime time = LocalTime.now();
System.out.println("local time now : " + time);

You can see that current time has no date attached to it because LocalTime is just time, no date.

7. How to add hours in time
In many occasions, we would like to add hours, minutes or seconds to calculate time in future. Java 8 has not only helped with Immutable and thread-safe classes but also provided better methods e.g. plusHours() instead of add(), there is no conflict. BTW, remember that these methods return a reference to new LocalTime instance because LocalTime is immutable, so don’t forget to store them back.

LocalTime time = LocalTime.now();
LocalTime newTime = time.plusHours(4);
System.out.println("Time after 4 hours : " + newTime);

Now, try to compare this with older ways of adding and subtracting hours from a date in Java. Let us know which one is better.

8. How to find Date after 1 week
This is similar to the previous example, there we learned how to find time after 2 hours and here we will learn how to find a date after 1 week. LocalDate is used to represent date without the time and it got a plus() method which is used to add days, weeks or months, ChronoUnit is used to specify that unit. Since LocalDate is also immutable any mutable operation will result in a new instance, so don’t forget to store it back.

        LocalDate today = LocalDate.now();
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        System.out.println("Today is : " + today); 
        System.out.println("Date after 1 week : " + nextWeek);

You can see that new date is 7 days away from the current date, which is equal to 1 week. You can use the same method to add 1 month, 1 year, 1 hour, 1 minute and even 1 decade, check out ChronoUnit class from Java 8 API for more options.

9. Date before and after 1 year
This is a continuation of the previous example. In the last example, we learn how to use plus() method of LocalDate to add days, weeks or months in a date, now we will learn how to use the minus() method to find what was the day before 1 year.

        LocalDate today = LocalDate.now();

        LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
        System.out.println("Date before 1 year : " + previousYear);

        LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
        System.out.println("Date after 1 year : " + nextYear);

10. Using Clock in Java 8
Java 8 comes with a Clock, which can be used to get current instant, date and time using time zone. You can use Clock in place of System.currentTimeInMillis() and TimeZone.getDefault().

// Returns the current time based on your system clock and set to UTC. Clock clock = Clock.systemUTC(); 
System.out.println("Clock : " + clock); 

// Returns time based on system clock zone Clock defaultClock = Clock.systemDefaultZone(); 
System.out.println("Clock : " + clock); 

Output: 
Clock : SystemClock[Z] 
Clock : SystemClock[Z]


//You can check given date against this clock, as shown below :

public class MyClass { 
    private Clock clock; // dependency inject ... 
    public void process(LocalDate eventDate) {
        if (eventDate.isBefore(LocalDate.now(clock)) { 
            ... 
        }
    }
}

This could be useful if you want to process dates on the different time zone.

11. How to see if a date is before or after another date in Java
This is another very common task in an actual project. How do you find if a given date is before, or after current date or just another date? In Java 8, LocalDate class has got methods like isBefore() and isAfter() which can be used to compare two dates in Java. isBefore() method return true if given date comes before the date on which this method is called.

        LocalDate today = LocalDate.now();
        LocalDate tomorrow = LocalDate.of(2016, 10, 16);

        if (tomorrow.isAfter(today)) {
            System.out.println("Tomorrow comes after today");
        }

        LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);
        if(yesterday.isBefore(today)){
            System.out.println("Yesterday is day before today");
        }

You can see that how easy it is to compare dates in Java 8. You don’t need to use another class like Calendar to perform such essential tasks.

12. Dealing with time zones in Java 8
Java 8 has not only separated date and time but also timezone. You now have a separate set of classes related to timezone e.g. ZonId to represent a particular timezone and ZonedDateTime class to represent a date time with timezone. It’s equivalent of GregorianCalendar class in pre-Java 8 world. By using this class, you can convert local time to equivalent time in another time zone as shown in the following example :

ZoneId america = ZoneId.of("America/New_York");
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime dateAndTimeInNewYork = ZonedDateTime.of(localDateTime, america);
System.out.println("Current date and time in a particular timezone : " + dateAndTimeInNewYork);

Compare this with the older way of converting local time to GMT. By the way, just like before Java 8, don’t forget to use the correct text for time zones, otherwise, you would be greeted with the following exception :

Exception in thread “main” java.time.zone.ZoneRulesException: Unknown time-zone ID: ASIA/Tokyo
at java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:272)
at java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:227)
at java.time.ZoneRegion.ofId(ZoneRegion.java:120)
at java.time.ZoneId.of(ZoneId.java:403)
at java.time.ZoneId.of(ZoneId.java:351)

13. How to represent fixed date e.g. credit card expiry, YearMonth
Like our MonthDay example for checking recurring events, YearMonth is another combination class to represent things like credit card expires, FD maturity date, Futures or options expiry dates etc. You can also use this class to find how many days are in the current month, lengthOfMonth() returns a number of days in the current YearMonth instance, useful for checking whether February has 28 or 29 days.

YearMonth currentYearMonth = YearMonth.now();
System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());

YearMonth creditCardExpiry = YearMonth.of(2017, Month.FEBRUARY);
System.out.printf("Your credit card expires on %s %n", creditCardExpiry);

14. How to check Leap Year in Java 8
Nothing fancy here, LocalDate class has isLeapYear() method which returns true if the year represented by that LocalDate is a leap year. If you still want to reinvent the wheel, check out this code sample, which contains a Java program to find if a given year is leap using pure logic.

LocalDate today = LocalDate.now();
if (today.isLeapYear()) {
    System.out.println("This year is Leap year");
} else {
    System.out.println("2014 is not a Leap year");
}

15. How many days, month between two dates
One of the common tasks is to calculate the number of days, weeks or months between two given dates. You can use java.time.Period class to calculate the number of days, month or year between two dates in Java. In the following example, we have calculated the number of months between the current date and a future date.

LocalDate today = LocalDate.now();
LocalDate java9Release = LocalDate.of(2017, 12, 18);
Period periodToNextJavaRelease = Period.between(today, java9Release);
System.out.println("Months left between today and Java 9 release : " + periodToNextJavaRelease.getYears());
System.out.println("Months left between today and Java 9 release : " + periodToNextJavaRelease.getMonths());
System.out.println("Months left between today and Java 9 release : " + periodToNextJavaRelease.getDays());

16. Date and Time with timezone offset
In Java 8, you can use ZoneOffset class to represent a time zone, for example, India is GMT or UTC +05:30 and to get a corresponding timezone you can use static method ZoneOffset.of() method. Once you get the offset you can create an OffSetDateTime by passing LocalDateTime and offset to it.

        LocalDateTime dateTime = LocalDateTime.of(2016, Month.OCTOBER, 15, 19, 30);
        ZoneOffset offset = ZoneOffset.of("+08:30");
        OffsetDateTime date = OffsetDateTime.of(dateTime, offset);
        System.out.println("Date and Time with timezone offset in Java : " + date);

You can see the timezone attached to date and time now. BTW, OffSetDateTime is meant for machines for human dates prefer ZoneDateTime class.

17. How to get current timestamp in Java 8
If you remember how to get current timestamp before Java 8 then this would be a breeze. Instant class has a static factory method now() which return current time stamp, as shown below :

        Instant timestamp = Instant.now();
        System.out.println("What is value of this instant " + timestamp);

You can see that current timestamp has both date and time component, much like java.util.Date, in fact, Instant is your equivalent class of pre-Java 8 Date and you can convert between Date and Instant using respective conversion method added in both of these classes e.g. Date.from(Instant) is used to convert Instant to java.util.Date in Java and Date.toInstant() returns an Instant equivalent of that Date class.

18. How to parse/format date in Java 8 using predefined formatting
Date and time formatting was very tricky in pre-Java 8 world, our only friend SimpleDateFormat was not threading safe and quite bulky to use as a local variable for formatting and parsing numerous date instances. Thankfully, thread local variables made it usable in multi-threaded environment but Java has come a long way from there.

It introduced a brand new date and time formatter which is thread-safe and easy to use. It now comes with some predefined formatter for common date patterns. For example, in this sample code, we are using predefined BASIC_ISO_DATE formatter, which uses the format 20140114 for January 14, 214.

String dayAfterTommorrow = "20161017";
LocalDate formatted = LocalDate.parse(dayAfterTommorrow, DateTimeFormatter.BASIC_ISO_DATE);
System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted);

19. How to parse date in Java using custom formatting
In the last example, we have used an inbuilt date and time formatter to parse date strings in Java. Sure, predefined formatters are great but there would be a time when you want to use your own custom date pattern and in that case, you have to create your own custom date time formatter instances as shown in this example. Following example has a date in format “MMM dd yyyy”.

You can create a DateTimeFormatter with any arbitrary pattern by using ofPattern() static method, it follows same literals to represent a pattern as before e.g. M is still a month and m is still a minute. An Invalid pattern will throw DateTimeParseException but a logically incorrect where you use m instead of M will not be caught.

        String goodFriday = "10 14 2016";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM dd yyyy");
        LocalDate holiday = LocalDate.parse(goodFriday, formatter);
        System.out.printf("Successfully parsed String %s, date is %s%n", goodFriday, holiday);

You can see that the value of Date is same as the String passed, just they are formatted differently.

20. How to convert Date to String in Java 8, formatting dates
In last two example, though we have been using DateTimeFormatter class but we are mainly parsing a formatted date String. In this example, we will do the exact opposite. Here we have a date, instance of LocalDateTime class and we will convert into a formatted date String. This is by far the simplest and easiest way to convert Date to String in Java.

The following example will return formatted String in place of Date. Similar to the previous example, we still need to create a DateTimeFormatter instance with given pattern but now instead of calling parse() method of LocalDate class, we will call format() method.

This method returns a String which represents a date in a pattern represented bypassed DateTimeFormatter instance.

        LocalDateTime arrivalDate = LocalDateTime.now();
        DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm a");
        String landing = arrivalDate.format(format);
        System.out.printf("Arriving at :  %s %n", landing);

You can see that current time is represented in given “MMM dd yyyy hh:mm a” pattern which includes three letter month representation followed by time with AM and PM literals.

From
http://javarevisited.blogspot.sg/2015/03/20-examples-of-date-and-time-api-from-Java8.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值