How to check whether the given date is earlier than a month ago? What is the fastest algorithm? I have to take into account that different months have different numbers of days.
Updated to Java 8
The class LocalDate class can be used:
LocalDate aDate = LocalDate.parse("2017-01-01");
return aDate.isBefore( LocalDate.now().minusMonths(1));
For previous versions, the Calendar class would work.
Calendar calendar = Calendar.getInstance();
calendar.add( Calendar.MONTH , -1 );
return aDate.compareTo( calendar.getTime() ) < 0;
Sample code:
import static java.lang.System.out;
import java.time.LocalDate;
public class Sample {
public static void main( String [] args ) {
LocalDate aMonthAgo = LocalDate.now().minusMonths(1);
out.println( LocalDate.parse("2009-12-16").isBefore(aMonthAgo));
out.println( LocalDate.now().isBefore(aMonthAgo));
out.println( LocalDate.parse("2017-12-24").isBefore(aMonthAgo));
}
}
Prints
true
false
false
Using Joda Time:
DateTime dt1 = new DateTime(); //Now
DateTime dt2 = new DateTime(2009,9,1,0,0,0,0); //Other date
if (dt1.plusMonths(-1) > dt2) {
//Date is earlier than a month ago
}
LocalDate.now( ZoneId.of( "America/Montreal" )
.minusMonths( 1 )
.isAfter( LocalDate.parse( "2017-01-23" ) )
The modern approach uses the java.time classes rather than the troublesome legacy classes such as Date
& Calendar
.
First get the current date. The LocalDate
class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
Next, determine the date a month ago.
LocalDate monthAgo = today.minusMonths( 1 ) ;
Here are the rules used by LocalDate::minusMonths
, quoted from Java 8 class doc:
This method subtracts the specified amount from the months field in three steps:
Subtract the input months from the month-of-year field
Check if the resulting date would be invalid
Adjust the day-of-month to the last valid day if necessary
For example, 2007-03-31 minus one month would result in the invalid date 2007-02-31. Instead of returning an invalid result, the last valid day of the month, 2007-02-28, is selected instead.
Or, perhaps in your business rules you meant "30 days" instead of a calendar month.
LocalDate thirtyDaysAgo = today.minusDays( 30 ) ;
You are given a date. That should be passed to your code as a LocalDate
object.
LocalDate ld = LocalDate.of( 2017 , Month.JANUARY , 23 ) ;
If coming from a String, use the standard ISO 8601 formats. For other formats, search Stack Overflow for DateTimeFormatter
class.
LocalDate ld = LocalDate.parse( "2017-01-23" ) ;
Now compare. Call the isBefore
, isEqual
, isAfter
methods.
Boolean outdated = ld.isBefore( monthAgo ) ;
As for the issue of performance raised in the Question: Don't worry about it. This month-ago calculation and comparison is very unlikely to be a bottleneck in your app. Avoid premature optimization.
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 the java.time classes.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With