Inconsistent Javascript Dates - javascript

So I know this has been discussed as a problem before, but I'm looking more for some useful input really. I'm writing a calendar, and needed to add dates, and I came across an earlier thread (Add days to JavaScript Date), but it raised more quetions than answers. So I went away to code my own, and I'm close. This is what I've got:
Date.prototype.add = function(period, value, ignoreDaylightSaving)
{
var Day = this.getDate();
var Month = this.getMonth();
var Year = this.getFullYear();
var Hours = this.getHours();
var Mins = this.getMinutes();
var Secs = this.getSeconds();
var MilliSecs = this.getMilliseconds();
var TestDate;
var IgnoreDS = false;
var TZOffset1 = 0;
var TZOffset2 = 0;
if (typeof(ignoreDaylightSaving) == "boolen")
{
IgnoreDS = ignoreDaylightSaving;
}
switch (period.toUpperCase())
{
case "D":
Day += value;
break;
case "M":
Month += value;
break;
case "Y":
Year += value;
break;
case "H":
Hours += value;
break;
case "N":
Mins += value;
break;
case "S":
Secs += value;
break;
case "MS":
MilliSecs += value;
}
// Standardise Daylight Saving cut off.
if (IgnoreDS == false)
{
TestDate = new Date(Year, Month, Day, Hours, Mins, Secs, MilliSecs);
TZOffset1 = this.getTimezoneOffset();
TZOffset2 = TestDate.getTimezoneOffset();
if (value > 0)
{
if (this > TestDate)
{
if (TZOffset1 == TZOffset2)
{
Hours += 1;
}
}
} else {
if (this < TestDate)
{
if (TZOffset1 == TZOffset2)
{
Hours -= 1;
}
}
}
}
return(new Date(Year, Month, Day, Hours, Mins, Secs, MilliSecs));
}
It relies on Javascript to do the calcs for me. Internally, Dates and Times are just numbers, so if you pass a set of values, whether they are in range or not, javascript just multiplies them all out to get the internal number. Only when you apply Date functions to that number will it be converted into a date we recognise.
So my logic:
* split down the Date into its components
* add the value you want to one of the components
* create a new date from the components.
I've tested it with leap years IE and Chrome.
Daylight Saving is another matter. In the UK, British Summer Time begins 1am 30 March 2014. If I set a date of 30 March 2014 00:59:00 and add 2 minutes, Chrome gives me '30 March 2014 00:01:00' (GMT Standard Time), but IE gives me '30 March 2014 02:01:00' (GMT Summer Time).
Both browsers effectively say "you can't have a time of 01:01 in the morning of 30 March 2014 as it doesn't exist". IE advances to the next time (in effect adjusting the clock), whereas Chrome simply knocks you back an hour and keeps you in GMT Standard Time. When Summer Time ends they do it the opposite way round - IE keeps you in Summer Time and Chrome adjusts the clock for you. I've coded around this for going from GMT Standard to GMT Summertime (see the block under Standardise Daylight Saving cut off comment).
It's hard to code around the inconsistency in moving from GMT Summertime to GMT Standard though. I even wrote some javascript to find the change over dates by going through each month, then day then hour. But IE gives a different hour to Chrome. The code:
Date.prototype.getDaylightSavingDate = function(year)
{
var DSStart = new Date();
var DSEnd = new Date();
var MonthLoop;
var d1 = new Date();
var d2 = new Date();
var ThreshholdTZOffsets = new Array();
var ThreshholdMonths = new Array();
var ThreshholdDays = new Array();
var ThreshholdHours = new Array();
var ThisTZOffset;
var PrevTZOffset;
var THCount;
THCount = 0;
for (DateLoop=0; DateLoop < 12; DateLoop++)
{
d1 = new Date(year, DateLoop, 1);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, DateLoop-1, 1)
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdMonths[THCount] = DateLoop-1;
ThreshholdTZOffsets[THCount] = ThisTZOffset;
THCount += 1;
}
PrevTZOffset = ThisTZOffset
}
for (DateLoop=0; DateLoop<ThreshholdMonths.length; DateLoop++)
{
for (DayLoop=1; DayLoop < 32; DayLoop++)
{
d1 = new Date(year, ThreshholdMonths[DateLoop], DayLoop);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, ThreshholdMonths[DateLoop], DayLoop-1);
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdDays[DateLoop] = DayLoop-1;
}
PrevTZOffset = ThisTZOffset
}
}
for (DateLoop=0; DateLoop<ThreshholdMonths.length; DateLoop++)
{
for (HourLoop=0; HourLoop < 23; HourLoop++)
{
d1 = new Date(year, ThreshholdMonths[DateLoop], ThreshholdDays[DateLoop], HourLoop, 0, 0);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, ThreshholdMonths[DateLoop], ThreshholdDays[DateLoop], HourLoop-1, 0, 0);
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdHours[DateLoop] = HourLoop;
}
PrevTZOffset = ThisTZOffset
}
}
if (ThreshholdHours.length == 2)
{
DSStart = new Date(year, ThreshholdMonths[0], ThreshholdDays[0], ThreshholdHours[0],0,0,0);
DSEnd = new Date(year, ThreshholdMonths[1], ThreshholdDays[1], ThreshholdHours[1],0,0,0);
return({start:DSStart,end:DSEnd})
}
}
If you call this routine in IE and debug it ThreshholdDays[0]=1, and ThreshholdDays[1]=2. In Chrome however it's the other way round: ThreshholdDays[0]=2, and ThreshholdDays[1]=1.
My HTML for calling the routines:
<!DOCTYPE HTML>
<html dir="ltr" lang="en-gb" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Dates</title>
<script language="javascript" type="text/javascript" src="LIBS/general.js"></script>
</head>
<body>
<div>
<script language="javascript" type="text/javascript">
var d1 = new Date(2014, 9, 26, 2,1,0);
var d2 = d1.add("n", -2, true);
var ds1 = d1.getDaylightSavingDate(2014);
alert(ds1.start + ", " + ds1.end);
alert(d1 + ", " + d2 + ", " + (d2-d1));
</script>
</div>
</body>
</html>
Anybody think of another way of doing this without explicitly coding for each browser?

If you compare the local timezone offsets for a date in June with a date in January you can tell if DST applies.
South of the equator, where DST is used, January is always in DST, north of the equator, June is always in DST.
You can find the month, day, hour and minute that DST and standard time start by advancing the Date object through months, days, hours and minutes in turn, checking the difference in timezone offsets.
It is a busy function, but needs only be done once for any year in a calendar app.
The function getDST returns an Array with a Date object representing the first minute of standard time for the given year,
the first minute of DST for that year, and the offset difference in minutes.
(The second function returns the date and a message to appear on that date in a calendar)
The best way to test this kind of function is to change the timezone in your computer for as many timezones as you can stand, with use dst enabled.
function getDST(y){
y= y || new Date().getFullYear();
var D1= new Date(y, 0, 1), D2= new Date(y, 5, 1),
off1= D1.getTimezoneOffset(), off2= D2.getTimezoneOffset(),
diff= off2-off1;
if(diff=== 0) return ;
var stdTime= D1, dstTime= D2,
std1= 11, dst1= 5,
stdOffset= off1, dstOffset= off2,
isDst, isStd, one= 1;
if(diff>0){
diff*= -1;
stdOffset= off2;
dstOffset= off1;
std1= 5;
dst1= 11;
}
function isDst(D){
return D.getTimezoneOffset()=== dstOffset;
}
function isStd(D){
return D.getTimezoneOffset()=== stdOffset;
}
function edgeTz(D, m, check){
D.setMonth(m);
while(check(D)) D.setMonth(m--);
D.setMonth(D.getMonth()+1);
while(check(D)) D.setDate(D.getDate()-1);
one= 1;
while(!check(D)) D.setHours(one++);
D.setHours(D.getHours()-1);
one= 1;
while(!check(D)) D.setMinutes(one++);
return D;
}
stdTime= edgeTz(stdTime, std1, isStd);
dstTime= edgeTz(dstTime, dst1, isDst);
return [stdTime, dstTime, diff];
}
// local start time for standard and dst:
getDST(2014).join('\n');
//result for EST
Sun Nov 02 2014 02: 00: 00 GMT-0500(Eastern Daylight Time)
Sun Mar 09 2014 03: 00: 00 GMT-0400(Eastern Standard Time)
-60
//calendar note:
function tzReport(y){
var z= getDST(y);
var dstMsg, stdMsg, changeStd, changeDst,
stdTime= z[0], dstTime= z[1], diff= z[2];
changeStd= new Date(stdTime);
changeStd.setDate(changeStd.getDate()+1);
changeStd.setMinutes(changeStd.getMinutes()-diff);
stdMsg= 'Standard Time begins. At '+
changeStd.timeString()+', clocks return to '+stdTime.timeString()+'.';
changeDst= new Date(dstTime);
changeDst.setDate(changeDst.getDate()+1);
changeDst.setMinutes(changeDst.getMinutes()+diff);
dstMsg= 'DST begins. At '+changeDst.timeString()+
', clocks advance to '+dstTime.timeString()+'.';
return [[stdTime.toLocaleDateString(), stdMsg],
[dstTime.toLocaleDateString(), dstMsg]];
}
//Calendar notice: tzReport(2014).join('\n');
Sunday, November 02, 2014,
Standard Time begins.
At 3: 00 am, clocks return to 2: 00 am.
Sunday, March 09, 2014, DST begins.
At 2: 00 am, clocks advance to 3: 00 am.

Related

End of Month using javascript [duplicate]

If you provide 0 as the dayValue in Date.setFullYear you get the last day of the previous month:
d = new Date(); d.setFullYear(2008, 11, 0); // Sun Nov 30 2008
There is reference to this behaviour at mozilla. Is this a reliable cross-browser feature or should I look at alternative methods?
var month = 0; // January
var d = new Date(2008, month + 1, 0);
console.log(d.toString()); // last day in January
IE 6: Thu Jan 31 00:00:00 CST 2008
IE 7: Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2: Thu Jan 31 00:00:00 CST 2008
Opera 8.54: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60: Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Output differences are due to differences in the toString() implementation, not because the dates are different.
Of course, just because the browsers identified above use 0 as the last day of the previous month does not mean they will continue to do so, or that browsers not listed will do so, but it lends credibility to the belief that it should work the same way in every browser.
I find this to be the best solution for me. Let the Date object calculate it for you.
var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);
Setting day parameter to 0 means one day less than first day of the month which is last day of the previous month.
I would use an intermediate date with the first day of the next month, and return the date from the previous day:
int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);
In computer terms, new Date() and regular expression solutions are slow! If you want a super-fast (and super-cryptic) one-liner, try this one (assuming m is in Jan=1 format). I keep trying different code changes to get the best performance.
My current fastest version:
After looking at this related question Leap year check using bitwise operators (amazing speed) and discovering what the 25 & 15 magic number represented, I have come up with this optimized hybrid of answers (note the parameters m & y must obviously be integers for this to work):
function getDaysInMonth(m, y) {
return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}
Given the bit-shifting this obviously assumes that your m & y parameters are both integers, as passing numbers as strings would result in weird results.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/H89X3/22/
JSPerf results: http://jsperf.com/days-in-month-head-to-head/5
For some reason, (m+(m>>3)&1) is more efficient than (5546>>m&1) on almost all browsers.
The only real competition for speed is from #GitaarLab, so I have created a head-to-head JSPerf for us to test on: http://jsperf.com/days-in-month-head-to-head/5
It works based on my leap year answer here: javascript to find leap year this answer here Leap year check using bitwise operators (amazing speed) as well as the following binary logic.
A quick lesson in binary months:
If you interpret the index of the desired months (Jan = 1) in binary you will notice that months with 31 days either have bit 3 clear and bit 0 set, or bit 3 set and bit 0 clear.
Jan = 1 = 0001 : 31 days
Feb = 2 = 0010
Mar = 3 = 0011 : 31 days
Apr = 4 = 0100
May = 5 = 0101 : 31 days
Jun = 6 = 0110
Jul = 7 = 0111 : 31 days
Aug = 8 = 1000 : 31 days
Sep = 9 = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days
That means you can shift the value 3 places with >> 3, XOR the bits with the original ^ m and see if the result is 1 or 0 in bit position 0 using & 1. Note: It turns out + is slightly faster than XOR (^) and (m >> 3) + m gives the same result in bit 0.
JSPerf results: http://jsperf.com/days-in-month-perf-test/6
My colleague stumbled upon the following which may be an easier solution
function daysInMonth(iMonth, iYear)
{
return 32 - new Date(iYear, iMonth, 32).getDate();
}
stolen from http://snippets.dzone.com/posts/show/2099
A slight modification to solution provided by lebreeze:
function daysInMonth(iMonth, iYear)
{
return new Date(iYear, iMonth, 0).getDate();
}
I recently had to do something similar, this is what I came up with:
/**
* Returns a date set to the begining of the month
*
* #param {Date} myDate
* #returns {Date}
*/
function beginningOfMonth(myDate){
let date = new Date(myDate);
date.setDate(1)
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
return date;
}
/**
* Returns a date set to the end of the month
*
* #param {Date} myDate
* #returns {Date}
*/
function endOfMonth(myDate){
let date = new Date(myDate);
date.setDate(1); // Avoids edge cases on the 31st day of some months
date.setMonth(date.getMonth() +1);
date.setDate(0);
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
return date;
}
Pass it in a date, and it will return a date set to either the beginning of the month, or the end of the month.
The begninngOfMonth function is fairly self-explanatory, but what's going in in the endOfMonth function is that I'm incrementing the month to the next month, and then using setDate(0) to roll back the day to the last day of the previous month which is a part of the setDate spec:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate
https://www.w3schools.com/jsref/jsref_setdate.asp
I then set the hour/minutes/seconds to the end of the day, so that if you're using some kind of API that is expecting a date range you'll be able to capture the entirety of that last day. That part might go beyond what the original post is asking for but it could help someone else looking for a similar solution.
Edit: You can also go the extra mile and set milliseconds with setMilliseconds() if you want to be extra precise.
How NOT to do it
Beware of any answers for the last of the month that look like this:
var last = new Date(date)
last.setMonth(last.getMonth() + 1) // This is the wrong way to do it.
last.setDate(0)
This works for most dates, but fails if date is already the last day of the month, on a month that has more days than the following month.
Example:
Suppose date is 07/31/21.
Then last.setMonth(last.getMonth() + 1) increments the month, but keeps the day set at 31.
You get a Date object for 08/31/21,
which is actually 09/01/21.
So then last.setDate(0) results in 08/31/21 when what we really wanted was 07/31/21.
try this one.
lastDateofTheMonth = new Date(year, month, 0)
example:
new Date(2012, 8, 0)
output:
Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)}
This works for me.
Will provide last day of given year and month:
var d = new Date(2012,02,0);
var n = d.getDate();
alert(n);
This one works nicely:
Date.prototype.setToLastDateInMonth = function () {
this.setDate(1);
this.setMonth(this.getMonth() + 1);
this.setDate(this.getDate() - 1);
return this;
}
You can get the First and Last Date in the current month by following the code:
var dateNow = new Date();
var firstDate = new Date(dateNow.getFullYear(), dateNow.getMonth(), 1);
var lastDate = new Date(dateNow.getFullYear(), dateNow.getMonth() + 1, 0);
or if you want to format the date in your custom format then you can use moment js
var dateNow= new Date();
var firstDate=moment(new Date(dateNow.getFullYear(),dateNow.getMonth(), 1)).format("DD-MM-YYYY");
var currentDate = moment(new Date()).format("DD-MM-YYYY"); //to get the current date var lastDate = moment(new
Date(dateNow.getFullYear(), dateNow.getMonth() + 1, 0)).format("DD-MM-YYYY"); //month last date
This will give you current month first and last day.
If you need to change 'year' remove d.getFullYear() and set your year.
If you need to change 'month' remove d.getMonth() and set your year.
var d = new Date();
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())];
var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())];
console.log("First Day :" + fistDayOfMonth);
console.log("Last Day:" + LastDayOfMonth);
alert("First Day :" + fistDayOfMonth);
alert("Last Day:" + LastDayOfMonth);
Try this:
function _getEndOfMonth(time_stamp) {
let time = new Date(time_stamp * 1000);
let month = time.getMonth() + 1;
let year = time.getFullYear();
let day = time.getDate();
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (_leapyear(year))
day = 29;
else
day = 28;
break
}
let m = moment(`${year}-${month}-${day}`, 'YYYY-MM-DD')
return m.unix() + constants.DAY - 1;
}
function _leapyear(year) {
return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
}
const today = new Date();
let beginDate = new Date();
let endDate = new Date();
// fist date of montg
beginDate = new Date(
`${today.getFullYear()}-${today.getMonth() + 1}-01 00:00:00`
);
// end date of month
// set next Month first Date
endDate = new Date(
`${today.getFullYear()}-${today.getMonth() + 2}-01 :23:59:59`
);
// deducting 1 day
endDate.setDate(0);
Below function gives the last day of the month :
function getLstDayOfMonFnc(date) {
return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}
console.log(getLstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 29
console.log(getLstDayOfMonFnc(new Date(2017, 2, 15))) // Output : 28
console.log(getLstDayOfMonFnc(new Date(2017, 11, 15))) // Output : 30
console.log(getLstDayOfMonFnc(new Date(2017, 12, 15))) // Output : 31
Similarly we can get first day of the month :
function getFstDayOfMonFnc(date) {
return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}
console.log(getFstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 1
Here is an answer that conserves GMT and time of the initial date
var date = new Date();
var first_date = new Date(date); //Make a copy of the date we want the first and last days from
first_date.setUTCDate(1); //Set the day as the first of the month
var last_date = new Date(first_date); //Make a copy of the calculated first day
last_date.setUTCMonth(last_date.getUTCMonth() + 1); //Add a month
last_date.setUTCDate(0); //Set the date to 0, this goes to the last day of the previous month
console.log(first_date.toJSON().substring(0, 10), last_date.toJSON().substring(0, 10)); //Log the dates with the format yyyy-mm-dd
function getLastDay(y, m) {
return 30 + (m <= 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0));
}
set month you need to date and then set the day to zero ,so month begin in 1 - 31 in date function then get the last day^^
var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate();
console.log(last);
I know it's just a matter of semantics, but I ended up using it in this form.
var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate();
console.log(lastDay);
Since functions are resolved from the inside argument, outward, it works the same.
You can then just replace the year, and month / year with the required details, whether it be from the current date. Or a particular month / year.
If you need exact end of the month in miliseconds (for example in a timestamp):
d = new Date()
console.log(d.toString())
d.setDate(1)
d.setHours(23, 59, 59, 999)
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.log(d.toString())
The accepted answer doesn't work for me, I did it as below.
$( function() {
$( "#datepicker" ).datepicker();
$('#getLastDateOfMon').on('click', function(){
var date = $('#datepicker').val();
// Format 'mm/dd/yy' eg: 12/31/2018
var parts = date.split("/");
var lastDateOfMonth = new Date();
lastDateOfMonth.setFullYear(parts[2]);
lastDateOfMonth.setMonth(parts[0]);
lastDateOfMonth.setDate(0);
alert(lastDateOfMonth.toLocaleDateString());
});
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<p>Date: <input type="text" id="datepicker"></p>
<button id="getLastDateOfMon">Get Last Date of Month </button>
</body>
</html>
This will give you last day of current month.
notes: on ios device include time.
#gshoanganh
var date = new Date();
console.log(new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59));
if you just need to get the last date of a month following worked out for me.
var d = new Date();
const year = d.getFullYear();
const month = d.getMonth();
const lastDay = new Date(year, month +1, 0).getDate();
console.log(lastDay);
try it out here https://www.w3resource.com/javascript-exercises/javascript-date-exercise-9.php
In my case, this code was useful
end_date = new Date(2018, 3, 1).toISOString().split('T')[0]
console.log(end_date)

Javascript Date() returns wrong weekday for certain dates

After getting that issue with the wrong weekday for dates from Sep 1, 2017 and later, I found that changing the sequence of 1 statemtent (setDate) returns correct results. See code below. When I enter 1.9.17 (which is Sep 1, 2017) I get Sunday, with the changed code it's Friday. Can somebody explain that to me? Issue occurs in FF, Chrome and Edge.
<body>
<input type="text" onchange="wday(this.value);">
<script>
function wday() {
var x = wday.arguments[0].split(".");
if (x[2].length<4) x[2] += 2000;
var y = new Date();
y.setFullYear(x[2]);
y.setMonth(x[1]-1);
y.setDate(x[0]);
var z = new Array("So","Mo","Di","Mi","Do","Fr","Sa");
alert("wrong "+z[y.getDay()])
wday2(wday.arguments)
}
function wday2() {
var x = wday.arguments[0].split(".");
if (x[2].length<4) x[2] += 2000;
var y = new Date();
y.setDate(x[0]);
y.setMonth(x[1]-1);
y.setFullYear(x[2]);
var z = new Array("So","Mo","Di","Mi","Do","Fr","Sa");
alert("correct "+z[y.getDay()])
}
</script>
</body>
setMonth can set the month to one where the current date (today is the 31st; September has 30 days) doesn’t exist. The overflow is turned into the appropriate day in the following month.
> var d = new Date();
> d
Wed Aug 31 2016 13:30:07 GMT-0700 (PDT)
> d.setMonth(8); // September
> d
Sat Oct 01 2016 13:30:07 GMT-0700 (PDT)
Construct dates all at once to avoid this sort of problem entirely. Your year-adjusting code is also broken (it’ll concatenate 2000 instead of adding it), and referencing arguments using func.arguments is really bad practice.
var WEEKDAYS = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
function wday(dateString) {
var parts = dateString.split('.');
var year = parseInt(parts[2], 10);
var month = parseInt(parts[1], 10);
var day = parseInt(parts[0], 10);
if (parts[2].length < 4) {
year += 2000;
}
var date = new Date(year, month - 1, day);
return WEEKDAYS[date.getDay()];
}
Use more functions for bonus points.
const WEEKDAYS = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
function parseYear(yearString) {
const year = parseInt(yearString, 10);
return yearString.length < 4 ?
year + 2000 :
year;
}
function parseDottedDate(dateString) {
const [day, month, year] = dateString.split('.');
return new Date(
parseYear(year),
parseInt(month, 10) - 1,
parseInt(day, 10)
);
}
function wday(dateString) {
const date = parseDottedDate(dateString);
return WEEKDAYS[date.getDay()];
}

Javascript: find beginning of Advent weeks each year

I have created the following code (which works) to print something different based on the weeks of a specified month:
<script language="javascript">
<!--
var advent;
mytime=new Date();
mymonth=mytime.getMonth()+1;
mydate=mytime.getDate();
if (mymonth==12 && (mydate >= 1 && mydate <= 6)){document.write("xxx");
}
if (mymonth==12 && (mydate >= 7 && mydate <= 13)){document.write("yyy");
}
if (mymonth==12 && (mydate >= 14 && mydate <= 20)){document.write("zzz");
}
if (mymonth==12 && (mydate >= 21 && mydate <= 30)){document.write("qqq");
}
//-->
</script>
But I need this to change for Advent each year and Advent changes based on when Christmas falls each year:
Advent starts on the Sunday four weeks before Christmas Day. There are
four Sundays in Advent, then Christmas Day. The date changes from year
to year, depending on which day of the week Christmas fall. Thus, in
2010, Advent began on 28 November. In 2011, it will occur on 27
November.
How do I calculate when the weeks of Advent begin each year?
Start with a Date that's exactly 3 weeks before Christmas Eve. Then, walk backwards until the day-of-week is Sunday:
function getAdvent(year) {
//in javascript months are zero-indexed. january is 0, december is 11
var d = new Date(new Date(year, 11, 24, 0, 0, 0, 0).getTime() - 3 * 7 * 24 * 60 * 60 * 1000);
while (d.getDay() != 0) {
d = new Date(d.getTime() - 24 * 60 * 60 * 1000);
}
return d;
}
getAdvent(2013);
// Sun Dec 01 2013 00:00:00 GMT-0600 (CST)
getAdvent(2012);
// Sun Dec 02 2012 00:00:00 GMT-0600 (CST)
getAdvent(2011);
// Sun Nov 27 2011 00:00:00 GMT-0600 (CST)
(2013 and 2012 were tested and verified against the calendar on http://usccb.org/. 2011 was verified against http://christianity.about.com/od/christmas/qt/adventdates2011.htm)
Here's what I was talking about in my comment:
function getAdvent(year) {
var date = new Date(year, 11, 25);
var sundays = 0;
while (sundays < 4) {
date.setDate(date.getDate() - 1);
if (date.getDay() === 0) {
sundays++;
}
}
return date;
}
DEMO: http://jsfiddle.net/eyUjX/1/
It starts on Christmas day, in the specific year. It goes into the past, day by day, checking for Sunday (where .getDate() returns 0). After 4 of them are encountered, the looping stops and that Date is returned.
So to get 2009's beginning of Advent, use: getAdvent(2009);. It returns a Date object, so you can still work with its methods.
As a reference of its methods: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date
You can get Advent Sunday by adding 3 days to the last Thursday in November, which seems simpler:
function getAdventDay(y){
var advent=new Date();
advent.setHours(0,0,0,0);
//set the year:
if(typeof y!='number')y=advent.getFullYear();
//get the last day of november:
advent.setFullYear(y,10,30);
//back up to the last thursday in November:
while(advent.getDay()!==4)advent.setDate(advent.getDate()-1);
//add 3 days to get Sunday:
advent.setDate(advent.getDate()+3);
return advent;
}
getAdventDay(2013)
/*
Sun Dec 01 2013 00:00:00 GMT-0500 (Eastern Standard Time)
*/
const getFirstAdvent=function(y){
const firstAdvent=new Date(y,11,3);
firstAdvent.setDate(firstAdvent.getDate()-firstAdvent.getDay());
return firstAdvent;
};
alert(getFirstAdvent(2020));
I love these challenges, here's how it can be done with recursion. First I find the fourth Sunday. Then I Just keep minusing 7 days until I have the other 3. The variables firstSunday, secondSunday, thirdSunday and fourthSunday - contains the dates.
EDIT: I believe I misunderstood, but the firstSunday variable Will be the date you are looking for.
Demo
Javascript
var year = 2011;//new Date().getFullYear();
var sevenDays = (24*60*60*1000) * 7;
var foundDate;
var findClosestSunday = function(date){
foundDate = date;
if (foundDate.getDay() != 0)
findClosestSunday(new Date(year,11,date.getDate()-1));
return foundDate;
}
var fourthSunday = findClosestSunday(new Date(year, 11, 23));
var thirdSunday = new Date(fourthSunday.getTime() - sevenDays);
var secondSunday = new Date(fourthSunday.getTime() - sevenDays *2);
var firstSunday = new Date(fourthSunday.getTime() - sevenDays *3);
console.log
(
firstSunday,
secondSunday,
thirdSunday,
fourthSunday
);
Javascript works with time in terms of milliseconds since epoch. There are 1000 * 60 * 60 *24 * 7 = 604800000 milliseconds in a week.
You can create a new date in Javascript that is offset from a know date doing this:
var weekTicks, christmas, week0, week1, week2, week3;
weekTicks = 604800000;
christmas = new Date(2013, 12, 25);
week0 = new Date(christmas - weekTicks);
week1 = new Date(week0 - weekTicks);
week2 = new Date(week1 - weekTicks);
week3 = new Date(week2 - weekTicks);
See how that works for you.
Also, the Date.getDay function will work to help you find which day of the month is the first Sunday.

How do I calculate the date in JavaScript three months prior to today?

I Am trying to form a date which is 3 months before the current date. I get the current month by the below code
var currentDate = new Date();
var currentMonth = currentDate.getMonth()+1;
Can you guys provide me the logic to calculate and form a date (an object of the Date data type) considering that when the month is January (1), 3 months before date would be OCtober (10)?
var d = new Date();
d.setMonth(d.getMonth() - 3);
This works for January. Run this snippet:
var d = new Date("January 14, 2012");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() - 3);
console.log(d.toLocaleDateString());
There are some caveats...
A month is a curious thing. How do you define 1 month? 30 days? Most people will say that one month ago means the same day of the month on the previous month citation needed. But more than half the time, that is 31 days ago, not 30. And if today is the 31st of the month (and it isn't August or Decemeber), that day of the month doesn't exist in the previous month.
Interestingly, Google agrees with JavaScript if you ask it what day is one month before another day:
It also says that one month is 30.4167 days long:
So, is one month before March 31st the same day as one month before March 28th, 3 days earlier? This all depends on what you mean by "one month before". Go have a conversation with your product owner.
If you want to do like momentjs does, and correct these last day of the month errors by moving to the last day of the month, you can do something like this:
const d = new Date("March 31, 2019");
console.log(d.toLocaleDateString());
const month = d.getMonth();
d.setMonth(d.getMonth() - 1);
while (d.getMonth() === month) {
d.setDate(d.getDate() - 1);
}
console.log(d.toLocaleDateString());
If your requirements are more complicated than that, use some math and write some code. You are a developer! You don't have to install a library! You don't have to copy and paste from stackoverflow! You can develop the code yourself to do precisely what you need!
I recommend using a library called Moment.js.
It is well tested, works cross browser and on server side(I am using it both in Angular and Node projects). It has great support for locale dates.
http://momentjs.com/
var threeMonthsAgo = moment().subtract(3, 'months');
console.log(threeMonthsAgo.format()); // 2015-10-13T09:37:35+02:00
.format() returns string representation of date formatted in ISO 8601 format. You can also use it with custom date format like this:.format('dddd, MMMM Do YYYY, h:mm:ss a')
A "one liner" (on many line for easy read)) to be put directly into a variable:
var oneMonthAgo = new Date(
new Date().getFullYear(),
new Date().getMonth() - 1,
new Date().getDate()
);
This should handle addition/subtraction, just put a negative value in to subtract and a positive value to add. This also solves the month crossover problem.
function monthAdd(date, month) {
var temp = date;
temp = new Date(date.getFullYear(), date.getMonth(), 1);
temp.setMonth(temp.getMonth() + (month + 1));
temp.setDate(temp.getDate() - 1);
if (date.getDate() < temp.getDate()) {
temp.setDate(date.getDate());
}
return temp;
}
To make things really simple you can use DateJS, a date library for JavaScript:
http://www.datejs.com/
Example code for you:
Date.today().add({ months: -1 });
If the setMonth method offered by gilly3 isn't what you're looking for, consider:
var someDate = new Date(); // add arguments as needed
someDate.setTime(someDate.getTime() - 3*28*24*60*60);
// assumes the definition of "one month" to be "four weeks".
Can be used for any amount of time, just set the right multiples.
I like the simplicity of gilly3's answer, but users will probably be surprised that a month before March 31 is March 3. I chose to implement a version that sticks to the end of the month, so a month before March 28, 29, 30, and 31 will all be Feb 28 when it's not a leap year.
function addMonths(date, months) {
var result = new Date(date),
expectedMonth = ((date.getMonth() + months) % 12 + 12) % 12;
result.setMonth(result.getMonth() + months);
if (result.getMonth() !== expectedMonth) {
result.setDate(0);
}
return result;
}
var dt2004_05_31 = new Date("2004-05-31 0:00"),
dt2001_05_31 = new Date("2001-05-31 0:00"),
dt2001_03_31 = new Date("2001-03-31 0:00"),
dt2001_02_28 = new Date("2001-02-28 0:00"),
result = addMonths(dt2001_05_31, -2);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());
result = addMonths(dt2001_05_31, -3);
console.assert(dt2001_02_28.getTime() == result.getTime(), result.toDateString());
result = addMonths(dt2001_05_31, 36);
console.assert(dt2004_05_31.getTime() == result.getTime(), result.toDateString());
result = addMonths(dt2004_05_31, -38);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());
console.log('Done.');
Do this
let currentdate = new Date();
let last3months = new Date(currentdate.setMonth(currentdate.getMonth()-3));
Javascript's setMonth method also takes care of the year. For instance, the above code will return 2020-01-29 if currentDate is set as new Date("2020-01-29")
For get date three monts prior to today :
let d = new Date(new Date().setMonth(new Date().getMonth() - 3))
console.log(d.toISOString().slice(0, 10))
// 2022-05-24 (today is 2022-08-24)
var d = new Date("2013/01/01");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() + 18);
console.log(d.toLocaleDateString());
This is the Smallest and easiest code.
var minDate = new Date();
minDate.setMonth(minDate.getMonth() - 3);
Declare variable which has current date.
then just by using setMonth inbuilt function we can get 3 month back date.
There is an elegant answer already but I find that its hard to read so I made my own function. For my purposes I didn't need a negative result but it wouldn't be hard to modify.
var subtractMonths = function (date1,date2) {
if (date1-date2 <=0) {
return 0;
}
var monthCount = 0;
while (date1 > date2){
monthCount++;
date1.setMonth(date1.getMonth() -1);
}
return monthCount;
}
As I don't seem to see it already suggested....
const d = new Date();
const day = d.getDate();
const goBack = 3;
for (let i = 0; i < goBack; i++) d.setDate(0);
d.setDate(day);
This will give you the date of today's date 3 months ago as .setDate(0) sets the date to the last day of last month irrespective of how many days a month contains. day is used to restore today's date value.
var todayDate = new Date().toISOString().slice(0, 10);
var d = new Date(todayDate);
d.setMonth(d.getMonth() -3);
console.log(todayDate)
console.log(d.toISOString().slice(0, 10));
d.setMonth changed local time in browser try
const calcDate = (m) => {
let date = new Date();
let day = date.getDate();
let month = date.getMonth() + 1;
let year = date.getFullYear();
let days = 0;
if (m > 0) {
for (let i = 1; i < m; i++) {
month += 1;
if (month > 12) {
year += 1;
month = 1;
}
days += new Date(year, month, 0).getDate();
}
} else {
for (let i = m; i < 0; i++) {
month -= 1;
if (month < 1) {
year -= 1;
month = 12;
}
days -= new Date(year, month, 0).getDate();
}
}
const newTime = date.getTime() + 3600 * 24 * 1000 * days;
return new Date(newTime);
};
calcDate(3)//+3 month
Since "Feb 31th" is auto converted to "March 3" or "March 2", as a month before "March 31th", which is quite counterintuitive, I decided to do it just like how I do it in my mind.
Similar to #Don Kirkby 's answer, I also revise the date with the last day of the target month.
function nMonthsAgo(date, n) {
// get the target year, month, date
const y = date.getFullYear() - Math.trunc(n / 12)
const m = date.getMonth() - n % 12
let d = date.getDate()
if (d > 27) { // get a valid date
const lastDateofMonth = new Date(y, m + 1, 0).getDate()
d = Math.min(d, lastDateofMonth)
}
return new Date(y, m, d)
}
d = new Date('2022-03-31')
nMonthsAgo(d, 1).toLocaleDateString()
Finally, I love what #gilly3 said in his answer:
If your requirements are more complicated than that, use some math and write some code. You are a developer! You don't have to install a library! You don't have to copy and paste from stackoverflow! You can develop the code yourself to do precisely what you need!
for (let monthOfYear = 0; monthOfYear < 12; monthOfYear++) {
const maxDate = new Date();
const minDate = new Date();
const max = maxDate.setMonth(maxDate.getMonth() - (monthOfYear - 1), 0);
const min = maxDate.setMonth(minDate.getMonth() - (monthOfYear), 1);
console.log('max: ', new Date(max));
console.log('min: ', new Date(min));
}
In my case I needed to substract 1 month to current date. The important part was the month number, so it doesn't care in which day of the current month you are at, I needed last month. This is my code:
var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)
dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month
//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)
Substract 1 month to actual date it's not accurate, that's why in first place I set first day of the month (first day of any month always is first day) and in second place I substract 1 day, which always send you to last month.
Hope to help you dude.
var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)
dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month
//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)
var date=document.getElementById("date");
var d = new Date();
document.write(d + "<br/>");
d.setMonth(d.getMonth() - 6);
document.write(d);
if(d<date)
document.write("lesser then 6 months");
else
document.write("greater then 6 months");
Pass a JS Date object and an integer of how many months you want to add/subtract. monthsToAdd can be positive or negative. Returns a JS date object.
If your originalDateObject is March 31, and you pass -1 as monthsToAdd, then your output date will be February 28.
If you pass a large number of months, say 36, it will handle the year adjustment properly as well.
const addMonthsToDate = (originalDateObject, monthsToAdd) => {
const originalDay = originalDateObject.getUTCDate();
const originalMonth = originalDateObject.getUTCMonth();
const originalYear = originalDateObject.getUTCFullYear();
const monthDayCountMap = {
"0": 31,
"1": 28,
"2": 31,
"3": 30,
"4": 31,
"5": 30,
"6": 31,
"7": 31,
"8": 30,
"9": 31,
"10": 30,
"11": 31
};
let newMonth;
if (newMonth > -1) {
newMonth = (((originalMonth + monthsToAdd) % 12)).toString();
} else {
const delta = (monthsToAdd * -1) % 12;
newMonth = originalMonth - delta < 0 ? (12+originalMonth) - delta : originalMonth - delta;
}
let newDay;
if (originalDay > monthDayCountMap[newMonth]) {
newDay = monthDayCountMap[newMonth].toString();
} else {
newDay = originalDay.toString();
}
newMonth = (+newMonth + 1).toString();
if (newMonth.length === 1) {
newMonth = '0' + newMonth;
}
if (newDay.length === 1) {
newDay = '0' + newDay;
}
if (monthsToAdd <= 0) {
monthsToAdd -= 11;
}
let newYear = (~~((originalMonth + monthsToAdd) / 12)) + originalYear;
let newTime = originalDateObject.toISOString().slice(10, 24);
const newDateISOString = `${newYear}-${newMonth}-${newDay}${newTime}`;
return new Date(newDateISOString);
};
Following code give me Just Previous Month From Current Month even the date is 31/30 of current date and last month is 30/29/28 days:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the date after changing the month.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var d = new Date("March 29, 2017"); // Please Try the result also for "March 31, 2017" Or "March 30, 2017"
var OneMonthBefore =new Date(d);
OneMonthBefore.setMonth(d.getMonth(),0);
if(OneMonthBefore.getDate() < d.getDate() )
{
d.setMonth(d.getMonth(),0);
}else
{
d.setMonth(d.getMonth()-1);
}
document.getElementById("demo").innerHTML = d;
}
</script>
</body>
</html>
var d = new Date();
document.write(d + "<br/>");
d.setMonth(d.getMonth() - 6);
document.write(d);

Calculate last day of month

If you provide 0 as the dayValue in Date.setFullYear you get the last day of the previous month:
d = new Date(); d.setFullYear(2008, 11, 0); // Sun Nov 30 2008
There is reference to this behaviour at mozilla. Is this a reliable cross-browser feature or should I look at alternative methods?
var month = 0; // January
var d = new Date(2008, month + 1, 0);
console.log(d.toString()); // last day in January
IE 6: Thu Jan 31 00:00:00 CST 2008
IE 7: Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2: Thu Jan 31 00:00:00 CST 2008
Opera 8.54: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27: Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60: Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Output differences are due to differences in the toString() implementation, not because the dates are different.
Of course, just because the browsers identified above use 0 as the last day of the previous month does not mean they will continue to do so, or that browsers not listed will do so, but it lends credibility to the belief that it should work the same way in every browser.
I find this to be the best solution for me. Let the Date object calculate it for you.
var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);
Setting day parameter to 0 means one day less than first day of the month which is last day of the previous month.
I would use an intermediate date with the first day of the next month, and return the date from the previous day:
int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);
In computer terms, new Date() and regular expression solutions are slow! If you want a super-fast (and super-cryptic) one-liner, try this one (assuming m is in Jan=1 format). I keep trying different code changes to get the best performance.
My current fastest version:
After looking at this related question Leap year check using bitwise operators (amazing speed) and discovering what the 25 & 15 magic number represented, I have come up with this optimized hybrid of answers (note the parameters m & y must obviously be integers for this to work):
function getDaysInMonth(m, y) {
return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}
Given the bit-shifting this obviously assumes that your m & y parameters are both integers, as passing numbers as strings would result in weird results.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/H89X3/22/
JSPerf results: http://jsperf.com/days-in-month-head-to-head/5
For some reason, (m+(m>>3)&1) is more efficient than (5546>>m&1) on almost all browsers.
The only real competition for speed is from #GitaarLab, so I have created a head-to-head JSPerf for us to test on: http://jsperf.com/days-in-month-head-to-head/5
It works based on my leap year answer here: javascript to find leap year this answer here Leap year check using bitwise operators (amazing speed) as well as the following binary logic.
A quick lesson in binary months:
If you interpret the index of the desired months (Jan = 1) in binary you will notice that months with 31 days either have bit 3 clear and bit 0 set, or bit 3 set and bit 0 clear.
Jan = 1 = 0001 : 31 days
Feb = 2 = 0010
Mar = 3 = 0011 : 31 days
Apr = 4 = 0100
May = 5 = 0101 : 31 days
Jun = 6 = 0110
Jul = 7 = 0111 : 31 days
Aug = 8 = 1000 : 31 days
Sep = 9 = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days
That means you can shift the value 3 places with >> 3, XOR the bits with the original ^ m and see if the result is 1 or 0 in bit position 0 using & 1. Note: It turns out + is slightly faster than XOR (^) and (m >> 3) + m gives the same result in bit 0.
JSPerf results: http://jsperf.com/days-in-month-perf-test/6
My colleague stumbled upon the following which may be an easier solution
function daysInMonth(iMonth, iYear)
{
return 32 - new Date(iYear, iMonth, 32).getDate();
}
stolen from http://snippets.dzone.com/posts/show/2099
A slight modification to solution provided by lebreeze:
function daysInMonth(iMonth, iYear)
{
return new Date(iYear, iMonth, 0).getDate();
}
I recently had to do something similar, this is what I came up with:
/**
* Returns a date set to the begining of the month
*
* #param {Date} myDate
* #returns {Date}
*/
function beginningOfMonth(myDate){
let date = new Date(myDate);
date.setDate(1)
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
return date;
}
/**
* Returns a date set to the end of the month
*
* #param {Date} myDate
* #returns {Date}
*/
function endOfMonth(myDate){
let date = new Date(myDate);
date.setDate(1); // Avoids edge cases on the 31st day of some months
date.setMonth(date.getMonth() +1);
date.setDate(0);
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
return date;
}
Pass it in a date, and it will return a date set to either the beginning of the month, or the end of the month.
The begninngOfMonth function is fairly self-explanatory, but what's going in in the endOfMonth function is that I'm incrementing the month to the next month, and then using setDate(0) to roll back the day to the last day of the previous month which is a part of the setDate spec:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate
https://www.w3schools.com/jsref/jsref_setdate.asp
I then set the hour/minutes/seconds to the end of the day, so that if you're using some kind of API that is expecting a date range you'll be able to capture the entirety of that last day. That part might go beyond what the original post is asking for but it could help someone else looking for a similar solution.
Edit: You can also go the extra mile and set milliseconds with setMilliseconds() if you want to be extra precise.
How NOT to do it
Beware of any answers for the last of the month that look like this:
var last = new Date(date)
last.setMonth(last.getMonth() + 1) // This is the wrong way to do it.
last.setDate(0)
This works for most dates, but fails if date is already the last day of the month, on a month that has more days than the following month.
Example:
Suppose date is 07/31/21.
Then last.setMonth(last.getMonth() + 1) increments the month, but keeps the day set at 31.
You get a Date object for 08/31/21,
which is actually 09/01/21.
So then last.setDate(0) results in 08/31/21 when what we really wanted was 07/31/21.
try this one.
lastDateofTheMonth = new Date(year, month, 0)
example:
new Date(2012, 8, 0)
output:
Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)}
This works for me.
Will provide last day of given year and month:
var d = new Date(2012,02,0);
var n = d.getDate();
alert(n);
This one works nicely:
Date.prototype.setToLastDateInMonth = function () {
this.setDate(1);
this.setMonth(this.getMonth() + 1);
this.setDate(this.getDate() - 1);
return this;
}
You can get the First and Last Date in the current month by following the code:
var dateNow = new Date();
var firstDate = new Date(dateNow.getFullYear(), dateNow.getMonth(), 1);
var lastDate = new Date(dateNow.getFullYear(), dateNow.getMonth() + 1, 0);
or if you want to format the date in your custom format then you can use moment js
var dateNow= new Date();
var firstDate=moment(new Date(dateNow.getFullYear(),dateNow.getMonth(), 1)).format("DD-MM-YYYY");
var currentDate = moment(new Date()).format("DD-MM-YYYY"); //to get the current date var lastDate = moment(new
Date(dateNow.getFullYear(), dateNow.getMonth() + 1, 0)).format("DD-MM-YYYY"); //month last date
This will give you current month first and last day.
If you need to change 'year' remove d.getFullYear() and set your year.
If you need to change 'month' remove d.getMonth() and set your year.
var d = new Date();
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())];
var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())];
console.log("First Day :" + fistDayOfMonth);
console.log("Last Day:" + LastDayOfMonth);
alert("First Day :" + fistDayOfMonth);
alert("Last Day:" + LastDayOfMonth);
Try this:
function _getEndOfMonth(time_stamp) {
let time = new Date(time_stamp * 1000);
let month = time.getMonth() + 1;
let year = time.getFullYear();
let day = time.getDate();
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (_leapyear(year))
day = 29;
else
day = 28;
break
}
let m = moment(`${year}-${month}-${day}`, 'YYYY-MM-DD')
return m.unix() + constants.DAY - 1;
}
function _leapyear(year) {
return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
}
const today = new Date();
let beginDate = new Date();
let endDate = new Date();
// fist date of montg
beginDate = new Date(
`${today.getFullYear()}-${today.getMonth() + 1}-01 00:00:00`
);
// end date of month
// set next Month first Date
endDate = new Date(
`${today.getFullYear()}-${today.getMonth() + 2}-01 :23:59:59`
);
// deducting 1 day
endDate.setDate(0);
Below function gives the last day of the month :
function getLstDayOfMonFnc(date) {
return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}
console.log(getLstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 29
console.log(getLstDayOfMonFnc(new Date(2017, 2, 15))) // Output : 28
console.log(getLstDayOfMonFnc(new Date(2017, 11, 15))) // Output : 30
console.log(getLstDayOfMonFnc(new Date(2017, 12, 15))) // Output : 31
Similarly we can get first day of the month :
function getFstDayOfMonFnc(date) {
return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}
console.log(getFstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 1
Here is an answer that conserves GMT and time of the initial date
var date = new Date();
var first_date = new Date(date); //Make a copy of the date we want the first and last days from
first_date.setUTCDate(1); //Set the day as the first of the month
var last_date = new Date(first_date); //Make a copy of the calculated first day
last_date.setUTCMonth(last_date.getUTCMonth() + 1); //Add a month
last_date.setUTCDate(0); //Set the date to 0, this goes to the last day of the previous month
console.log(first_date.toJSON().substring(0, 10), last_date.toJSON().substring(0, 10)); //Log the dates with the format yyyy-mm-dd
function getLastDay(y, m) {
return 30 + (m <= 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0));
}
set month you need to date and then set the day to zero ,so month begin in 1 - 31 in date function then get the last day^^
var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate();
console.log(last);
I know it's just a matter of semantics, but I ended up using it in this form.
var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate();
console.log(lastDay);
Since functions are resolved from the inside argument, outward, it works the same.
You can then just replace the year, and month / year with the required details, whether it be from the current date. Or a particular month / year.
If you need exact end of the month in miliseconds (for example in a timestamp):
d = new Date()
console.log(d.toString())
d.setDate(1)
d.setHours(23, 59, 59, 999)
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.log(d.toString())
The accepted answer doesn't work for me, I did it as below.
$( function() {
$( "#datepicker" ).datepicker();
$('#getLastDateOfMon').on('click', function(){
var date = $('#datepicker').val();
// Format 'mm/dd/yy' eg: 12/31/2018
var parts = date.split("/");
var lastDateOfMonth = new Date();
lastDateOfMonth.setFullYear(parts[2]);
lastDateOfMonth.setMonth(parts[0]);
lastDateOfMonth.setDate(0);
alert(lastDateOfMonth.toLocaleDateString());
});
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<p>Date: <input type="text" id="datepicker"></p>
<button id="getLastDateOfMon">Get Last Date of Month </button>
</body>
</html>
This will give you last day of current month.
notes: on ios device include time.
#gshoanganh
var date = new Date();
console.log(new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59));
if you just need to get the last date of a month following worked out for me.
var d = new Date();
const year = d.getFullYear();
const month = d.getMonth();
const lastDay = new Date(year, month +1, 0).getDate();
console.log(lastDay);
try it out here https://www.w3resource.com/javascript-exercises/javascript-date-exercise-9.php
In my case, this code was useful
end_date = new Date(2018, 3, 1).toISOString().split('T')[0]
console.log(end_date)

Categories

Resources