Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to have a Java8 duration of one year that accounts for leap years?

I need the number of days in a year and I wanted to use Java8's new time api.

However, I can't do Duration.ofDays(365) because it doesn't account for leap years. And Duration.of(1, ChronoUnit.YEARS) doesn't fly because of java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration

I looked into Period, but it doesn't appear useful for going from years to days.

I feel like I'm missing something here? I could write something to add a day if the year is a leap year, but it seems like I should be able to handle this out of the box.

like image 289
user2272115 Avatar asked Apr 27 '15 15:04

user2272115


People also ask

How to determine a leap year Java?

Since Java 1.1, the GregorianCalendar class allows us to check if a year is a leap year: public boolean isLeapYear(int year); As we might expect, this method returns true if the given year is a leap year and false for non-leap years.

Which of the following Java SE code blocks will check for a leap year in a calendar?

The java. util. GregorianCalendar. isLeapYear() method determines if the given year passed as a parameter to the function is a leap year or not and returns true if the given year is a leap year and false otherwise.

How is duration defined in Java?

A Duration represents a directed distance between two points on the time-line. A negative duration is expressed by the negative sign of the seconds part. A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.

Can Java duration be negative?

A Duration represents a directed distance between two points on the time-line and can therefore be positive, zero or negative.


1 Answers

As per the response in Getting Duration using the new dateTime API you should be using

Period p = Period.ofYears(1); 

It's important to understand the difference between Duration (exact number of nanoseconds < 1 day) and Period (variable > 1 day).

Duration won't account for leap days, daylight savings time or leap seconds, for example, and is intended for durations of less than a day, at most a few days.

So you should use Period instead.

Because different years have different number of days, if you want to find the number of days in a year, you need to specify which year you're talking about.

If you want the number of days in a specific year, you can use

Year.of(year).length() 

If you want the date one year from now, you can use

LocalDate.now().plusYears(1) 

or

LocalDate.now().plus(Period.ofYears(1)) 

If you need the number of days between two dates, you can use

ChronoUnit.DAYS.between(start, end) 

So to find the number of days to the date a year from now, you can use

LocalDate today = LocalDate.now(); long days = ChronoUnit.DAYS.between(today, today.plusYears(1)); 

If you want to see whether a membership of one year is still valid, you can use

Period membershipLength = Period.ofYears(1); LocalDate membershipStart = ...; LocalDate membershipEnd = membershipStart.plus(membershipLength);  LocalDate today = LocalDate.now(); boolean memberShipEnded = today.isAfter(membershipEnd); boolean membershipValid = !membershipEnded; 
like image 102
Christoffer Hammarström Avatar answered Sep 23 '22 21:09

Christoffer Hammarström