To calculate the difference between now and a time X, I'm using the following:
var splitPickDate= startDate.split('/');
var splitPick = startTime.split(':');
var timeCalc = new Date(parseInt(splitPickDate[2]),parseInt(splitPickDate[0]),parseInt(splitPickDate[1]), parseInt(splitPick[0]), parseInt(splitPick[1]));
var now = new Date();
var diffNow = timeCalc - now;
Assuming splitPickDate = '01/28/2015', splitPick = '00:00' and now = Wed Jan 28 2015 15:35:04 GMT+0530 (India Standard Time) should I not get a negative value for diffNow?
Am I wrong in calculating the time difference between the two times?
I think thats because in JS when you use numbers for months January = 0, February = 1, etc.
Your code just uses 1 from the string which creates a date for 28 February, instead of 28 January. So you subtract a January time from a February time. Which is sure positive.
With this. your calculation will be ok for those particular dates:
var timeCalc = new Date(parseInt(splitPickDate[2]),parseInt(splitPickDate[0]),parseInt(splitPickDate[1]), parseInt(splitPick[0]), parseInt(splitPick[1]));
Related
Through the 'date-fns' module, I am receiving numbers of how many weeks the date is this year.
const current = '2022-03-10'
const weekNumber = getWeek(current, 1) // 11
On the contrary, if you only know the numbers, you want to know how to do the first date of the week number.
The way I want to know.
const weekNumber = 11;
const weekOfstartDate = anyFunc(weekNumber) // '2022-03-07'
Do you know the answer to this solution?
You can use the I token:
var dateFns = require("date-fns");
console.log(dateFns.parse('10','I', new Date()));
At npm.runkit.com that returns a date for Mon 7 Mar 2022. It seems date-fns assumes the year of the current week. I have no idea how to specify the year, attempting:
console.log(dateFns.parse('2022-10','YYYY-II', new Date(),{
useAdditionalWeekYearTokens: true
}));
Throws a range error: The format string mustn't contain YYYY and II at the same time. Similarly for "2022W10" and tokens "YYYY'W'II", it says Y and I tokens can't be in the same format string.
A function to do the same thing is:
// Returns the first day (Monday) of the specified week
// Year defaults to the current local calendar year
function getISOWeek(w, y = new Date().getFullYear()) {
let d = new Date(y, 0, 4);
d.setDate(d.getDate() - (d.getDay() || 7) + 1 + 7*(w - 1));
return d;
}
// Mon Mar 14 2022
console.log(getISOWeek(11).toString());
// Mon Jan 02 2023
console.log(getISOWeek(1,2023).toString());
// Mon Dec 28 2026
console.log(getISOWeek(53,2026).toString());
A robust function should validate the input such that the week number is 1 to 53 and that 53 is only permitted for years that have 53 weeks.
I wanted a solution only using date-fns functions. This is how i combined it:
const result = setWeek(nextMonday(new Date(year, 0, 4)), week, {
weekStartsOn: 1,
firstWeekContainsDate: 4,
});
For m = range 1-12 it works as expected, increasing month by 1.
For m = range 13- it doesn't work as expected, increasing year by 1.
As m exceeds 12 inside loop I was expecting result:
Sun Feb 28 2015 00:00:00 GMT+0400 (GET)
Tue Mar 28 2015 00:00:00 GMT+0400 (GET)
Sat Apr 28 2015 00:00:00 GMT+0400 (GET)
Instead I get:
Sun Feb 28 2016 00:00:00 GMT+0400 (GET)
Tue Mar 28 2017 00:00:00 GMT+0400 (GET)
Sat Apr 28 2018 00:00:00 GMT+0400 (GET)
...
var loanAmount = 3800,
loanInterest = 32, // %
loanDuration = 48, // Month
loanGrace = 0,
loanFee = 1, // %
loanInitMonth = 0,
loanInitDay = 28,
loanInitYear = 2014;
var loanStart = new Date(loanInitYear,loanInitMonth,loanInitDay);
for (var m = loanInitMonth; m < loanDuration; m++) {
var d = loanStart;
d.setMonth(m);
console.log(m);
console.log(d);
}
Jsfiddle
As setMonth description states:
If a parameter you specify is outside of the expected range, setMonth
attempts to update the date information in the Date object
accordingly. For example, if you use 15 for monthValue, the year will
be incremented by 1 (year + 1), and 3 will be used for month.
I'm obviously not getting this behavior.
Browser Chrome.
When you do this, you are copying the reference to the Date object instead of creating a new copy of the object:
var d = loanStart;
Then, when you change the date in the d variable, you are also changing the date in the loanStart variable, as it's the same object.
Create a copy of the Date object:
var d = new Date(loanStart.getTime());
The problem is that you aren't adding the time to the original date, you're adding it to the current date. So setting the month > 12 to the current date will always add at least one year, which will increment the year.
You have two solutions:
Make sure you're always modifying the original date by maintaining a copy of that date.
Do real date math - trying to set the month (and rely on side-effects) when what you really want to do is increment the month makes for rather confusing code and will have edge cases when, for example, the day of the month isn't a valid day for that month.
Instead of passing m to setMonth, do d.setMonth(d.getMonth()+1) like below:
var loanAmount = 3800,
loanInterest = 32, // %
loanDuration = 48, // Month
loanGrace = 0,
loanFee = 1, // %
loanInitMonth = 0,
loanInitDay = 28,
loanInitYear = 2014;
var loanStart = new Date(loanInitYear,loanInitMonth,loanInitDay);
for (var m = loanInitMonth; m < loanDuration; m++) {
var d = loanStart;
d.setMonth(d.getMonth()+1);
console.log(m);
console.log(d);
}
I have read several questions on stack overflow and all over the internet but somehow I am unable to get it right. I get a date from another function and the value is as below.
var currentDate = new Date("2021-04-27T15:30:27.588+0000");
console.log(currentDate); // this prints Wed Apr 28 2021 00:00:00 GMT+1000 (Australian Eastern Standard Time)
// want to add 45 days to my date
var offset = 45;
var xDate = new Date();
xDate.setDate(currentDate.getDate() + offset);
console.log(xDate);
The output I get is:
Mon Jul 12 2021 19:00:57 GMT+1000 (Australian Eastern Standard Time)
where as this should be some date in June.
Please can someone help me understand what I am doing wrong?
The problem is that when you are initializing a new date object using new Date(), the date object is initialized with the current date. When you increment the days using currentDate.getDate() + offset the day of the month is first set to that of currentDate and incremented by offset but the month from which it is incremented is the current month. Try this one.
var currentDate = new Date("2021-04-27T15:30:27.588+0000");
console.log(currentDate); // this prints Wed Apr 28 2021 00:00:00 GMT+1000 (Australian Eastern Standard Time)
// want to add 45 days to my date
var offset = 45;
var xDate = new Date("2021-04-27T15:30:27.588+0000");
xDate.setDate(currentDate.getDate() + offset);
console.log(xDate);
1 day is equal to 86,400,000 milliseconds. You can multiply that value by 45 and add it to your date:
var currentDate = new Date("2021-04-27T15:30:27.588+0000");
console.log(currentDate);
// Add 45 days
var offset = 45;
var xDate = new Date(currentDate.getTime() + offset * 86400000);
console.log(xDate);
My suggestion:
const addDays = (date, days) => {
var ndt = new Date(date);
ndt.setDate(date.getDate() + days);
return ndt;
};
var date = new Date("2021-04-27T15:30:27.588+0000");
console.log(date);
console.log(addDays(date, 45));
I agree Wais Kamal's answer is right. The below code is more succinct since you avoid time calculations
var currentDate = new Date("2021-04-27T15:30:27.588+0000");
var offset = 45;
var xDate = currentDate.setDate(currentDate.getDate() + offset);
console.log(xDate);
You can make use of the moment here. Link to official docs. Don't forget to install moment package like so (assuming you are using npm)
npm i moment
const myDate = "2021-04-27T15:30:27.588+0000";
const updatedDate = moment
.utc(myDate)
.add(45, 'days')
.format('YYYY-MM-DD');
console.log('updatedDate', updatedDate); // "2021-06-11"
I need to create Date Objects from strings of Date data for every hour of every day since the year 2000.
The strings look like this for every hour, in a Month/Day/Year Hour format...
"04/02/2000 01", "04/02/2000 02", "04/02/2000 03" ...all the way to... "04/02/2000 24"
Now, I have the following code, which works fine except for on days with Daylight Savings Time...
// Split At Space
var splitDate = "04/02/2000 24".split(/[ ]+/);
var hour = splitDate[1];
var day = splitDate[0];
// Split At Slashes
var dayArray = day.split("/");
if (hour === "24") {
// Months are zero-based, so subtract 1 from the month
date = new Date(Date.UTC( dayArray[2], parseInt(dayArray[0] - 1), dayArray[1], 0, 0, 0 ));
date.setDate(date.getDate() + 1);
} else {
// Months and Hours are zero-based, so subtract 1 from each
date = new Date(Date.UTC( dayArray[2], parseInt(dayArray[0] - 1), dayArray[1], hour, 0, 0 ));
};
On days with daylight savings time, like 04/02/2000 adding a day does not work if the hour is 24. Instead, it just returns Sun, 02 Apr 2000 23:00:00 GMT
With Moment.js, is it possible to detect a DST day and get this code to work correctly?
To detect DST, use the .isDST() method: http://momentjs.com/docs/#/query/is-daylight-saving-time/
moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST
Using this test, you should be able to determine how to modify your program's behavior accordingly.
Here's how I made a little checker:
var curDst = dtdate.isDST()
var prevDst = moment(dtdate).clone().subtract(1, "day").isDST();
var nextDst = moment(dtdate).clone().add(1, "day").isDST();
var isDstChangeDate = (curDst !== nextDst) === true || (curDst === prevDst) !== true;
I have some javascript which parses an ISO-8601 date. For some reason, it is failing for dates in June. But dates in July and May work fine, which doesn't make sense to me. I'm hoping a fresh set of eyes will help, because I can't see what I'm doing wrong here.
Function definition (with bug)
function parseISO8601(timestamp)
{
var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$");
var matches = regex.exec(timestamp);
if(matches != null)
{
var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10);
if(matches[7] == "-")
offset = -offset;
var date = new Date();
date.setUTCFullYear(parseInt(matches[1], 10));
date.setUTCMonth(parseInt(matches[2], 10) - 1); //UPDATE - this is wrong
date.setUTCDate(parseInt(matches[3], 10));
date.setUTCHours(parseInt(matches[4], 10));
date.setUTCMinutes(parseInt(matches[5], 10) - offset);
date.setUTCSeconds(parseInt(matches[6], 10));
date.setUTCMilliseconds(0);
return date;
}
return null;
}
Test code
alert(parseISO8601('2009-05-09T12:30:00-00:00').toUTCString());
alert(parseISO8601('2009-06-09T12:30:00-00:00').toUTCString());
alert(parseISO8601('2009-07-09T12:30:00-00:00').toUTCString());
Output
Sat, 09 May 2009 12:30:00 GMT
Thu, 09 Jul 2009 12:30:00 GMT
Thu, 09 Jul 2009 12:30:00 GMT
Update
Thanks for the quick answers, the problem was that the Date object was initially today, which happened to be July 31. When the month was set to June, before I changed the day, it was temporarily June 31, which got rolled forward to July 1.
I've since found the following to be a cleaner implementation, as it sets all the date attributes at once:
function parseISO8601(timestamp)
{
var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$");
var matches = regex.exec(timestamp);
if(matches != null)
{
var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10);
if(matches[7] == "-")
offset = -offset;
return new Date(
Date.UTC(
parseInt(matches[1], 10),
parseInt(matches[2], 10) - 1,
parseInt(matches[3], 10),
parseInt(matches[4], 10),
parseInt(matches[5], 10),
parseInt(matches[6], 10)
) - offset*60*1000
);
}
return null;
}
The problem is that today is July 31.
When you set:
var date = new Date();
Then date.getUTCDate() is 31. When you set date.setUTCMonth(5) (for June), you are setting date to June 31. Because there is no June 31, the JavaScript Date object turns it into July 1. So immediately after setting calling date.setUTCMonth(5) if you alert(date.getUTCMonth()); it will be 6.
This isn't unique to June. Using your function on the 31st of any month for any other month that does not have 31 days will exhibit the same problem. Using your function on the 29th (non-leap years), 30th or 31st of any month for February would also return the wrong result.
Calling setUTC*() in such a way that any rollovers are overwritten by the correct value should fix this:
var date = new Date();
date.setUTCMilliseconds(0);
date.setUTCSeconds(parseInt(matches[6], 10));
date.setUTCMinutes(parseInt(matches[5], 10) - offset);
date.setUTCHours(parseInt(matches[4], 10));
date.setUTCDate(parseInt(matches[3], 10));
date.setUTCMonth(parseInt(matches[2], 10) - 1);
date.setUTCFullYear(parseInt(matches[1], 10));
The date object starts off with the current date.
It's the 31st today so setting 2009-06-09 gives:
var date = new Date(); // Date is 2009-07-31
date.setUTCFullYear(2009); // Date is 2009-07-31
date.setUTCMonth(6 - 1); // Date is 2009-06-31 = 2009-07-01
date.setUTCDate(9); // Date is 2009-07-09
If you set the date to the 1st before you begin, then you should be safe.
It's because today is July 31. Grant explained the problem. Here's what I believe is a simpler solution. Initialize your date on Jan 1.
var date = new Date(2009,0,1,0,0,0);
It's the order in which you are changing the date.
The date starts out as July 31, so the set of the month fails because there is no 31 in June. (Actually it is rolling over to jul-1.)
After setting the full year, add this:
date.setYUTCDate(1);
It makes it the first of the month wherein every month is valid.
Looks like a bug?
C:\Documents and Settings\me>java org.mozilla.javascript.tools.shell.Main
Rhino 1.7 release 2 2009 03 22
js> date = new Date();
Fri Jul 31 2009 15:18:38 GMT-0400 (EDT)
js> date.setUTCMonth(5); date.toUTCString();
Wed, 01 Jul 2009 19:18:38 GMT
js> date.setUTCMonth(5); date.toUTCString();
Mon, 01 Jun 2009 19:18:38 GMT
EDIT: Nevermind I guess. Question already answered by somebody more knowledgable.