Why is moment.js giving different results when assigned to a variable? - javascript

I have been debugging this for a little while now and still haven't been able to figure it out. Look specifically at the how the time in _d differs from the time in _i. Why?
var date = new Date('Fri, 06 Jan 2017 21:30:00 -0000')
const momentDate = moment(date)
console.log(`momentDate: `, momentDate);
console.log(`moment(date): `, moment(date));

So what was causing the problem was I had a react component that was overwriting the values to startOf('day'). If you're using moment to convert all your string dates flowing into your application into moment objects, if you experience bugs, make sure to look in your component and not just at the convertToMoment massaging functions for the API calls.
More importantly, until moment 3.0, all moment objects are mutable so if you do:
var a = moment()
var b = a.startOf('day')
console.log(a.format('LLL')) // January 22, 2017 12:00 AM
console.log(b.format('LLL')) // January 22, 2017 12:00 AM
The only way to fix this is either:
// use the cool `frozen-moment` package (which is basically a polyfill)
var a = moment().freeze()
var b = a.startOf('day')
console.log(a.format('LLL')) // January 22, 2017 2:17 AM
console.log(b.format('LLL')) // January 22, 2017 12:00 AM
// or type `.clone()` everytime you want to use a cool function
var a = moment()
var b = a.clone().startOf('day')
console.log(a.format('LLL')) // January 22, 2017 2:17 AM
console.log(b.format('LLL')) // January 22, 2017 12:00 AM

Related

What if I give parameter for Date.prototype.getTime()?

I create date in two ways:
new Date('some date').getTime();
new Date().getTime('some date');
I did it before I had read on MDN, that Date.prototype.getTime() doesn't have parameter. It means second way is wrong. Nevertheless, it gives the same date value the right way gives (new Date('*some date*').getTime();) but amount of milliseconds is different and I don't get why.
Could someone explain me?
(function () {
let dateToCount = "Jan 01, 2022 00:00:00";
let date1 = new Date(dateToCount).getTime();
let date2 = new Date().getTime(dateToCount);
console.log(Date(date1).toString()); // Tue Oct 19 2021 22:41:59 GMT+0300 (Eastern European Summer Time)
console.log(Date(date2).toString()); // Tue Oct 19 2021 22:41:59 GMT+0300 (Eastern European Summer Time)
console.log(`date1 = ${date1} ms`); // date1 = 1640988000000 ms
console.log(`date2 = ${date2} ms`); // date2 = 1634672519002 ms
console.log(`date1 - date2 = ${+date1 - (+date2)} ms`); // date1 - date2 = 6315480998 ms
})();
it gives the same date value the right way gives
No, it doesn't - it just that when you were debugging with console.log(Date(date1).toString()); you fell in yet another trap: missing the new operator in the call the Date. As MDN puts it:
Calling the Date() function (without the new keyword) returns a string representation of the current date and time, exactly as new Date().toString() does. Any arguments given in a Date() function call (without the new keyword) are ignored; regardless of whether it’s called with an invalid date string — or even called with any arbitrary object or other primitive as an argument — it always returns a string representation of the current date and time.
So if you fix that as well, you'll realise that the two different millisecond values you get back from getTime() actually do represent two different dates:
const dateToCount = "Jan 01, 2022 00:00:00";
const date1 = new Date(dateToCount).getTime();
const date2 = new Date().getTime(dateToCount);
console.log(new Date(date1).toString()); // Sat Jan 01 2022 00:00:00, as expected
console.log(new Date(date2).toString()); // Surprise!
console.log(`date1 = ${date1} ms`);
console.log(`date2 = ${date2} ms`);

How Can I use new Date().setHours(0,0,0) in a single line? [duplicate]

What is the simplest way to obtain an instance of new Date() but set the time at midnight?
The setHours method can take optional minutes, seconds and ms arguments, for example:
var d = new Date();
d.setHours(0,0,0,0);
That will set the time to 00:00:00.000 of your current timezone, if you want to work in UTC time, you can use the setUTCHours method.
Just wanted to clarify that the snippet from accepted answer gives the nearest midnight in the past:
var d = new Date();
d.setHours(0,0,0,0); // last midnight
If you want to get the nearest midnight in future, use the following code:
var d = new Date();
d.setHours(24,0,0,0); // next midnight
A one-liner for object configs:
new Date(new Date().setHours(0,0,0,0));
When creating an element:
dateFieldConfig = {
name: "mydate",
value: new Date(new Date().setHours(0, 0, 0, 0)),
}
Just going to add this here because I landed on this page looking for how to do this in moment.js and others may do too.
[Rationale: the word "moment" already appears elsewhere on this page so search engines direct here, and moment.js is widespread enough to warrant to being covered going on how often it is mentioned in other date-related SO questions]
So, in version 2.0.0 and above:
date.startOf('day');
For earlier versions:
date.sod();
Docs:
http://momentjs.com/docs/#/manipulating/start-of/
You can probably use
new Date().setUTCHours(0,0,0,0)
if you need the value only once.
If calculating with dates summertime will cause often 1 hour more or one hour less than midnight (CEST). This causes 1 day difference when dates return. So the dates have to round to the nearest midnight. So the code will be (thanks to jamisOn):
var d = new Date();
if(d.getHours() < 12) {
d.setHours(0,0,0,0); // previous midnight day
} else {
d.setHours(24,0,0,0); // next midnight day
}
Adding usefulness to #Dan's example, I had the need to find the next midday or midnight.
var d = new Date();
if(d.getHours() < 12) {
d.setHours(12,0,0,0); // next midnight/midday is midday
} else {
d.setHours(24,0,0,0); // next midnight/midday is midnight
}
This allowed me to set a frequency cap for an event, only allowing it to happen once in the morning and once in the afternoon for any visitor to my site. The date captured was used to set the expiration of the cookie.
I have made a couple prototypes to handle this for me.
// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
};
Date.method('endOfDay', function () {
var date = new Date(this);
date.setHours(23, 59, 59, 999);
return date;
});
Date.method('startOfDay', function () {
var date = new Date(this);
date.setHours(0, 0, 0, 0);
return date;
});
if you dont want the saftey check, then you can just use
Date.prototype.startOfDay = function(){
/*Method body here*/
};
Example usage:
var date = new Date($.now()); // $.now() requires jQuery
console.log('startOfDay: ' + date.startOfDay());
console.log('endOfDay: ' + date.endOfDay());
In case you already have d3.js as a dependency in your project, or don't mind bringing it in, d3-time (d3.js library is modular as of v4.0.0) has got Intervals.
They might prove useful when setting dates to "default" values, e.g. midnight, 0.00 seconds, the first of the month, etc.
var d = new Date(); // Wed Aug 02 2017 15:01:07 GMT+0200 (CEST)
d3.timeHour(d) // Wed Aug 02 2017 00:00:00 GMT+0200 (CEST)
d3.timeMonth(d) // Tue Aug 01 2017 00:00:00 GMT+0200 (CEST)
Using the dayjs library, you can use the startOf('day') method.
const dayjs = require('dayjs');
const todayAtMidnight= dayjs().startOf('day');
// Get as a native date object
console.log(todayAtMidnight.toDate());
To get the start of a particular day you can use the following:
const date = dayjs("2023-02-12").startOf('day');

How to create date object from string retrieved from JSON?

I would like to create a new Javascript date object and save it to a variable all from a JSON endpoint route. The JSON looks like this:
[
{
"class_instructor": 1,
"id": 1,
"location": "Boise",
"start_date_time": "Thu, 19 Nov 2020 09:10:00 GMT"
},
{
"class_instructor": 1,
"id": 2,
"location": "Meridian",
"start_date_time": "Mon, 16 Nov 2020 09:10:00 GMT"
}
]
I have been able to grab each objects value through iteration using Axios and saving it to a variable, however I would like to generate a javascript date object from the start_date_time value's strings. I am sure I can grab each of character of the string and eventually create the date object by individually adding each year, month, day... let this_date = new Date(2020, 11, 19, 9, 10)
However, this doesn't appear to be fullproof and there has got to be an easier way.
use this to create new date from your string
var getDateFrom = array[0].start_date_time;
var setDateTo = new Date(getDateFrom);
//this sets date using string format like you have
it is simple you need just to call Date with your string.
const a= new Date('Thu, 19 Nov 2020 09:10:00 GMT')
or in general :
const a= new Date('start_date_time')
you can verify that in console, when you click . after a a.
the properties and functions of the Date type will appear.

Date objects in dictionaries change timezone in Javascript/Node

To avoid day light saving issues with date objects, I use UTC. For example:
new Date(2019,8,20, 9, 0) gives 2019-09-20T08:00:00.000Z
new Date(Date.UTC(2019,8,20, 9, 0)) gives 2019-09-20T09:00:00.000Z -- what I want
My issue now is that when I add that date to a dictionary, It uses local timezone somehow. For example:
const b = {}
b[Date(Date.UTC(2019,8,20, 9, 0))] = true
gives the following:
{ 'Fri Sep 20 2019 10:00:00 GMT+0100 (IST)': true }
you can do the following to get the UTC time -
var utcDate = new Date(Date.UTC(2019,8,20,9,0)).toUTCString()
b[utcDate] = true
EDIT
You should use ISOString() format to get format like 2019-09-20T09:00:00.000Z
var utcDate = new Date(Date.UTC(2019,8,20,9,0)).toISOString()
b[utcDate] = true

Include millisecond data in JavaScript Date

I have a requirement to send the current system date to microservices on search. The time should include milliseconds information as well. For now I was sending new Date() for the same and it looked like:
Thu Aug 31 2017 15:06:37 GMT+0530 (India Standard Time)
However I need the milliseconds information as well so the time should look like:
Thu Aug 31 2017 15:06:37.228 GMT+0530 (India Standard Time)
Here 228 is the millisecond at that moment that I can extract using getMilliseconds() method of date. The question is how can I add this in the date so that it works for all locations wherever the application is accessed?
If you don't mind having the result as a string, this will show the output you are looking for:
// ES5
var fmtDateMsES5 = function(date) {
var splitDate = date.toString().split(' ');
splitDate[4] = splitDate[4] + '.' + date.getMilliseconds();
return splitDate.join(' ');
}
// log output (ES5)
console.log('ES5 output\n', fmtDateMsES5(new Date()));
// ES6
const fmtDateMsES6 = date => {
const splitDate = date.toString().split(' ');
splitDate[4] = `${splitDate[4]}.${date.getMilliseconds()}`;
return splitDate.join(' ');
};
// log output (ES6)
console.log('ES6 output\n', fmtDateMsES6(new Date()));
// ES5 and ES6 functions logged simultaneously
console.log(
`\nES5 and ES6 functions logged simultaneously`,
`\n${'-'.repeat(55)}`,
`\nES5 output ${fmtDateMsES5(new Date())}`,
`\nES6 output ${fmtDateMsES6(new Date())}`
);
Initially I saw the format method on the Date object but this is not built-in and requires a library.
If you must use a time library I would recommend the excellent moment.js and use the "SSS" syntax to get the milliseconds, for example:
var now = moment().format('MMM DD h:mm.SSS A');
//Sep 12 8:21.167 AM
http://jsfiddle.net/kLL2eobh/

Categories