Given a java.util.Date object how do I go about finding what Quarter it's in?
Assuming Q1 = Jan Feb Mar, Q2 = Apr, May, Jun, etc.
Given a java.util.Date object how do I go about finding what Quarter it's in?
Assuming Q1 = Jan Feb Mar, Q2 = Apr, May, Jun, etc.
Since Java 8, the quarter is accessible as a field using classes in the java.time package.
import java.time.LocalDate;
import java.time.temporal.IsoFields;
LocalDate myLocal = LocalDate.now();
int quarter = myLocal.get(IsoFields.QUARTER_OF_YEAR);
In older versions of Java, you could use:
import java.util.Date;
Date myDate = new Date();
int quarter = (myDate.getMonth() / 3) + 1;
Be warned, though that getMonth was deprecated early on:
As of JDK version 1.1, replaced by Calendar.get(Calendar.MONTH).
Instead you could use a Calendar
object like this:
import java.util.Calendar;
import java.util.GregorianCalendar;
Calendar myCal = new GregorianCalendar();
int quarter = (myCal.get(Calendar.MONTH) / 3) + 1;
In Java 8 and later, the java.time classes have a more simple version of it. Use LocalDate
and IsoFields
LocalDate.now().get(IsoFields.QUARTER_OF_YEAR)
You are going to have to write your own code because the term "Quarter" is different for each business. Can't you just do something like:
Calendar c = /* get from somewhere */
int month = c.get(Calendar.MONTH);
return (month >= Calendar.JANUARY && month <= Calendar.MARCH) ? "Q1" :
(month >= Calendar.APRIL && month <= Calendar.JUNE) ? "Q2" :
(month >= Calendar.JULY && month <= Calendar.SEPTEMBER) ? "Q3" :
"Q4";
Since quarters are a localized (Western) concept, specify a Locale rather than using the platform default:
Calendar cal = Calendar.getInstance(Locale.US);
/* Consider whether you need to set the calendar's timezone. */
cal.setTime(date);
int month = cal.get(Calendar.MONTH); /* 0 through 11 */
int quarter = (month / 3) + 1;
This will avoid getting the thirteenth month (Calendar.UNDECIMBER) on non-Western calendars, and any skew caused by their shorter months.
If you have
private static final int[] quarters = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
Then current quarter
is
private static final int thisQuarter = quarters[thisMonth];
Where thisMonth
is
private static final int thisMonth = cal.get(Calendar.MONTH);
YearQuarter
.from(
LocalDate.of( 2018 , 1 , 23 )
)
The Answer by abdmob is correct: Using java.time is the wise way to go.
In addition, the ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.
Its useful classes include:
To get the current quarter, specify a time zone. Determining a quarter means determining a date. And determining a date means specifying a time zone. For any given moment, the date varies around the globe by zone. Specify by using a proper time zone name in form of continent/region
. Never use the 3-4 letter abbreviations such as EST
or IST
.
ZoneId z = ZoneId.of( "America/Montreal" );
YearQuarter yq = YearQuarter.now( z );
java.util.Date
If given a java.util.Date
first convert to a java.time type. The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = myUtilDate.toInstant();
Assign a time zone to get a ZoneDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Generate a YearQuarter
from that ZonedDateTime
.
YearQuarter yq = YearQuarter.from( zdt );
You should be passing around instances of YearQuarter
rather than mere numbers or strings. Using objects provides type-safety, ensures valid values, and makes your code more self-documenting.
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?
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.
When using Joda time, use Math.ceil() function:
double quarter = Math.ceil(new Double(jodaDate.getMonthOfYear()) / 3.0);
int month = Calendar.getInstance().get( Calendar.MONTH ) + 1;
int quarter = month % 3 == 0? (month / 3): ( month / 3)+1;
Make sure that the thisMonth
is at least a float or a double, not an int:
String quarter = thisMonth/3 <= 1 ? "Q1" : thisMonth/3 <= 2 ? "Q2" : thisMonth/3 <= 3 ? "Q3" : "Q4";
Regards, MS
JFreeChart has a Quarter class. If you're curious, check out the javadoc. The source is also available from SourceForge if you want to check out the implementation.
Good solutions here, but remember that quarters can be subject to change depending on company/industry too. Sometimes a quarter can be a different 3 months.
You probably want to extend or encapsulate the calendar class to customize it to your tasks rather than write some utility function that converts it. Your application is probably complex enough in that area that you will find other uses for your new calendar class--I promise you'll be glad you extended or encapsulated it even if it seems silly now.
For Me, I Used this method for string representation:
int quarter = (Calendar.getInstance().get(Calendar.MONTH) / 3); // 0 to 3
String[] mQuarterKey = {"qt1", "qt2", "qt3", "qt4"};
String strQuarter = mQuarterKey[quarter];
with java8 you may use formatter:
import java.time.format.DateTimeFormatter
import java.time.LocalDate
println("withQuarter: " + LocalDate.of("2016".toInt,"07".toInt,1).format(DateTimeFormatter.ofPattern("yyyyQMM")))
withQuarter: 2016307
I use this method.
public static Integer getQuarter(Date d){
Calendar c = Calendar.getInstance();
c.setTime(d);
int month = c.get(Calendar.MONTH);
return (month /3)+1;
}