Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the first date and last date of current quarter in java.util.Date

Tags:

java

date

I need to get the first date of the current quarter as a java.util.Date object and the last date of the current quarter as a java.util.Date object.

I'm using following methods to get this month first date and this month last date.

private   Date getThisMonthFirstDate(){
    Calendar calendar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    return calendar.getTime();
}

private   Date getThisMonthLastDate(){
    Calendar calandar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH,1);
    calendar.add(Calendar.MONTH, 1);
    calendar.add(Calendar.DATE, -1);
   return calendar.getTime();
}

Is there a way to modify that function to achieve this or could anyone point out a better way?

Assume that Q1 = Jan Feb Mar, Q2 = Apr, May, Jun, etc.

like image 888
Asanka sanjaya Avatar asked Apr 08 '16 07:04

Asanka sanjaya


People also ask

How do I use util date?

Date. getTime() method results in count of milliseconds of the argumented date, referencing January 1, 1970, 00:00:00 GMT. Syntax: public long getTime() Result: milliseconds of the argumented date, referencing January 1, 1970, 00:00:00 GMT.

What is Java Util date return?

The java. util. Date class represents a particular moment in time, with millisecond precision since the 1st of January 1970 00:00:00 GMT (the epoch time). The class is used to keep coordinated universal time (UTC).


2 Answers

Pure Java-8+ solution:

LocalDate localDate = LocalDate.now();
LocalDate firstDayOfQuarter = localDate.with(localDate.getMonth().firstMonthOfQuarter())
    .with(TemporalAdjusters.firstDayOfMonth());

LocalDate lastDayOfQuarter = firstDayOfQuarter.plusMonths(2)
    .with(TemporalAdjusters.lastDayOfMonth());
like image 152
Pavel Avatar answered Nov 09 '22 18:11

Pavel


As others mentioned, you are using outmoded classes. Sun/Oracle decided to supplant the old date-time classes with the java.time framework, a vast improvement.

Avoid the old date-time classes. They really are poorly designed, confusing, and troublesome.

java.time

The java.time framework is built into Java 8. For Java 6 & 7, use the back-port, ThreeTen-Backport. For Android, the adaptation of that back-port, ThreeTenABP.

The java.time framework is inspired by the highly successful Joda-Time library, defined by JSR 310, and extended by the ThreeTen-Extra project. See Oracle Tutorial.

LocalDate

For a date-only value, without time-of-day and without time zone, use LocalDate built-in as part of java.time. To get the current date requires a time zone as the date varies around the world (a new day dawns earlier in the east).

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );

Quarter & YearQuarter

The ThreeTen-Extra project mentioned above serves as the proving ground for possible future features to be added to java.time. To use this library, add its jar file to your project (or use Maven etc.). If you really don’t want to add a library, see an alternate solution Answer by dheeran.

This library currently includes the Quarter and YearQuarter classes that you might find particularly useful. Safer to pass around objects of these types in your code rather than use strings and numbers to represent your quarters.

YearQuarter currentQuarter = YearQuarter.now ( zoneId );

The YearQuarter has many useful methods, including asking for its dates.

LocalDate start = currentQuarter.atDay ( 1 );
LocalDate stop = currentQuarter.atEndOfQuarter ();

Dump to console.

System.out.println ( "today: " + today + " currentQuarter: " + currentQuarter + " start: " + start + " stop: " + stop );

today: 2016-04-08 currentQuarter: 2016-Q2 start: 2016-04-01 stop: 2016-06-30

If you really do not want to add the ThreeTen-Extra library as I recommended, see the Answer by Pavel for another solution using only the built-in java.time classes. But if you are doing much work with quarters, I am sure you’ll find ThreeTen-Extra to be well worth the trouble of adding a library to your project.

Conversion

If you must use java.util.Date to work with old code not yet updated to java.time, you can convert back and forth. Find new methods added to the old classes for conversion.

Unfortunately, the old classes lack any clean way to represent a date-only value. So there is no perfectly clean way to go to/from a LocalDate.

java.sql.Date

The java.sql.Date class pretends to be a date-only but actually contains a time-of-day adjusted to 00:00:00.0. This class awkwardly inherits from java.util.Date but the doc clearly warns against using that fact; you are supposed to treat the two as separate unrelated classes.

java.sql.Date sqlDate_quarterStart = java.sql.Date.valueOf( start );

java.util.Date

A java.util.Date represents both a date and time-of-day, effectively in UTC. We can first adjust our LocalDate into the first moment of a day to get a date with time-of-day, a ZonedDateTime. From there we can ask for an Instant which is a moment on the timeline in UTC. The old .Date class has a static from( Instant ) conversion method.

ZonedDateTime zdt = start.atStartOfDay( zoneId ); // First moment of the day on a certain date.
Instant instant = zdt.toInstant(); // Moment on the timeline in UTC.
java.util.Date utilDate = java.util.Date.from( instant );

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 the java.time classes.

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

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, 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 Java SE 7
    • Much 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.

like image 27
Basil Bourque Avatar answered Nov 09 '22 17:11

Basil Bourque