Why do this dates not match? - javascript

i have this code which works with dates:
let startDate = new Date(toolOrder.jsAppStartDate.getTime()); // clone date
startDate.setDate(startDate.getDate() - Math.floor((days - 1) / 2)); // sub some days
console.log(toolOrder.jsAppStartDate); // Output: Date Thu Sep 21 2023 00:00:00 GMT+0200 (Central European Summer Time)
console.log(toolOrder.jsAppStartDate.getTime()); // Output: 1695247200000
console.log("--------------");
for (let index = 0; index < days; index++)
{
console.log(startDate);
console.log(startDate.getTime());
// ... some drawing code here ...
startDate.setDate(startDate.getDate() + 1); // add one day
if(startDate === toolOrder.jsAppStartDate) // check if start date reached
{
console.log("Dates match");
startDate = new Date(toolOrder.jsAppEndDate.getTime());
}
}
The output of the log before the loop is:
Date Thu Sep 21 2023 00:00:00 GMT+0200 (Central European Summer Time)
1695247200000
---------------
The output from the loop is:
Date Mon Sep 18 2023 00:00:00 GMT+0200 (Central European Summer Time)
1694988000000
Date Tue Sep 19 2023 00:00:00 GMT+0200 (Central European Summer Time)
1695074400000
Date Wed Sep 20 2023 00:00:00 GMT+0200 (Central European Summer Time)
1695160800000
Date Thu Sep 21 2023 00:00:00 GMT+0200 (Central European Summer Time)
1695247200000
Date Fri Sep 22 2023 00:00:00 GMT+0200 (Central European Summer Time)
1695333600000
So even if the dates match in loop 3, the if condition is not true. It works when I use
if(startDate.getTime() === toolOrder.jsAppStartDate.getTime())
but I thought it should work without also?

=== compares identity so:
startDate === toolOrder.jsAppStartDate
Means: is startDate the same object [in memory] as toolOrder.jsAppStartDate which is not the case because toolOrder.jsAppStartDate is a different object and not the object referred to by the name startDate.
mdn says this about the strict equality operator:
If both operands are objects, return true only if they refer to the same object.
(emphasis mine)
if(startDate.getTime() === toolOrder.jsAppStartDate.getTime())
Works because you're now comparing numbers instead of objects.
The rule for the two operands being numbers is:
Otherwise, compare the two operand's values:
Numbers must have the same numeric values. +0 and -0 are considered to be the same value.
mdn (emphasis mine)

You are comparing Date instances with each other when you're using the === operator. However, they are not the same instance. Each new Date creates a unique, new instance (unless the class constructor deliberately returns a previously created instance [for more info: singleton pattern]).
When you are comparing each instance's getTime() result, you are comparing 2 primitive values (numbers in this case). Primitive values are not class instances; so === works like == with primitives.

Related

Convert all dates in an array to format MM/DD/YYYY javascript

I have an array of dates in the format :
dates_arr = [
Thu Aug 13 2020 00:00:00 GMT-0400 (Eastern Daylight Time),
Fri Aug 14 2020 00:00:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 15 2020 00:00:00 GMT-0400 (Eastern Daylight Time),
Sun Aug 16 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
]
I would like to convert all the dates to the format MM/DD/YYYY and replace the array with them.
I would like to convert all the dates to the format MM/DD/YYYY and
replace the array.
You could do it as follows -
Correct Code -
let dates_arr = [
'Thu Aug 13 2020 00:00:00 GMT-0400 (Eastern Daylight Time)',
'Fri Aug 14 2020 00:00:00 GMT-0400 (Eastern Daylight Time)',
'Sat Aug 15 2020 00:00:00 GMT-0400 (Eastern Daylight Time)',
'Sun Aug 16 2020 00:00:00 GMT-0400 (Eastern Daylight Time)'
];
dates_arr = dates_arr.map((element) => {
var d = new Date(element);
return `${d.getMonth()+1}/${d.getDate()}/${d.getFullYear()}`;
})
console.log("Dates in the format MM/DD/YYYY : \n", dates_arr);
Explanation :
The strings which are present in dates_arr are the default way in which Javascript will output the dates. We are taking each of those strings and mapping over the dates_arr using map() function and simply returning the dates in the required format. This will create a new array with strings of date in the form we need them to be.
Firstly, I am creating a date object in the code using new Date(element). The Date() constructor can take in date string and form date object on which we can apply various in-built methods provided by JS as given below.
There are different methods which date provides us like
getMonth() which returns the month from 0-11
getDate() which returns the day of the month from 1-31 and
getFullYear() which returns the year in the date.
I have used these methods to get the date string into the desired format. There are various other methods as well which you can read more on here.
Also, if you are not aware, I am using template literals in the return statement which is just a syntactic sugar added in ES6. The return statement does the same thing as -
return ((d.getMonth()+1) + '/' + d.getDate() + '/' + d.getFullYear())
But using the template literals is just a more efficient way of writing such statements.
var formattedDate = dates_arr.map(date=>dateFormat(date));
function dateFormat(date){
const dateTimeFormat = new Intl.DateTimeFormat('en', { year: 'numeric', month: 'short', day: '2-digit' })
const [{ value: month },,{ value: day },,{ value: year }] = dateTimeFormat .formatToParts(date )
return `${month}/${day}/${year}`
}

Let value changes out of nowhere

Can someone please explain to me, why start and end variables print to console different values for these loggers?
I get printed out:
start1 = Mon Feb 17 2020 10:00:00 GMT+0100 (Central European Standard Time)
end1 = Mon Feb 17 2020 11:30:00 GMT+0100 (Central European Standard Time)
start2 = Mon Feb 17 2020 11:30:00 GMT+0100 (Central European Standard Time)
end2 = Mon Feb 17 2020 11:30:00 GMT+0100 (Central European Standard Time)
I want to add, that the code I presented is in some method of course, and the names start and end don't interfere with other variable names.
let start = this.service.getDateTime(
eventFromUi.start_date,
eventFromUi.start_time_hour,
eventFromUi.start_time_minute
);
console.log("start1 = " + start);
let end = this.service.getDateTime(
eventFromUi.start_date,
eventFromUi.end_time_hour,
eventFromUi.end_time_minute
);
console.log("end1 = " + end);
console.log("start2 = " + start);
console.log("end2 = " + end);
EDIT:
The getDateTime() method returns object of TypeScript ootb type Date.
I used Chrome debugger to look into this, and I see that when I first execute the getDateTime() method, I get value Mon Feb 17 2020 10:00:00 GMT+0100 (Central European Standard Time) returned and assigned to let start.
Then the method getDateTime() is executed again and retuns value Mon Feb 17 2020 11:30:00 GMT+0100 (Central European Standard Time), and this value gets assigned to both start and end variables.
How does this happen?
EDIT2:
Function getDateTime:
getDateTime(dateWithoutTime: Date, hour: number, minute: number): Date {
let date = dateWithoutTime;
console.log(date);
console.log(hour);
console.log(minute);
date.setHours(hour);
date.setMinutes(minute);
return date;
}
This is happening because you're dealing with object references.
getDateTime(dateWithoutTime: Date, hour: number, minute: number): Date {
let date = dateWithoutTime;
// date is now a copy of the *reference* to the same object that
// dateWithoutTime is a reference to. In other words: it is pointing
// to the same object in memory
date.setHours(hour);
date.setMinutes(minute);
// since date is pointing to the same object as dateWithoutTime, this is
// modifying both date and dateWithoutTime
return date;
}
This also means that in your code, eventFromUi.start_date, start and end are all references pointing to the same Date object.
To solve your problem, make sure you create a clone of dateWithoutTime when it is passed into your function:
getDateTime(dateWithoutTime: Date, hour: number, minute: number): Date {
let date = new Date(dateWithoutTime);
// date is now a reference to a *new Date object* with the same
// date/time/etc. values as dateWithoutTime
date.setHours(hour);
date.setMinutes(minute);
// since date now points to a new object, this is only modifying date
// while leaving dateWithoutTime alone and unchanged
return date;
}

Js new Date() creates different GMT

I'm reading data from a API server:
opTMP:
{ DATAI: "2019-10-27T00:00:00", …}
{ DATAI: "2019-10-31T00:00:00", …}
then I create a new date:
const opTMP1 = this.opTMP.map(x => Object.assign({}, x));
for (const op of opTMP1){
let d = new Date(op.DATAI);
console.log(d);
...
}
but in console I got different results,one is GMT+0300 and one GMT+0200 :
d: Sun Oct 27 2019 00:00:00 GMT+0300 (Eastern European Summer Time)
d: Thu Oct 31 2019 00:00:00 GMT+0200 (Eastern European Standard Time)
because of that I got problems when comparing it,I want to get only day month and year,no time info needed,how can I reset both to the same time or to 0:00:00?
Converting date to epoch time is good way to comparing the dates.
let d = new Date(op.DATAI).getTime();

Getting list of dates between two dates not returning correctly JS

I have a start date and an end date, and I want to generate a list of dates between (and including) these two dates. But I don't get why it isn't working...
I pass in a couple of JS date objects, I've shown what they log to the console below
function dateList(dateStart, dateEnd) {
console.log(dateStart);
console.log(dateEnd);
var dates = [];
for ( i = dateStart; i <= dateEnd; i.setDate(i.getDate() + 1) ){
dates.push(i);
}
return dates
}
Mon May 08 2017 00:00:00 GMT+0100 (BST)
Fri May 12 2017 00:00:00 GMT+0100 (BST)
The array that is returned is
Array[5]
0: Sat May 13 2017 00:00:00 GMT+0100 (BST)
1: Sat May 13 2017 00:00:00 GMT+0100 (BST)
2: Sat May 13 2017 00:00:00 GMT+0100 (BST)
3: Sat May 13 2017 00:00:00 GMT+0100 (BST)
4: Sat May 13 2017 00:00:00 GMT+0100 (BST)
length: 5
__proto__: Array[0]
...Why???......
Try to add new Date(i), instead of just i:
function dateList(dateStart, dateEnd) {
var dates = [];
for (i = dateStart; i <= dateEnd; i.setDate(i.getDate() + 1)){
dates.push(new Date(i));
}
return dates;
}
console.log(dateList(new Date('2017-05-08'), new Date('2017-05-12')));
Your code i.setDate(i.getDate() + 1) doesn't create a new date - it just updates the same Date object over and over. Then you push that object onto the array, which pushes a reference to that object - not a copy of the object.
A solution would be to create a new Date() inside the loop and setting the value of it, and then pushing this new date onto your array.
Because the same object is modified all elements referencing the same object

Javascript Date -> numeric vs string

var date1 = new Date('1900-01-01');
console.log(date1);
Yields:
"Mon Jan 01 1900 01:00:00 GMT+0100 (W. Europe Standard Time)"
var date2 = new Date(1900,1,1);
console.log(date2);
Yields:
"Thu Feb 01 1900 00:00:00 GMT+0100 (W. Europe Standard Time)"
Fiddle
But I don't understand why!
You can see the month difference since when you pass individual components (year, month, day, etc) to the Date object constructor, you have to consider that month parameter should start with 0:
console.log( new Date('1900-01-01').getMonth() ); // 0
Other than Jan/Feb there shouldn't be any differences in dates.
MDN: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date

Categories