0

I am able to get the last quarter value from the below code:

Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int presentQuarter = (month / 3) + 1;
int lastQuarter = (presentQuarter - 1) > 0 ? presentQuarter - 1 : 4;

But how can I get the last date of the last quarter? (i.e 2017-06-30 which is the last date of the last quarter).

Alex Man
  • 4,746
  • 17
  • 93
  • 178
  • 1
    Do you *have* to use `java.util.Date` and `java.util.Calendar`? If you can use `java.time.*` your code will be *much* nicer. – Jon Skeet Jul 21 '17 at 11:16
  • @JonSkeet Can you give some sample example – Alex Man Jul 21 '17 at 11:20
  • 1
    @AlexMan give an example of your desired output. For example you now get 3 for presentQuarter and 2 for the lastQuarter. What do you expect the present and last quarter date to be ? as from my point of view quarters are represented by several month so what type of a date you need. – Ahmad Sanie Jul 21 '17 at 11:26
  • @AhmadAlsanie I want the last day of the last quarter, i.e `2017-06-30` – Alex Man Jul 21 '17 at 11:28
  • 1
    I'm not going to start writing code when I don't know whether you'll be able to use it or not - that's why I asked whether you can use `java.time.*` (from Java 8). That's what I'd normally *want* to write the answer in. – Jon Skeet Jul 21 '17 at 11:35
  • @AlexMan Man since the end of quarters are set of constants, and i don't really now if those dates are added to java 8 date and time API that Jon talked about above. Here is my suggestion, you can use java 8 date and time LocalDate date2 = LocalDate.now(); System.out.println(date2.get(IsoFields.QUARTER_OF_YEAR)); to get current quarter and then do a switch on a set of of enums that returns a LocalDate object when calling a getDate method on them. Sounds compilcated but it is really simple, let me know if you didn't get it, I'll write the code and attach it as an answer – Ahmad Sanie Jul 21 '17 at 11:42
  • ohh okay you are using Java 7 as i read bellow, that sucks tbh. would you consider adding joda time. its easier and it helps you when upgrading to 8. I'm not saying that it can't be done with 7 it can using the same strategy above. – Ahmad Sanie Jul 21 '17 at 11:45
  • @AhmadAlsanie How can we get it using jdk 7 – Alex Man Jul 21 '17 at 11:46
  • Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in [joda's website](http://www.joda.org/joda-time) it says: **"Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310)."**. In JDK7 you can use the [ThreeTen Backport](http://www.threeten.org/threetenbp/) instead - check my answer below. –  Jul 21 '17 at 11:58

3 Answers3

4

You should go for the java.time API of JDK 8 and try out the ThreeTen-Extra project, to get the desired result as it simplifies these scenarios to a great extent. I suppose you need to work with just date, so you can get the current date as below:

ZoneId zone = ZoneId.systemDefault();
LocalDate today = LocalDate.now (zone);

Then, you can utilize the YearQuarter class of the ThreeTen-Extra project to get the current and last quarter as below:

YearQuarter lastQuarter = YearQuarter.now (zone).minusQuarters(1);
LocalDate lastDayOfLastQuarter = lastQuarter.atEndOfQuarter ();

Disclaimer: I haven't tested the code, it is just to give you an idea of ease with which date-time calculations can be done using these API.

Update: This is in response to your comment that you are using JDK 7, I advise to upgrade to JDK 8 if possible to take advantage of all the new features that have come with it. In case you are not able to do that, you can use the back-port of the java.time for JDK 6 and 7, the ThreeTen-Backport. But in that case you would not be able to make use of the YearQuarter class of the ThreeTen-Extra project as pointed out by Basil Bourque in his comment to this post. Hugo's answer already shows the how-to using only ThreeTen-Backport.

Pallavi Sonal
  • 3,661
  • 1
  • 15
  • 19
  • I am using JDK1.7 – Alex Man Jul 21 '17 at 11:39
  • 2
    ThreeTen-Extra cannot be used with ThreeTen-Backport, only with the java.time classes built into Java 8 and later. But the `YearQuarter` class is good to know about for those people using current versions of Java. – Basil Bourque Jul 21 '17 at 18:11
  • Thanks @Basil Bourque for pointing that out. The initial answer was written with JDK 8 in mind, so the suggestion to use `YearQuarter`. – Pallavi Sonal Jul 22 '17 at 07:17
3

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

All relevant classes are in the org.threeten.bp package.

As you seem to care only about the date (day/month/year), I'm using org.threeten.bp.LocalDate class. I also use the org.threeten.bp.temporal.IsoFields class, which has fields that can properly deal with quarters:

// get today's date
LocalDate today = LocalDate.now();
// get previous quarter
LocalDate previousQuarter = today.minus(1, IsoFields.QUARTER_YEARS);
// get last day in previous quarter
long lastDayOfQuarter = IsoFields.DAY_OF_QUARTER.rangeRefinedBy(previousQuarter).getMaximum();

// get the date corresponding to the last day of quarter
LocalDate lastDayInPreviousQuarter = previousQuarter.with(IsoFields.DAY_OF_QUARTER, lastDayOfQuarter);

The lastDayInPreviousQuarter will be 2017-06-30.


The code above gets the current date in your system's default timezone, but if you want a more reliable code, you can tell the API to explicity uses one specific timezone, using the org.threeten.bp.ZoneId class. In this example, I'm using mine (America/Sao_Paulo), but you can change to the one that fits best to your system:

// get today's date in a specific timezone
ZoneId zone = ZoneId.of("America/Sao_Paulo");
LocalDate today = LocalDate.now(zone);

The API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.

You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().

It's preferred to use an explicit timezone because the system's default can be changed without notice, even at runtime.


If you also need other fields (like hour, minutes, seconds, and so on), check this tutorial that explains all the new types. The tutorial is for Java 8, but the ThreeTen Backport has all the same classes and methods (just the package name is different: in Java 8 is java.time and in ThreeTen Backport is org.threeten.bp).

0

Try this one. This should not require any extra packages except those in standard jdk package.

Date date = new Date();
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int presentQuarter = (month / 3) + 1;

int lastQuarter = 0;

if(presentQuarter - 1 > 0){
  lastQuarter = presentQuarter - 1;
}else{
  lastQuarter = 4;
  year--;
}

month = lastQuarter * 3 - 1;
cal.set(year, month, 1);
int day = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(year, month, day);
System.out.println(cal.getTime());
Alexey R.
  • 8,057
  • 2
  • 11
  • 27
  • 2
    I believe it’s correct, and it’s certainly correct that it does not require any extra to Java 7. On the other hand, it’s a lot more code, and trickier and harder to read. I should still recommend you give ThreeTen Backport a consideration as in the other answers. You will only need it temporarily until you upgrade to Java 8 or 9 anyway. – Ole V.V. Jul 21 '17 at 13:49
  • 2
    Better to use the modern java.time classes rather than the troublesome old legacy classes shown here. Instead, see the [correct Answer by Hugo using the *ThreeTen-Backport* project](https://stackoverflow.com/a/45237009/642706). – Basil Bourque Jul 21 '17 at 18:13
  • I agree completely, of course, @BasilBourque, but if the OP has any chance to upgrade to Java 8, [Pallavi Sonal’s answer](https://stackoverflow.com/a/45236678/5772882) is gold too (watch that user, her answers are very good). – Ole V.V. Jul 21 '17 at 19:49