While setting the date to 31st we encountered this issue.
function getTodayMidnight() {
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(1);
date.setMilliseconds(0);
return date;
}
function getDates() {
var octStartDate = getTodayMidnight();
octStartDate.setDate(1);
octStartDate.setMonth(9);
var octEndDate = getTodayMidnight();
octEndDate.setDate(31);
octEndDate.setMonth(9);
console.log(octStartDate);
console.log(octEndDate);
}
getDates();
I'm accounting for the date offset in my timezone (+530, 330 mins). For start of the month case, the behaviour is expected. (We expect to go back to the previous month and display the date). But we are getting an erroneous output in the case of the last date of the month. Why are they pointing to the same date?
Assuming you ran this program today (15th November), then new Date() returns a Date object with the month set to November. So a call to setDate(31) will result in the date overflowing to 1st December (because November only has 30 days). You then call setMonth(9), so the final result corresponds to 1st October.
Obviously, you can avoid this by switching the order of your method calls.
But to avoid this ordering problem entirely, I'd suggest using the Date(year, month, date, ...) constructor (this also avoids mutating a value type, which is generally considered to be a good thing).
Related
This javascript method for determining the last day of the month doesn't work for me, who is in Ukraine, but it works for my colleague in the US. I get 2022-10-30 and my colleague gets 2022-10-31. What is the problem?
var now = new Date();
const lastDayOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().split('T')[0];
console.log(lastDayOfMonth)
I created a codepen and we got different results:
Сodepen to check
It's because of timezones. new Date works in local time, but toISOString formats the UTC version of the date/time. You don't want to mix UTC methods and local methods, because you'll get inconsistent results. In this case, since you're ahead of UTC, your local date/time at midnight is on the previous day in UTC. But in the States, they're behind UTC (and not so far behind they have the opposite problem), so it works for them.
Start with midnight UTC instead, via the UTC method, so you're consistently using a single timezone:
const now = new Date();
const lastDayOfMonth = new Date(Date.UTC(now.getFullYear(), now.getMonth() + 1, 0))
.toISOString()
.split("T")[0];
console.log(lastDayOfMonth);
I have a ASP.NET webapi with a DateTimeZoneHandling set to Local and I am getting two different results when converting to a JavaScript date.
Example 1
Date returned from server 1932-10-13T00:00:00-04:00
var strDate = new Date("1932-10-13T00:00:00-04:00");
strDate.toISOString(); // 1932-10-13T04:00:00.000Z
strDate.toLocaleString(); // 10/12/1932, 11:00:00 PM
Example 2
Date returned from server 2013-05-09T00:00:00-04:00
var strDate = new Date("2013-05-09T00:00:00-04:00");
strDate.toISOString(); // 2013-05-09T04:00:00.000Z
strDate.toLocaleString(); // 5/9/2013, 12:00:00 AM
I expected behaviour should always be midnight as the dates returned from the server are always midnight. It appears all recent dates parse correctly, however, dates far in the past are incorrect.
The timezone can vary in some locales, for example, I'm UTC-0300, and on certain season shifts it becomes UTC-0200, so it indicates that your locale changed the offset too, making it display the time one hour lesser, basicaly because you locale adopted a different offset along the year.
The example bellow, I've changed your first example to use the same day and month than the second one, so that it proves you that old dates has nothing to do with it.
console.log("Example One");
var strDate = new Date("1932-05-09T00:00:00-04:00");
console.log(strDate.toISOString());
console.log(strDate.toLocaleString());
console.log("--------------------------");
console.log("Example Two");
var strDate2 = new Date("2013-05-09T00:00:00-04:00");
console.log(strDate2.toISOString());
console.log(strDate2.toLocaleString());
Further explanation on UTC/Zulu time
It has normalized the iso date to a zulu date (zero offset iso date). It is still the same datetime, but it has converted the timezone offset into hours making the timezone offset zero.
date [2013-05-09]
separator [T]
time [00:00:00]
offset [-04:00]
The fundamental aspect is that 00:00:00.000-04:00 is the same than 04:00:00.000Z.
If you're simply trying to display the date as someone living in that time would have remembered it (in your case, October 13th happened on October 13th), you may be able to (ab)use Moment Timezone, which appears to format the date as expected:
moment.tz("1932-10-13T00:00:00-04:00", "America/Toronto").tz("UTC").format(); // 1932-10-13T04:00:00Z
In your case, this hacktechnique results in 1932-10-13T04:00:00Z which may be what you are looking for.
I'm working on a response from a script to work out an expiry date. The response is 7200 which I've been advised from the developer is an epoch value that should equate to 3 months. I've never used Epoch before so don't understand how this works?
The formula I've been given to use is (created_at + expires_in) * 1000 which I've been advised will give me my new date.
I used dtmNow = new Date(Date.now()).toISOString(); which returned 2016-08-23T06:33:35.936Z which was correct, but when I tried dtmExpires = new Date((Date.now()+7200)*1000).toISOString(); it returned +048613-09-25T09:58:58.000Z?
I'm not sure what I'm doing wrong here?
Date.now() returns the number of milliseconds since the epoch (the current time value). If you pass a number to the Date constructor, it's used as the time value for a new Date instance. In the following:
new Date(Date.now()).toISOString()
is exactly the same as:
new Date().toISOString()
i.e. you don't need Date.now(). If you want to add 3 months to a date, use Date methods:
// Get a Date for now
var now = new Date();
// Add 3 months
now.setMonth(now.getMonth() + 3);
However, if it's currently 30 November then the above will attempt to create a date for 30 February, which will end up being 1 or 2 March depending on whether it's a in a leap year or not. So if the modified day in the month doesn't match the original, you can set it back to the last day of the previous month.
If you want to add (say) 90 days, then do that using the setDate and getDate methods similar to the following. This also takes account of daylight saving boundaries if you cross one, whereas setting the time value doesn't.
The SO console writes dates in UTC so take that into account when looking at the following results:
function add3Months(d) {
// Default to current date if d not provided
d = d || new Date();
// Remember current date
var date = d.getDate();
// Add 3 months
d.setMonth(d.getMonth() + 3);
// Set the date back to the last day of the previous
// month if date isn't the same
if (d.getDate() != date) d.setDate(0);
return d;
}
// Add 3 months to today
console.log(add3Months());
// Add 3 months to 30 November
console.log(add3Months(new Date(2016,10,30)))
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 ;)
I'm in javascript, running this in the console
d = new Date();
d.setMonth(1);
d.setFullYear(2009);
d.setDate(15);
d.toString();
outputs this:
"Sun Mar 15 2009 18:05:46 GMT-0400 (EDT)"
Why would this be happening? It seems like a browser bug.
That's because when you initialize a new Date, it comes with today's date, so today is Oct 30 2008, then you set the month to February, so there is no February 30, so set first the day, then the month, and then the year:
d = new Date();
d.setDate(15);
d.setMonth(1);
d.setFullYear(2009);
But as #Jason W, says it's better to use the Date constructor:
new Date(year, month, date [, hour, minute, second, millisecond ]);
It's probably best to construct a Date object in one step to avoid the Date object being in an ambiguous or invalid state:
d = new Date(2009, 1, 15);
d = new Date();
d.setDate(15);
d.setMonth(1);
d.setFullYear(2009);
d.toString();
This works.
After a bunch of testing in FF3 on XP with Firebug, here are the things I can tell you
Calling Date.setDate() after calling Date.setMonth() will generate this odd behavior.
Date.setMonth() forces the timezone to be CST (or, some non DST-aware zone)
Date.setDate() forces the timezone to be CDT (or, some DST-aware zone)
So, there's definitely something wonky going on with setMonth() and setDate() in respect to the timezone.
The only solution I can offer is this: Set the date before you set the month.
This will work generally to avoid the rollover behavior of the javascript Date API:
d.setDate(1);
d.setFullYear(year);
d.setMonth(month);
d.setDate(day);
Given that year + month + day are in a "valid" combination, e.g. taken from another Date object using getFullYear(), getMonth(), getDate().
The important parts are:
starting with setDate(1) to avoid possible rollover when the current date value is 29, 30 or 31
call setMonth(month) before setDate(day) to avoid the same rollover in case the current month value is "problematic" (because then the initial setDate(1) would be without effect)