Find out Last 30 Days, 60 Days and 90 Days in java

tl;dr

LocalDate                       // Represent a date-only value, without time-of-day and without time zone.
.now(                           // Capture today's date as seen in the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "Asia/Tokyo" )   // Specify the desired/expected zone.
)                               // Returns a `LocalDate` object.
.minus(                         // Subtract a span-of-time.
    Period.ofDays( 30 )         // Represent a span-of-time unattached to the timeline in terms of years-months-days.
)                               // Returns another `LocalDate` object.

Avoid legacy date-time classes

The bundled java.util.Date & .Calendar group of classes are notoriously troublesome. Avoid them.

java.time

The modern approach uses the java.time classes built into Java 8 and later, and back-ported to Java 6 & 7.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

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.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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 ) ;

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety. Ditto for Year & YearMonth.

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Date math

You can define a span-of-time in terms of years-months-days with the Period class.

Period days_30 = Period.ofDays( 30 ) ;
Period days_60 = Period.ofDays( 60 ) ;
Period days_90 = Period.ofDays( 90 ) ;

You can add and subtract a Period to/from a LocalDate, resulting in another LocalDate object. Call the LocalDate::plus or LocalDate::minus methods.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate ago_30 = today.minus( days_30 ) ;
LocalDate ago_60 = today.minus( days_60 ) ;
LocalDate ago_90 = today.minus( days_90 ) ;

You more directly call LocalDate.minusDays, but I suspect the named Period objects will make your code more readable and self-documenting.

LocalDate ago = today.minusDays( 30 ) ;

JDBC

Sounds like you are querying a database. As of JDBC 4.2 and later, you can exchange java.time objects with your database. For a database column of a data type akin to the SQL-standard standard DATE (a date-only value, without time-of-day and without time zone), use LocalDate class in Java.

myPreparedStatement.setObject( … , ago_30 ) ;

Retrieval:

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

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.

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.


Joda-Time

UPDATE: The Joda-Time library is now in maintenance-mode. Its creator, Stephen Colebourne, went on to lead the JSR 310 and java.time implementation based on lessons learned with Joda-Time. I leave this section intact as history, but advise using java.time instead.

Here is some example code using the Joda-Time 2.3 library’s LocalDate class.

LocalDate now = LocalDate.now();
LocalDate thirty = now.minusDays( 30 );
LocalDate sixty = now.minusDays( 60 );
LocalDate ninety = now.minusDays( 90 );

Dump to console…

System.out.println( "now: " + now );
System.out.println( "thirty: " + thirty );
System.out.println( "sixty: " + sixty );
System.out.println( "ninety: " + ninety );

When run…

now: 2014-03-26
thirty: 2014-02-24
sixty: 2014-01-25
ninety: 2013-12-26

Time Zone

The beginning and ending of a day depends on your time zone. A new day dawns in Paris earlier than in Montréal.

By default, the LocalDate class uses your JVM's default time zone to determine the current date. Alternatively, you may pass a DateTimeZone object.

LocalDate localDate = new LocalDate( DateTimeZone.forID( "Europe/Paris" ) );

Use java.util.Calendar.

Date today = new Date();
Calendar cal = new GregorianCalendar();
cal.setTime(today);
cal.add(Calendar.DAY_OF_MONTH, -30);
Date today30 = cal.getTime();
cal.add(Calendar.DAY_OF_MONTH, -60);
Date today60 = cal.getTime();
cal.add(Calendar.DAY_OF_MONTH, -90);
Date today90 = cal.getTime();

If you put 1 in xdaysago it means 1 day ago 30 means 30 days ago, you can look your zone id in ZoneId class.

 public static String getDate(int xdaysago){
        LocalDate localDate = LocalDate.now(ZoneId.of( "Asia/Karachi" )).minus( Period.ofDays( xdaysago ));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return localDate.format(formatter);
    }

Tags:

Java

Date