Get current quarter in year with javascript

71,168

Solution 1

Given that you haven't provided any criteria for how to determine what quarter "*we are currently in", an algorithm can be suggested that you must then adapt to whatever criteria you need. e.g.

// For the US Government fiscal year
// Oct-Dec = 1
// Jan-Mar = 2
// Apr-Jun = 3
// Jul-Sep = 4
function getQuarter(d) {
  d = d || new Date();
  var m = Math.floor(d.getMonth()/3) + 2;
  return m > 4? m - 4 : m;
}

As a runnable snippet and including the year:

function getQuarter(d) {
  d = d || new Date();
  var m = Math.floor(d.getMonth() / 3) + 2;
  m -= m > 4 ? 4 : 0;
  var y = d.getFullYear() + (m == 1? 1 : 0);
  return [y,m];
}

console.log(`The current US fiscal quarter is ${getQuarter().join('Q')}`);
console.log(`1 July 2018 is ${getQuarter(new Date(2018,6,1)).join('Q')}`);

You can then adapt that to the various financial or calendar quarters as appropriate. You can also do:

function getQuarter(d) {
  d = d || new Date(); // If no date supplied, use today
  var q = [4,1,2,3];
  return q[Math.floor(d.getMonth() / 3)];
}

Then use different q arrays depending on the definition of quarter required.

Edit

The following gets the days remaining in a quarter if they start on 1 Jan, Apr, Jul and Oct, It's tested in various browsers, including IE 6 (though since it uses basic ECMAScript it should work everywhere):

function daysLeftInQuarter(d) {
  d = d || new Date();
  var qEnd = new Date(d);
  qEnd.setMonth(qEnd.getMonth() + 3 - qEnd.getMonth() % 3, 0);
  return Math.floor((qEnd - d) / 8.64e7);
}

Solution 2

Assuming January through March are considered Q1 (some countries/companies separate their financial year from their calendar year), the following code should work:

var today = new Date();
var quarter = Math.floor((today.getMonth() + 3) / 3);

This gives you:

Month      getMonth()  quarter
---------  ----------  -------
January         0         1
February        1         1
March           2         1
April           3         2
May             4         2
June            5         2
July            6         3
August          7         3
September       8         3
October         9         4
November       10         4
December       11         4

As to how to get the days remaining in the quarter, it's basically figuring out the first day of the next quarter and working out the difference, something like:

var today = new Date();
var quarter = Math.floor((today.getMonth() + 3) / 3);
var nextq;
if (quarter == 4) {
    nextq = new Date (today.getFullYear() + 1, 1, 1);
} else {
    nextq = new Date (today.getFullYear(), quarter * 3, 1);
}
var millis1 = today.getTime();
var millis2 = nextq.getTime();
var daydiff = (millis2 - millis1) / 1000 / 60 / 60 / 24;

That's untested but the theory is sound. Basically create a date corresponding to the next quarter, convert it and today into milliseconds since the start of the epoch, then the difference is the number of milliseconds.

Divide that by the number of milliseconds in a day and you have the difference in days.

That gives you (at least roughly) number of days left in the quarter. You may need to fine-tune it to ensure all times are set to the same value (00:00:00) so that the difference is in exact days.

It may also be off by one, depending on your actual definition of "days left in the quarter".

But it should be a good starting point.

Solution 3

if the first solution doesn't work than you can just adjust it to the range you would like

var today = new Date();
var month = now.getMonth();
var quarter;
if (month < 4)
  quarter = 1;
else if (month < 7)
  quarter = 2;
else if (month < 10)
  quarter = 3;
else if (month < 13)
  quarter = 4;

Solution 4

function getQuarter(d) {
  return Math.floor(d.getMonth()/3) + 1);
}

EDIT: i left out %4, totally right, thanks Clement

Solution 5

You can use moment package:

Answer of your question using moment package is:

moment().quarter()

Below are the start and end dates of a quarter using the moment package:

START DATE OF QUARTER

moment().quarter(moment().quarter()).startOf('quarter');

Would return the current quarter with the date set to the quarter starting date.

moment("2019", "YYYY").quarter(4).startOf('quarter');

Would return the starting date of the 4th quarter of the year "2019".

moment().startOf('quarter');

Would return the starting date of the current quarter of current year.

END DATE OF QUARTER

moment().quarter(moment().quarter()).endOf('quarter');

Would return the current quarter with the date set to quarter ending date.

moment("2019", "YYYY").quarter(4).endOf('quarter');

Would return the ending date of the 4th quarter of the year "2019".

moment().endOf('quarter');

Would return the ending date of the current quarter of current year.

Share:
71,168
John Doe
Author by

John Doe

Updated on May 26, 2021

Comments

  • John Doe
    John Doe almost 3 years

    How can I get the current quarter we are in with javascript? I am trying to detect what quarter we are currently in, e.g. 2.

    EDIT And how can I count the number of days left in the quarter?

  • RobG
    RobG over 11 years
    Given that the OP thinks August is in Q2, it is unlikely January to March is Q1. A hard coded solution works though.
  • paxdiablo
    paxdiablo over 11 years
    @Rob, I saw the example 2 as just being a quarter we could be in. I don't think the OP is stating that it corresponds to the current month when this question was asked (August).
  • RobG
    RobG over 11 years
    $NaN? I have no idea how you get that, the code above is tested in Firefox and IE 9, it's plain ECMAScript so has nothing to do with jQuery. All of it should work in nearly every browser that ever supported javascript, certainly everything since and including IE and NN 4.
  • John Doe
    John Doe over 11 years
    yeah yeah it's cool it was an issue with ie 6, and sadly the client I'm building this for can't "upgrade" to like chrome or something.
  • John Doe
    John Doe over 11 years
    Your daysleftInquarter example isn't correct, it keeps returning 60 when I pass the current month
  • lee_mcmullen
    lee_mcmullen over 10 years
    Surely you need a Math.floor around your result to get the quarter? Also there is no variable called "now", I guess you meant to use "today" instead?
  • paxdiablo
    paxdiablo over 10 years
    @lee_mcmullen, hence the "untested" comment :-) Congrats on being the first person to pick up the today/now error in over a year, have fixed both issues based on your suggestions.
  • SivaRajini
    SivaRajini about 10 years
    @paxdiablo thanks it helped me . do you know how to calcualte FYTD and CYTD same like above ? stackoverflow.com/questions/22909656/…
  • Tony Gutierrez
    Tony Gutierrez over 9 years
    Your very first code block returns 0 for a date in Dec due to getMonth being a 0 based index.
  • RobG
    RobG over 9 years
    @TonyGutierrez—Thanks, error is due to my bad Mathematics, it should have been m - 4 not m - 5.
  • Steve Seeger
    Steve Seeger over 5 years
    Original answer did not account for dates in North America where one is in Daylight savings and the other is not. Thanks!
  • paxdiablo
    paxdiablo over 5 years
    @SteveSeeger, not sure what you're talking about there, the quarter is dictated by month alone. Daylight savings doesn't seem to be the least bit relevant here, you're either in a month or not. Perhaps you could explain further?
  • Steve Seeger
    Steve Seeger over 5 years
    @paxdiablo I added an edit which accounts for daylight savings. This refers to the second part of the answer, days remaining in the quarter. I used this in production but had to account for DST. This is because today and nextq dates can have time zone vales that differ by one hour. In this case, daydiff will not be an integer and be off by one hour eg 1\24th.
  • paxdiablo
    paxdiablo over 5 years
    Steve: Ah, that makes sense now. Let me have a look at it, not sure why the swarm rejected it if it was valid.
  • aruno
    aruno over 5 years
    so where does year come into this? surely Q1 of 2018 doesn't come after Q3 of 2018!
  • RobG
    RobG over 5 years
    @Simon_Weaver—added a runnable snippet with year.
  • aruno
    aruno over 5 years
    @RobG thanks but what I meant was the function could return a tuple { quarter, year } where for Q1 the year is actually calendarDate.Year + 1 since it belongs to the next year. If people don’t do that and sort the data they’ll get a huge mess!
  • RobG
    RobG over 5 years
    @Simon_Weaver—the new function returns [y,m]. ;-) Formatting of the actual expression is up to the user, if sortability is required then year/quarter suits. My preference is 2019Q1, which is quite ISO-ish, so probably why the US seem to prefer something else, like Q1'19 or Q1/19 or similar that will not sort lexically. :-(
  • Mayer Spitz
    Mayer Spitz about 5 years
    Just what I'm looking for, as I wanted to have the actual Quarter, not the US fiscal year. Thanks!
  • Cédric Guillemette
    Cédric Guillemette almost 5 years
    Since the month is zero-based, you'll need to add 1 for this to work properly. [0,1,2,3,4,5,6,7,9,10,11].map(month => Math.ceil(month/3)) === [0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4]
  • Cédric Guillemette
    Cédric Guillemette almost 5 years
    Since month is zero-based, 4/7/10/13 should be 3/6/9/12
  • Clement
    Clement about 3 years
    % 4 is not needed
  • Disorder
    Disorder almost 2 years
    omg, why so difficult? Why do you all use floor and add 1, when you can simply use ceil? return Math.ceil((d.getMonth() + 1) / 3)