Javascript and setMonth behaving unexpectedly - javascript

I am doing datObj.setMonth(1), but the month is being set to March? Isn't 1 supposed to be February? I'm using Chrome 79.
Here's part of code meant to parse dates such as YYYY-MM-DD HH:MM:SS (because safari can't do that natively)
var date = "2020-02-02 23:59:00"
if (typeof date == 'string')
{
var dateParts = date.split(/[:-\s]+/);
if (dateParts.length == 6)
{
dateObj = new Date();
dateObj.setYear(dateParts[0]);
var m = dateParts[1] - 1;
console.log('m= ' + m);
dateObj.setMonth(m);
console.log('after setmonth, date= ' + dateObj);
dateObj.setDate(dateParts[2]);
dateObj.setHours(dateParts[3]);
dateObj.setMinutes(dateParts[4]);
dateObj.setSeconds(dateParts[5]);
}
}
console.log(dateObj);
alert(dateObj);

Your problem, as you figured, is that you're setting the month while the day is still 30. While you could work around that by using setFullYear and pass year, month and day at once, you really should just construct the whole Date object with the right values in the first place:
dateObj = new Date(dateParts[0], dateParts[1]-1, dateParts[2], dateParts[3], dateParts[4], dateParts[5]);
or rather using UTC as the timezone:
dateObj = new Date(Date.UTC(dateParts[0], dateParts[1]-1, dateParts[2], dateParts[3], dateParts[4], dateParts[5]));

Just figured this out before I submitted. Today is January 30th, 2020. I can't change the month to February, because there is no February 30th. So, the code breaks either on the 29th or the 30th day of the month.
In JavaScript, it is advisable to do
dateObj.setMonth(monthNum -1, dayNum)
to set the day and month at the same time to avoid this problem

Related

Javascript newdate function unexpected output

I am confused by the result of the following script and I don't understand why it is what it is:
enddate = '01-02-2020'; //euro format dd-mm-yyyy
datesplit = enddate.split("-");
console.log("datesplit: ", datesplit); //[ '01', '02', '2020' ]
console.log(datesplit[2]); // 2020
console.log(datesplit[1]); // 02
console.log(datesplit[0]); // 01
enddate1 = new Date(datesplit[2],datesplit[1],datesplit[0]);
console.log("enddate 1", enddate1); //output: 2020-03-01T05:00:00.000Z , but I'm expecting 2020-02-01T00:00:00.000Z
That last console log output is what I can't understand. I would appreciate an explanation of why the result is what it is.
JavaScript treats the month as zero-based. So you'll have to -1 your month value to get the right result. As #RobG said, you should use new Date(Date.UTC(...)) to get your date in UTC
let endDate = '01-02-2020' // dd-mm-yyyy;
let [day, month, year] = endDate.split('-');
// Months are zero-based, so -1 to get the right month
month = month - 1;
console.log(day); // '01'
console.log(month);// 1
console.log(year); // '2020'
let newDate = new Date(Date.UTC(year, month, day));
console.log(newDate) // "2020-02-01T00:00:00.000Z"
Given that the other posts seem to have helped you get the right month, have you tried using .toISOString method on the Date object to get the right UTC offset?
The docs on MDN state that the timezone is always zero UTC offset.
You can check Mozilla Documentation
You will see that January is 0, February is 1, and so on. So that's how date works in JavaScript.
You need to convert your month value to Number and then make it "-1". So something like this:
new Date(datesplit[2], (parseInt(datesplit[1], 10) - 1), datesplit[0])

Set custom start date in html

I would like to set a custom start date for a calendar. So instead of the Gregorian calendar's start at 0, 2016 years ago. I would like to start at something like 1980 and a custom month and day too.
So instead of a new year at January 1st, I would like November 5th to be the new year instead (but it's still called January 1st, but compared to the Gregorian calendar, it's November 5th).
Which means, when we (with the Gregorian calendar) have the date 2016-02-10, the calendar I make, I would like it to be year 36 (2016-1980), month April (as November is now first instead of January according to the Gregorian calendar), and day 15 (10+5). So 2016-02-10 would be 30-04-15.
I have this code, but I don't know how to get it to work. Is it possible to do or will I have write code for everything that can happen?
<script type="text/javascript">
var tmonth=new Array("November","December","January","February","March","April","May","June","July","August","September","October");
function GetClock(){
var d=new Date();
//d.setFullYear(1980,0,3);
var nmonth=d.getMonth()
ndate=d.getDate(),nyear=d.getYear();
if(nyear<1000) nyear+=1900;
nyear-=1962;
d.setFullYear(nyear,nmonth,ndate);
var nhour=d.getHours(),nmin=d.getMinutes(),nsec=d.getSeconds(),ap;
if(nhour==0){ap=" AM";nhour=12;}
else if(nhour<12){ap=" AM";}
else if(nhour==12){ap=" PM";}
else if(nhour>12){ap=" PM";nhour-=12;}
if(nmin<=9) nmin="0"+nmin;
if(nsec<=9) nsec="0"+nsec;
document.getElementById('clockbox').innerHTML=""+tmonth[nmonth]+" "+ndate+", "+nyear+" "+nhour+":"+nmin+":"+nsec+ap+"";
}
window.onload=function(){
GetClock();
setInterval(GetClock,1000);
}
</script>
<div id="clockbox"></div>
If i was going to do something like this i'd probably get the difference between now and November the 5th (last year) in milliseconds which is: 8592904550
This means, you can subtract that number from the current timestamp to get the date that amount of seconds ago. I'd then take the current year and -1980 to get the year number.
$(function(){
var el = $('.clockbox');
var dateNow = new Date();
var newDateStamp = dateNow-8592904550;
var newDate = new Date(newDateStamp);
el.text(newDate.getMonth()+1 + "-" + newDate.getDate() + "-" + (dateNow.getFullYear()-1980));
})
You can see a fiddle using jQuery here: https://jsfiddle.net/fpmes8y3/1/
remember the getMonth is zero indexed so you need to +1 to get the true number.
Sorry if i've misunderstood your question.

Javascript add days to a existing calendar object off by one month

I'm trying to read a date from a Calendar object and add a specific amount of days to it (i.e. 7)
Here is the code that I have:
var daysFromBeginDate = parseInt($("#policyDuration").val()) * 7
alert(daysFromBeginDate)
var beginDate = new Date("2015-04-24");
alert(beginDate)
var endDate = new Date("2015-05-08");
alert(beginDate.getDate() + daysFromBeginDate)
endDate.setDate(new Date(beginDate.getDate() + daysFromBeginDate));
alert(endDate.toString())
and I am getting Sun May 31 2015 17:00:000 GMT as my answer. It should be that with one less month, where is the extra month getting added?
JavaScript using the below call, I found out that the month argument counts starting from zero.
new Date(2015, 3, 1); // that's the 1st April 2015!
And what is causing the issue is the below code snippet in your code:-
endDate.getMonth() + 1
That is possibly the reason for your issue..
EDIT:
if the below code
var endDate = new Date("2015-05-08");
is changed to
var endDate = new Date();
you will get correct output..
it is because setDate sets the day of the month and April has only 30 days so it is rolled over and you get it as May and you get 31 because 24+7 is 31..

JS time calculation - How many times a date has occurred between two dates

I really need some assistance with a time calculation in JS.
Put basically I need to calculate how many times a day of a month has occurred between two dates.
For Example -
A date of 15th of the month between 1st February 2014 to 14 May 2014 would be 3
A date of 15th of the month between 1st February 2014 to 16 May 2014 would be 4
I've looked at moment Jquery library but it estimates that a month is 30 days so I wouldn't be exact and take into consideration leap years - months with 28 days etc..
It really needs to be exact because its for a chargeable event calculation. The dates can spare many years so could lead to in-accuries because of the 30 day thing.
Any help would be appreciated
There are probably a million ways to do this... here's a brute force way:
// add a "addDays() method to Date"
Date.prototype.addDays = function(days)
{
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
// provide two dates and a day ordinal you want to count between the two
function numOrdinalsBetweenDts(Date1, Date2, theOrdinal) {
var temp;
if(Date2 < Date1) { // put dates in the right order (lesser first)
temp = Date1;
Date1 = Date2;
Date2 = temp;
}
var workDate = Date1;
var ctr = 0;
while(workDate < Date2) { // iterate through the calendar until we're past the end
if(workDate.getDate() == theOrdinal) // if we match the ordinal, count it
ctr++;
workDate = workDate.addDays(1); // move the calendar forward a day
}
return ctr;
}
var result = numOrdinalsBetweenDts(new Date("July 21, 1901"), new Date("July 21, 2014"), 2);
console.log(result);
alert(result);
There is a slightly counter-intuitive behavior in the Javascript Date constructor where if you create a new Date with the day set to 0, it will assume the last day of the month. You can the use the following function get the number of days in a month:
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
The Javascript date object is leap-year aware, so you can use this function reliably.
You then just need to count the number of months between the start and end date and check each one to make sure the day number is actually present in the month. You can short-circuit this check if the day is less than or equal to 28.

Does this code work fine? I'd like to get the timestamp of the following date

I'm building a chrome extension now.
I'd like to set an alarm to be fired at 23:59:59 everyday, so I can reset some saved settings at the end of day.
I wrote this code below but, I'm not used to using Date Object.
And I'm worried if this code works fine and don't mess up everything.
Especially, I'm worried about the code for setting up an alarm again for the next day.
var day = now.getDate() + 1;
To get the date of the following day, I just add 1 to the returned value of "now.getDate()".
But, I wonder if the returned value of "now.getDate()" is the end of the month and because of that, adding 1 ends up getting the date which doesn't exist.
Please take a look at my code and tell me if this works fine or not.
Thank you in advance!!
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth();
var day = now.getDate();
var timestamp = Number(new Date(year, month, day, 23, 59, 59, 0));
//set an alarm for today at 23:59:59.
chrome.alarms.create('resetSpentTime', {
when: timestamp
});
// when alarm fires, do the following.
chrome.alarms.onAlarm.addListener(function() {
//clear some saved settings at the end of day.
//After that, set an alarm again for tomorrow at 23:59:59.
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth();
var day = now.getDate() + 1;
var timestamp = Number(new Date(year, month, day, 23, 59, 59, 0));
//set an alarm for tomorrow at 23:59:59.
chrome.alarms.create('resetSpentTime', {
when: timestamp
});
})
I'll suggest use date.js Link for date.js filefor all date operations in Javascript in which you can add days or parse dates easily. See the demo on given site.
You can try this. Nextday as well as end of month is auto handeled.
var today = new Date();
var tomorrow = new Date();
tomorrow.setDate(today.getDate()+1);
Source: Add days to JavaScript Date

Categories

Resources