Why is this momentjs date incorrect? - javascript

Here is my code:
var moment = require("moment");
var day = 31;
var month = 12;
var year = 2016;
moment().date(day).month(month - 1).year(year)
The date that is returned is Sat Dec 03 2016 16:23:43 GMT-0700 (MST).
Why is the date being converted to 03 instead of 31?

This line is processed in multiple steps: moment().date(day).month(month - 1).year(year)
First: moment().date(31)
It is currently February 7th, 2017. We are changing it to "February 31st, 2017", which wraps around to March 3rd since February has only 28 days.
Then it changes the month to 12, and the year to 2016.
Flip the steps around. Do the year first, then month, then date.

Related

Moment.js - How to convert time formats correctly to properly do time zone conversions

The code below is at moment-timezone documentation and it works perfectly. The result is what I want.
https://momentjs.com/timezone/
import moment from 'moment-timezone';
let timeInput = "2014-06-01 12:00";
var newYork = moment.tz(timeInput, "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
console.log(newYork.format("LLLL")); // Sunday, June 1, 2014 12:00 PM
console.log(losAngeles.format("LLLL")); // Sunday, June 1, 2014 9:00 AM
console.log(london.format("LLLL")); // Sunday, June 1, 2014 5:00 PM
The problem
I am using a date/time material picker widget that outputs a date object. When I try to format the date/time the result is the following:
let timeAndDate = moment(dateObj).format("LLL");
// Thursday, December 26, 2019 12:00 PM
// I can also get "2019-12-26T00:00:00-08:00" by doing format()
In the code below I expect the time offsets to be the same as the initial code I posted above - it is not.
import moment from 'moment-timezone';
let timeInput = "Thursday, December 26, 2019 12:00 PM";
var newYork = moment.tz(timeInput, "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
console.log(newYork.format("LLLL")); // Thursday, December 26, 2019 7:00 AM
console.log(losAngeles.format("LLLL")); // Thursday, December 26, 2019 4:00 AM
console.log(london.format("LLLL")); // Thursday, December 26, 2019 12:00 PM
My question is, how do I take a date that is formatted like this:
"Thursday, December 26, 2019 12:00 PM" and convert it to format like "2019-12-26 12:00" so that I can convert between time zones correctly in my app?
Use newYork.format("YYYY-MM-DD HH:mm")

Function returns incorrect month depending on order of statements

Does anyone have any thoughts on why this might have happened? Today, I found that a date conversion function I wrote started returning the wrong month. For instance, when attempting to convert "2017-06-02" to "Fri Jun 02 2017 00:00:00 GMT-0600 (Mountain Daylight Time)", it actually returned July instead of June. When I re-arranged the order of some of the statements in the function, the correct date was finally returned. This code has been in place for many months, so this spontaneous...maybe due to the current month changing, as today is 5/31/17? This might only be broken when ran on todays date, or end-of-month? (I'm sure there's a better way to convert dates, but here's the code in question anyway):
<!doctype html>
<body onload="testDate()">
<div id="resultbad"></div>
<div id="resultgood"></div>
<script>
function testDate() {
document.getElementById("resultbad").innerHTML = "Bad Result: Converting 2017-06-02 returns: " + badDate("2017-06-02");
//returns: Bad Result: Converting 2017-06-02 returns: Sun Jul 02 2017 00:00:00 GMT-0600 (Mountain Daylight Time)
document.getElementById("resultgood").innerHTML = "Good Result: Converting 2017-06-02 returns: " + goodDate("2017-06-02");
//returns: Good Result: Converting 2017-06-02 returns: Fri Jun 02 2017 00:00:00 GMT-0600 (Mountain Daylight Time)
}
function badDate(d) {
var td = d.split('-');
var nd = new Date();
//originally ordered: Year, Month then Day
nd.setFullYear(td[0]);
nd.setMonth(td[1] - 1);
nd.setDate(td[2]);
//set time
nd.setHours(0);
nd.setMinutes(0,0,0);
return nd;
}
function goodDate(d) {
var td = d.split('-');
var nd = new Date();
//new order: Day, Month then Year
nd.setDate(td[2]);
nd.setMonth(td[1] - 1);
nd.setFullYear(td[0]);
//set time
nd.setHours(0);
nd.setMinutes(0,0,0);
return nd;
}
</script>
</body>
This code overrides the date elements based on today's date. So, if you are running the code on the 31st day of the month, the "bad" version of this code will overwrite the month first, and if that month only has 30 days, it will roll over to the next month.
Basically, after setMonth but before setDate, you are trying to create the date June 31, 2017, which JS will convert for you into July 1, 2017.
Instead, do this as one call:
new Date(td[0], td[1]-1, td[2], 0, 0, 0, 0)
You figured out the problem fairly well - it has to do with today being the 31st of the month.
The issue is that new Date() creates a date object with the fields filled in. You're then changing those fields one by one.
So right now we can think of it as having a pseudo-structure like this, remembering that month is 0-based:
{
year: 2017
month: 4
date: 31
}
when you call setMonth(), you're just changing the month field, so you'd think for June it would set it to
{
year: 2017
month: 5
date: 31
}
but it knows there aren't 31 days in June. The 31st "day" of June would be the 1st of July. So it helps you out and adjusts it to
{
year: 2017
month: 6
date: 1
}
You're then setting the date to the 2nd with setDate():
{
year: 2017
month: 6
date: 2
}
In the function that works, you're setting the date before the month, so you're not having it recompute what the day is in case you've specified a date that is larger than the number of days in the month.

Javascript is giving invalid month when month is set to 5

I am getting invalid date when I set month as 5 in JavaScript date object.
I know that Month is zero based. so, month 5 means June.
But I am getting month as July.
<!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="demo1"></p>
<p id="demo"></p>
<script>
function myFunction() {
var d = new Date();
d.setYear(2017);
d.setMonth(5);
d.setDate(30);
document.getElementById("demo1").innerHTML = d.getMonth();
document.getElementById("demo").innerHTML = d;
}
</script>
</body>
</html>
Output:
6
Sun Jul 30 2017 15:11:20 GMT+0200 (W. Europe Daylight Time)
But, Ideally the output should be:
5
Sat Jun 30 2017 15:11:20 GMT+0200 (W. Europe Daylight Time)
Here is what happens:
var d = new Date();
//d is today : which is 31st of May (day of your test)
d.setMonth(5)
//5 is June (setMonth starts at 0)
//As 31st of June doesn't exist, it is set as 1st of July.
d.setDate(30)
//d is now 30th of July
You'd better use the full Date constructor:
new Date(year, month, date);
Today is May 31st 2017.
When you set the month to 5 which is June, the day is still 31 but there is no June 31. At this point behavior is undefined or at least unclear; anything could happen really.
To avoid it, create the date like this:
var date = new Date(2017, 5, 30);
This is because setMonth will also set the day, but we are on 31 and June only contains 30 days, so the date will change to 1 July. Then on July 30th thanks to the setDay. Try to set the day before, normally it should work.

Wrong result when converting a date

I am just a beginner. My original date is: Friday, September 16th 2016, 09:00
And I need to convert it to this format: Fri Sep 16 2016 09:00:00 GMT+0000 (GMT)
But my code shows wrong date: Tue Sep 06 2016 09:00:00 GMT+0100 (BST)
Please see my code here:
var startdate = "Friday, September 16th 2016, 09:00";
var sdate = new Date(startdate.replace(/(\d)+(st|nd|th)/g, '$1'));
alert(new Date(sdate));
Can anybody help me with this issue? The example is here: https://jsfiddle.net/5hzwbbku/3/
By using momentjs I receive the strange results: https://jsfiddle.net/5hzwbbku/13/
Your regex is incorrect. /(\d)+(st|nd|th)/g matches the 16th but the captured group only contains 6. In order to return 16 your regex needs to be /(\d+)(st|nd|th)/g, like so:
var sdate = new Date(startdate.replace(/(\d+)(st|nd|th)/g, '$1'));
If you need the time to be in UTC, you'll have to append a timezone such as +0, +0000, or simply Z (for Zulu time).
var startdate = "Friday, September 16th 2016, 09:00";
startdate = startdate + ' +0000';
var sdate = new Date(startdate.replace(/(\d+)(st|nd|th)/g, '$1'));
alert(new Date(sdate));
On my system that returns Fri Sep 16 2016 11:00:00 GMT+0200 (CEST) which is 09:00 in UTC.
Other regexes that match correctly are /(\d)(st|nd|th)/g (note the complete absence of the +) and the one given by pastine in the comments /(.\d)+(st|nd|th)/g.

Convert date to end of day

I get time in milliseconds from the server. I convert it to Date and get -
Mon Jul 22 2013 11:16:01 GMT+0200 (W. Europe Daylight Time) as the date in the record.
I want to separate out data of Monday, Tuesday etc into arrays. I am thinking of converting this date to Mon Jul 22 2013 23:59:59 GMT+0200 (W. Europe Daylight Time) and then filter out the records.
How can i change the date to the required end of the day time? or is there an easier way to do this ?
You could always construct a new DateTime object just using the year, month and day properties from the existing date, like so:
var actualDate = new Date(); // 2013-07-30 17:11:00
var endOfDayDate = new Date(actualDate.getFullYear()
,actualDate.getMonth()
,actualDate.getDate()
,23,59,59); // 2013-07-30 23:59:59
For future visitors, just use
var start = new Date();
var end = new Date();
start.setHours(0,0,0,0);
end.setHours(23,59,59,999);
Using http://momentjs.com:
var now = new Date().getTime();
var endOfDay = moment(now).endOf("day").toDate(); // Wed Jan 20 2016 23:59:59 GMT-0800 (PST)
var actualDate = new Date()
var eodDate = new Date(Math.floor(actualDate.getTime()/86400000+1)*86400000 + actualDate .getTimezoneOffset()*60000 - 1000)
where 86400000 are total milliseconds in a day
If two Date Objects are on the same day then they have the same Date String:
new Date('1374488161000').toDateString()
=> "Tue Jul 30 2013"
new Date('13744917610403').toDateString()
=> "Tue Jul 30 2013"
Although a rather naive method of comparing days, it's probably the simplest comparison.

Categories