Add days to Javascript Date object, and also increment month - javascript

Looking over the previous questions and answers it appeared this should work :
var palindrome = new Date('2011-11-11');
var december = new Date('2011-11-11');
december.setDate(palindrome.getDate()+20);
//should be december, but in fact loops back over to Nov 1st)
my jsFiddle
is there a simple way to ensure that months are incremented correctly, or have I missed something obvious ?

You could do it like this:
var dayOffset = 20;
var millisecondOffset = dayOffset * 24 * 60 * 60 * 1000;
december.setTime(december.getTime() + millisecondOffset);

The getMonth() call returns a value between 0 and 11, where 0 is January and 11 is December, so 10 means November. You need to increment the value by 1 when using it in a string. If you simply output it as a string you'll see that it has the correct date. Note I also had to change the starting date format. It didn't seem to like 2011-11-11 so I made it 11/11/2011. http://jsfiddle.net/9HLSW/

Your code is correct, however you are converting it to a string wrongly.
getMonth() starts with 0 as January, and ends with 11 as December. So all you need to do is add 1 to the month like this:
alert(endDate.getFullYear() + "-" + (endDate.getMonth()+1) +"-"+ endDate.getDate());
Notice the additional brackets - cos you are performing a math operation while concatenating strings. You won't want to end up with "101" as the month.
To see whether you got the date correct, use endDate.toDateString() to display the date in a fully qualified name (i.e.: January - December).
alert(endDate.toDateString());
For more info on the Date object, check out this section in w3schools

Related

javascript adding number to getdate

const date = new Date("2020-03-20T12:45:52.793Z");
console.log(date.getDate() + 1);
it shows 21 instead of 3
I'm new in javascript. the operation += does not works
regarding.
This has nothing to do with the operator (+, +=) used. Instead, it is to do with the function you used. From w3schools:
The getDate() method returns the day of the month (from 1 to 31) for the specified date.
See the following snippet:
const date = new Date("2020-03-20T12:45:52.793Z");
console.log(date.getDate());
As you can see, date.getDate() outputs 20, the day of the month you specified. So it is no surprise that adding 1 to this value will get you 21.
Given that you expect the output to be 3, I assume you want to get the month of the date.
To do this, you need to use getMonth and not getDate.
And as you have already correctly noticed, you need to add 1 to the month number if you want to get the result 3, because January starts at 0.
Again, the w3schools definition tells you what you need to know:
The getMonth() method returns the month (from 0 to 11) for the specified date, according to local time.
Note: January is 0, February is 1, and so on.
const date = new Date("2020-03-20T12:45:52.793Z");
console.log(date.getMonth() + 1);

Moment.js diff wrong behaviour

I have a date and I want to substract today of this date. This is my example:
date.format('YYYY-MM-DD')
"2018-04-07"
moment().format('YYYY-MM-DD')
"2018-04-06"
date.diff(moment(), 'days')
0
The diff call returns 0 instead of 1. What is wrong here?
By default, moment#diff will truncate the result to zero decimal
places, returning an integer. If you want a floating point number,
pass true as the third argument. Before 2.0.0, moment#diff returned a
number rounded to the nearest integer, not a truncated number.
To see the full value, pass true as the third parameter:
now.diff(date, 'days', true)
If you want to compare just dates, then use:
var now = moment().startOf('day');
which will set the time to 00:00:00 in the local time zone. And compare with date
Use fromNow() function to understand why you are getting 0 instead of 1. It is very straight-forward.
Do like this :
moment(date).fromNow();
It will give you number of days passed if time is greater than 24 hours otherwise it will give to time in hours. e.g. 2 hours ago, 23 hours etc.
Below is example:
console.log(moment("2018-04-06", "YYYY-MM-DD").fromNow());
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
So you can see it is returning 18 hours ago (as of now) which is less than 24hours i.e. 1 day.
I would suggest to use fromNow instead of diff to get exact difference.
Hope now it makes clear to you.
moment() returns a full moment including time, so it's doing a diff from today, including time, to midnight of the 7th of April, which isn't a full day.
I was also facing the same issue. So after a few research on StackOverflow and moment.js documentation I came up with this solution. Works perfectly for me.
const date1 = "2021-05-12T06:30:00.000Z"
const date2 = "2021-05-18T06:30:00.000Z"
const day1 = moment((moment(date1).format("YYYY-MM-DD")).split("-"))
const day2 = moment((moment(date2).format("YYYY-MM-DD")).split("-"))
const diff = day2.diff(day1,'days')

Calculate days to go until a particular date with momentjs

I want to count down the days until a particular event using momentjs but I'm getting an unexpected result.
With today's date being 17th April, and the event date being 14th May, I want the resulting number of days to be 27, however my code gives me a result of 57. What's wrong?
function daysRemaining() {
var eventdate = moment([2015, 5, 14]);
var todaysdate = moment();
return eventdate.diff(todaysdate, 'days');
}
alert(daysRemaining());
When creating a moment object using an array, you have to take note that months, hours, minutes, seconds, and milliseconds are all zero indexed. Years and days of the month are 1 indexed. This is to mirror the native Date parameters.
Reference
So either change the month to 4 to reflect May or parse the date as an ISO 8601 string
function daysRemaining() {
var eventdate = moment("2015-05-14");
var todaysdate = moment();
return eventdate.diff(todaysdate, 'days');
}
alert(daysRemaining());
Just to add for anyone else that comes across this - there's actually a helper that does the phrasing etc for you:
https://momentjs.com/docs/#/displaying/to/
/* Retrieve a string describing the time from now to the provided date */
daysUntil: function(dateToCheckAgainst){
return new moment().to(moment(dateToCheckAgainst));
}
// Sample outputs
"in three months"
"in two months"
"in 25 days"
That's because months are zero indexed. So 5 is actually June ;)

Calculate difference between 2 dates considering Daylight Saving Time

Given a start date, and a number of days, I need to display the end date = start date + number of days.
So I did something like this:
var endDate=new Date(startDate.getTime()+ONE_DAY);
Everything works fine, except that for 25 and 26 October gives one day less.
Ex.:
2014-01-01 + 2 days = 2014-01-03
2014-10-25 + 2 days = 2014-10-26 (here is the case I need to treat).
This difference appear because of the clock going back 1 hour. Practically 2014-10-27 00:00:00 becomes 2014-10-26 23:00:00.
A simple solution would be to compute this at another hour (example 3 AM). But I want to just display a note when this happens.
For example, if user inputs 2014-10-25, I show a popup saying [something].
Now here is the real problem... I can't seem to find any algorithm that says when clocks goes back in year X.
Example... in 2014 the day is 26 October. In 2016 is 30 October (https://www.gov.uk/when-do-the-clocks-change). Why? This date looks random to be, but I don't think it is. So... when does clock go back/forward?
EDIT: All answers/comments are helpful related to how to fix the problem. But... I already passed that stage. Now I only have an itch about "how on earth are the days when clock is changed computed?".
To find the difference between two dates in whole days, create Date objects, subtract one from the other, then divide by the milliseconds in one day and round. The remainder will only be out by 1 hour for daylight saving so will round to the right value.
You may also need a small function to convert strings to Dates:
// Return Date given ISO date as yyyy-mm-dd
function parseISODate(ds) {
var d = ds.split(/\D/);
return new Date(d[0], --d[1], d[2]);
}
Get the difference in days:
function dateDiff(d0, d1) {
return Math.round((d1 - d0)/8.64e7);
}
// 297
console.log(dateDiff(parseISODate('2014-01-01'), parseISODate('2014-10-25')));
If you want to add days to a date, do something like:
// Add 2 days to 2014-10-25
var d = new Date(2014, 9, 25);
d.setDate(d.getDate() + 2);
console.log(d); // 2014-10-27
The built–in Date object takes account of daylight saving (thought there are bugs in some browsers).
I prefer adding days this way:
var startDate = //someDate;
var endDate = new Date(startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate()+1);
This way you don't have to worry about the days in the calendar.
This code add 1 day, if you want to add more, change the startDate.getDate()+1 for startDate.getDate()+NUMBER_OF_DAYS it works fine even if you are on the last day of month i.e. October 31th.
But maybe you can use #RobG solution which is more elegant than mine

Unable to validate double digit month using Javascript

I have an HTML form where I am allowing users to enter a date to print out a report. However, if that date is within 3 days of the current date, I have it set to tell the user that they must wait 3 days. For some reason the code works when I enter something like "09/30/2012" but when I enter "10/01/2012", the error check skips. It seems at though, if it's a double digit month (10, 11, and 12), it complete skips the error check. Please let me know if you have any ideas. Thanks
JS Code:
var date = myForm.SC_date.value;
var d = new Date(date);
var varBegin = (d.getMonth()+1) + "-" + (d.getDate()-3) + "-" + d.getFullYear()
re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
if (myForm.SC_date.value == "")
window.alert("Please enter the requested date of variance. NOTE: Date must be 3 days prior to today's date.")
//Here is where I am having issues
/*else if(new Date(date) > new Date(varBegin))
window.alert("Invalid date. You must wait at least 3 days before you can request a report.")*/
else if(!myForm.SC_date.value.match(re))
window.alert("Invalid date. Please enter the date as follows: mm/dd/yyyy.")
HTML Code:
<td>Date of Variance </td>
<td colspan="2"><input name="SC_date:*" id="SC_date" type="text" tabindex="06">
</textarea><b><span class="style3">*</span> </b><span class="style2">(mm/dd/yyyy)</span>
</td>
I don't think you want to construct your "3 days ago" date by manipulating a string. I.e., this snippet here:
var varBegin = (d.getMonth()+1) + "-" + (d.getDate()-3) + "-" + d.getFullYear()
First, I'm not sure why you're using hyphens as delimiters here, when you are using forward-slashes as delimiters in your input field?
In any case, that's not a reliable way to construct the date. When you feed a string into the constructor of a Date object, you are effectively calling Date.parse(). That behaves differently on different browsers.
Check this out:
> new Date('1-1-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('01-01-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('2012-1-1');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Looks pretty good, right? But that's on Chrome.
Now check out what happens in an up-to-date version of Firefox, with the exact same calls:
> new Date('1-1-2012');
Date {Invalid Date}
> new Date('01-01-2012');
Date {Invalid Date}
> new Date('2012-1-1');
Date {Invalid Date}
> new Date('2012-01-01');
Date {Sat Dec 31 2011 16:00:00 GMT-0800 (PST)}
Furthermore, look at this behavior, in both browsers:
> new Date('2012-01-01');
Sat Dec 31 2011 16:00:00 GMT-0800 (PST)
Simply prepending zeroes to the month and date digits causes a time warp! You have to set the time and a timezone (for me, PST) to make that go away:
> new Date('2012-01-01T00:00:00-08:00')
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Basically, dealing with date string parsing is a headache. You don't want to have to digest and account for specs like this, this, and this.
So, here's a better alternative -- pass the year, month, and date values (in that order) to the constructor of the Date object. That will reliably create the date for you, so your comparisons are valid.
Like this, for your specific example:
var WARNING_PERIOD_IN_DAYS = 3;
// Extract month, day, year from form input, 'trimming' whitespace.
var re = /^\s*(\d{1,2})\/(\d{1,2})\/(\d{4})\s*$/;
var match = re.exec(inputVal); // from "myForm.SC_date.value".
if (match) {
var month = parseInt(match[1]) - 1; // Zero-indexed months.
var date = parseInt(match[2]);
var year = parseInt(match[3]);
var inputDate = new Date(year, month, date);
var currentDate = new Date();
var threeDaysAgo = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDay() - WARNING_PERIOD_IN_DAYS);
console.log((inputDate > threeDaysAgo) ? 'Within warning period' : 'No warning needed');
}
Speaking of specs, there's one cool thing to note here, which is that in JavaScript, you can "wrap" the date value (it can be too large, or negative), and the resulting Date will still be valid and correct. Here's why:
From the ECMAScript 262 spec, here's what happens when you call setDate():
**15.9.5.36 Date.prototype.setDate (date)**
1. Let t be the result of LocalTime(this time value).
2. Let dt be ToNumber(date).
3. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
4. Let u be TimeClip(UTC(newDate)).
5. Set the [[PrimitiveValue]] internal property of this Date object to u.
6. Return u.
This is the key bit: MakeDay(YearFromTime(t), MonthFromTime(t), dt)
MakeDay gets the year and the month from the current time value of the Date object (in milliseconds of epoch time), and does this:
**15.9.1.12 MakeDay (year, month, date)**
The operator MakeDay calculates a number of days from its three arguments, which must be ECMAScript Number values. This operator functions as follows:
1. If year is not finite or month is not finite or date is not finite, return NaN.
2. Let y be ToInteger(year).
3. Let m be ToInteger(month).
4. Let dt be ToInteger(date).
5. Let ym be y + floor(m /12).
6. Let mn be m modulo 12.
7. Find a value t such that YearFromTime(t) == ym and MonthFromTime(t) == mn and DateFromTime(t) == 1;
but if this is not possible (because some argument is out of range), return NaN.
8. Return Day(t) + dt - 1.
This looks rather involved, but basically it's:
The floor, modulo, and date==1 bits handle month rollovers (months that are negative or greater than 12).
The resulting instant in epoch time is converted to a number of days.
Your date value is added to that number of days. If your date value is negative, that's fine, it will just be subtracted.
The result is passed back to setDate().
setDate calls MakeDate(), which converts the number of days plus the intra-day time into milliseconds in epoch time.
The Date object's internal time is set to this new epoch time.
That's why you can do stuff like this (comments taken from the MakeDay() function in the V8 JS engine project):
// MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
// MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
// MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
Ok, so that was almost certainly too much detail for this particular problem... but I just wanted to make clear what's really going on behind the scenes. Thanks for your patience.
And... just one last thing...
You have a random </textarea> hanging out in that HTML snippet. If there is an opening <textarea> somewhere before it, then it's incorrectly enclosing some of your other elements. If there is no opening <textarea>, then delete it.
If you don't care about the time of the day, I recommend you do the following:
var dUser = new Date(date); //just like you did before
var dVarBegin = new Date("10/05/2012"); //here you do whatever is the date you are setting.
var diff = dVarBegin.getTime() - dUser.getTime();
//now diff is the difference in milliseconds!
I don't fully understand your requirements in relation to the 3 days. However, if what you needed was to compare dates, now you can! I hope this works for you. If you need something more, please ellaborate a little bit on the 3 days thing.
Use a library that lets you control the date formats accepted, e.g. Globalize.js or Date.js. Then define the exact test you wish to carry out especially whether time of the day is significant and whether the test should be relative to current time in user’s system (which is what you get with new Date() without arguments). You can then e.g. calculate a time difference as outlined by #Mamsaac and convert milliseconds to days with simple arithmetic.
It is illogical to use Date() and then, without checking the result, start doing pattern matching on the input. Moreover, Date() is by definition system-dependent and should seldom be used. There is no guarantee that it will accept a format like mm/dd/yyyy at all.

Categories