AndreaNobili
AndreaNobili

Reputation: 42957

What is a smarter way to check if a Joda-Time DateTime object does not represent the last day of the year?

I am using Joda-Time and I would like to check if a specific date is not the last day of a year (in other words the date should not be 31/12/XXXX). It should work for any year.

To implement this check I have done something like this:

DateTime dataSecondoMovimento = new DateTime(mappaQuote.get(2).getDatariferimentoprezzo());

if(!(dataSecondoMovimento.getMonthOfYear() == 12 && dataSecondoMovimento.getDayOfMonth() == 31)) {
    System.out.println("It is not the end of year !!!");
}

So basically I am checking if the month is not December and if the day is not 31 (both have to be true for it not to be the last day of year). I think that this should work fine.

My question: does Joda-Time provide a neater way of doing this? Does there exist a method of checking if a specific date is the last day of the year?

Upvotes: 4

Views: 544

Answers (5)

Basil Bourque
Basil Bourque

Reputation: 338316

tl;dr

MonthDay.from( zdt ).equals( 
    MonthDay.of( 
        Month.DECEMBER , 
        Month.DECEMBER.maxLength() 
    )
)

java.time

The Joda-Time project is now in maintenance mode, and advises migrating to the java.time classes built into Java.

These include the MonthDay class to represent a day-of-month without year. We know the last day of year is always December 31. We make a constant for that value. To guard against silly mistakes, we ask for the length of the month rather than hard-code 31.

static final public MonthDay MONTHDAY_END_OF_YEAR = MonthDay.of( Month.DECEMBER , Month.DECEMBER.maxLength() );

The equivalent class to Joda-Time DateTime in java.time is ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

Ask for the MonthDay.

MonthDay md = MonthDay.from( zdt );

Compare to our constant.

Boolean isLastDay = md.equals( MONTHDAY_END_OF_YEAR );

TemporalAdjuster

By the way, there is a TemporalAdjuster for getting last day of the year: TemporalAdjusters.lastDayOfYear() (note the plural 's').

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtNow = ZonedDateTime.now( z );
ZonedDateTime zdtLastDayOfYear = zdtNow.with( TemporalAdjusters.lastDayOfYear() ) ;
MonthDay mdYearEnd = MonthDay.from( zdtLastDayOfYear );

Dump to console.

System.out.println( "zdtNow: " + zdtNow );
System.out.println( "zdtLastDayOfYear: " + zdtLastDayOfYear );
System.out.println( "mdYearEnd: " + mdYearEnd );

zdtNow: 2016-11-26T15:44:06.449-05:00[America/Montreal]

zdtLastDayOfYear: 2016-12-31T15:44:06.449-05:00[America/Montreal]

mdYearEnd: --12-31

See live code in IdeOne.com.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 2

David Rawson
David Rawson

Reputation: 21407

DateTime.Property

If you want some code that is close to the way you express the problem in natural language you could write a method where you access the DateTime.Property called dayOfYear to ask for the maximum value, meaning last day of the year.

private boolean isLastDayOfYear(DateTime dateTime) {
    return dateTime.dayOfYear().get() == dateTime.dayOfYear().getMaximumValue();
}

Then:

if (!isLastDayOfYear(dataSecondoMovimento)) {
    System.out.println("It is not the end of year !!!");
}

Upvotes: 3

Sergey Grinev
Sergey Grinev

Reputation: 34488

IMHO, your way is quite practical.

The only thing comes to my mind is

dataSecondoMovimento.plusDays(1).getDayOfYear() == 1

which is shorter but hardly more effective

P.S.: I've found a small benefit in this approach -- it will work for slightly improbable situation with non-Gregorian calendar which doesn't have 12 months or 31 days in the last one!

Upvotes: 4

Vinod Bokare
Vinod Bokare

Reputation: 86

Currently Joda Time don't have direct implementation of getLastDayOfYear(), we have to use logical way to handle the last day of year, one way you tried or you can use alternate way as below

 public int getDayOfYear() { //This is library method
    return getChronology().dayOfYear().get(getMillis());
}

if(!getDayOfYear() <=365 ||!getDayOfYear() <=366) { //Considering leap year
System.out.println("It is not the end of year !!!");
}

Upvotes: 0

Arnaud
Arnaud

Reputation: 17524

Another simple way would be to add one day to your date, then check if the year has changed :

DateTime dataSecondoMovimentoPlusOneDay = dataSecondoMovimento.plusDays(1);

boolean yearChanged = dataSecondoMovimento.getYear() != dataSecondoMovimentoPlusOneDay.getYear();

Upvotes: 2

Related Questions