How to compare start date and end date in javascript [duplicate] - javascript

I have the following string value of a date, Sun Apr 07 2019 00:00:00 GMT-0300, and I need to compare with the following date format 2019-04-08T03:00:00.000Z, note that both are the same day, I need to compare them and return a true as being equal days,
but I do not know how to do this using javascript, any help?
I tried to do something like this but it does not return me true:
if (input) {
//input.value = "Sun Apr 07 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)"
var situation = angular.isArray(item.situation) ? item.situation : [item.situation];
// situation =
//[
// 0: "2019-04-08T03:00:00.000Z"
// 1: "2019-04-13T03:00:00.000Z"
//]
if (!angular.isArray(input.value)) {
condition = situation.indexOf(input.value) >= 0;
} else if (angular.isArray(input.value)) {
condition = $window._.intersection(situation, input.value).length > 0;
}
}
if (condition) {
break;
}
//input.value = "Sun Apr 07 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)"
situation =
[
0: "2019-04-08T03:00:00.000Z"
1: "2019-04-13T03:00:00.000Z"
]

Sun Apr 07 2019 00:00:00 GMT-0300
2019-04-08T03:00:00.000Z
note that both are the same day
No, they are not.
You can convert them both to ISO string and just compare their date parts as strings (if I understood the question correctly, you want to compare date only, without time):
function isSameDate(date1, date2) {
const [d1, ] = (new Date(date1)).toISOString().split('T');
const [d2, ] = (new Date(date2)).toISOString().split('T');
return d1 === d2;
}

Convert all the values to Date objects and compare those. Use a framework/library to do it, because parsing strings to dates manually has lots of places where it can go wrong.
Currently you are comparing the literal Strings. Because neither "2019-04-08T03:00:00.000Z", nor "2019-04-13T03:00:00.000Z" match "Sun Apr 07 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)", your second if statement fails.

Build a date from the strings and compare the days (ie number of seconds since epoch / number of seconds in a day):
const sameDay = (dateString1, dateString2) => {
let time1 = (new Date(dateString1)).getTime();
let time2 = (new Date(dateString2)).getTime();
return Math.floor(Math.abs((time1-time2))/(1000*60*60*24))==0;
}
console.log(
sameDay('Sun Apr 07 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)','2019-04-08T03:00:00.000Z'),
sameDay('Sun Apr 07 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)','2019-04-13T03:00:00.000Z'),
);

Related

How can i find next smallest Element Key by Value in Object?

I have an object like this:
times = {
"dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)",
"dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)",
"evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)",
"morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)"
};
I want to compare the current time with this object and want to get the key as return value, which is closest to the current time.
I try to use this function, but I never get the right key back.
function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value || object[key] < value);
}
let date = new Date();
getKeyByValue(times, date);
What do I have to change for this to work?
There are two problems here:
You're comparing strings, not dates. Use Date.parse() to get a number, or new Date() to get a Date object.
You're only looking for the first matching value with .find(), not the closest. You'll have to use a more custom solution to find the closest.
This will find the time before the given time which is closest:
// Just so this example works in the future, while still
// comparing against the current time:
const makeTime = (h, m) => {
const today = new Date();
return new Date(today.getFullYear(), today.getMonth(), today.getDate(), h, m);
}
const times = {
"dawn": makeTime(05, 00), // 5:00am
"morning": makeTime(07, 00), // 7:00am
"afternoon": makeTime(12, 00), // 12:00pm
"late afternoon": makeTime(17, 00), // 5:00pm
"dusk": makeTime(19, 00), // 7:00pm
"evening": makeTime(20, 00), // 8:00pm
"night": makeTime(23, 00) // 11:00pm
};
// The important part is here:
const closestTime = Object.entries(times)
.map(([k, v]) => [ k, Date.now() - Date.parse(v) ])
.reduce((pre, cur) => cur[1] < pre[1] && cur[1] > 0 ? cur : pre)[0];
console.log(`Right now, it is ${closestTime}.`);
Here's how it works:
// Get a list of [ key, value ] lists for every key and value in `times`.
const closestTime = Object.entries(times)
// Turn that list of [ key, value ] and turn it into a list of keys and
// the differences between compareTime and the date in the value. Values
// in the future create negative numbers, since their Unix Epoch
// representation is larger than the compared time.
// IE: [ [ 'morning', 12300000 /* (seconds) */ ], ... ]
.map(([k, v]) => [ k, Date.now() - Date.parse(v) ])
// Run through that list, keeping track of the current value only if it
// is smaller than the previous value and positive.
.reduce((pre, cur) => cur[1] < pre[1] && cur[1] > 0 ? cur : pre)
// ↑ returns [ key, value ], and we just want `key`.
[0];
If you want to compare against a specific time, replace Date.now() with Date.parse() and pass in a date string, like Date.parse('Jul 07 2020 11:25:00').
You need to parse the dates in your times object.
Currently, JavaScript is just seeing them as strings so you're comparing a string to a number which returns false.
Try using Date.parse(object[key]). This returns a number.
Convert them to date objects, get the smallest delta, iterate em.
var times = {
"dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)",
"dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)",
"evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)",
"morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)"
};
var closestKey = null;
var closestDelta = null;
for(key in times)
{
var delta = Math.abs(Date.now() - Date.parse(times[key]));
if(delta < closestDelta || closestDelta == null)
{
closestKey = key;
closestDelta = delta;
}
}
console.log("The closest is:" + closestKey);
Please check it out
times = {
"dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)",
"dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)",
"evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)",
"morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)"
};
let obj = {}
for (time in times){
Object.assign(obj, {[time]:Math.abs(new Date() - new Date(times[time]).getTime())});
}
//console.log(obj)
function closestDate(obj){
let closestVal = Math.min(...Object.values(obj))
for (item in obj){
if(obj[item] === closestVal){
return item;
}
}
}
console.log(closestDate(obj));

How correctly check if 2 date (having different time) are in the same day (day, month, yeah) using JavaScript?

I am not so into JavaScript and I have to check if 2 date have the same day\month\year (not the time, so only if the day is the same). I have to use only old plain JavaScript
I have 2 Date variable and I was trying to do in this way:
if(previousDate.getDate() === dateCurrentForecast.getDate()) {
console.log("SAME DATE");
}
Where:
previousDate = Sun Nov 05 2017 06:00:00 GMT+0100 (ora solare Europa occidentale)
dateCurrentForecast = Sun Nov 05 2017 12:00:00 GMT+0100 (ora solare Europa occidentale)
I have to find a way to check that these 2 date are in the same day (Sun Nov 05 2017).
Using the previous snipet it seems to work because both previousDate.getDate() and dateCurrentForecast.getDate() returns the value 5, but what exactly means this returned value?
What is the correct way to do this kind of check?
You can remove timestamp part of date and then compare the value:
Note: Remember to create new objects else you will mutate original objects.
function isSameDay(d1, d2) {
var _d1 = new Date(+d1);
var _d2 = new Date(+d2);
_d1.setHours(0,0,0,0)
_d2.setHours(0,0,0,0)
return +_d1 === +_d2;
}
var d1 = new Date('Sun Nov 05 2017 06:00:00 GMT+0100 (ora solare Europa occidentale)');
var d2 = new Date('Sun Nov 05 2017 12:00:00 GMT+0100 (ora solare Europa occidentale)')
console.log(isSameDay(d1, d2))
or you can check for values manually:
function isSameDay(d1, d2) {
return d1.getDate() === d2.getDate() &&
d2.getMonth() === d2.getMonth() &&
d1.getFullYear === d2.getFullYear();
}
var d1 = new Date('Sun Nov 05 2017 06:00:00 GMT+0100 (ora solare Europa occidentale)');
var d2 = new Date('Sun Nov 05 2017 12:00:00 GMT+0100 (ora solare Europa occidentale)')
console.log(isSameDay(d1, d2))
JavaScript Date object methods are sometimes unobvious because getDate method returns day of the month and not a date string as it might be expected from method name.
You can accomplish your task by creating copy of your date objects and comparing them. It may be good idea to use UTC versions of methods to avoid cross-timezone differences:
function isSameDay(d1, d2) {
var date1 = new Date(Date.UTC(d1.getYear(), d1.getMonth(), d1.getDay()));
var date2 = new Date(Date.UTC(d2.getYear(), d2.getMonth(), d2.getDay()));
return date1.getTime() === date2.getTime();
}
console.log(isSameDay(
new Date('Sun Nov 05 2017 06:00:00 GMT+0100'),
new Date('Sun Nov 05 2017 12:00:00 GMT+0100')
));
console.log(isSameDay(
new Date('Sun Nov 06 2017 06:00:00 GMT+0100'),
new Date('Sun Nov 05 2017 12:00:00 GMT+0100')
));
Your actual code will work even if the two dates have different months or years when they have the same day.
You need to check upon year, month and day:
function areThe2DatesEqualByDay(d1, d2) {
if (d1.getYear() === d2.getYear()) {
if (d1.getMonth() === d2.getMonth()) {
if (d1.getDate() === d2.getDate())
return true;
}
}
return false;
}
Demo:
var previousDate = "Sun Nov 05 2017 06:00:00 GMT+0100";
var dateCurrentForecast = "Sun Nov 05 2017 12:00:00 GMT+0100";
var diffDate = "Sun Mar 05 2017 12:00:00 GMT+0100";
function areThe2DatesEqualByDay(d1, d2) {
if (d1.getYear() === d2.getYear()) {
if (d1.getMonth() === d2.getMonth()) {
if (d1.getDate() === d2.getDate())
return true;
}
}
return false;
}
console.log(areThe2DatesEqualByDay(new Date(), new Date()));
console.log(areThe2DatesEqualByDay(new Date(previousDate), new Date(dateCurrentForecast)));
console.log(areThe2DatesEqualByDay(new Date(previousDate), new Date(diffDate)));
getDate returns the day of the month. So you are now only checking if the day of the month is the samen. With getMonth and getYear you could check the month and the year of both dates.
if (previousDate.getDate() === dateCurrentForecast.getDate() && previousDate.getMonth() === dateCurrentForecast.getMonth() && previousDate.getYear() === dateCurrentForecast.getYear()) { console.log('the same'); }
The getDate function returns the day of the month, that the Date object represents. So to check if two Date objects represents the say day, while ignoring the time of day, you need to compare the day of month, the month, and the year.
var d1 = new Date("Sun Nov 05 2017 06:00:00 GMT+0100");
var d2 = new Date("Sun Nov 05 2017 12:00:00 GMT+0100");
var sameDate = d1.getDate() === d2.getDate() && d1.getMonth() === d2.getMonth() && d1.getYear() == d2.getYear();
console.log("Are they the same date?", sameDate);

How to check if two arrays of dates have matching items?

I have two arrays of dates. The first one have all the booked dates and the second one will have dates between "start day" and "end day" which user will pick.
Now I have to confirm that the days between the start and stop will not be found from the fully booked dates array.
I'm using Vue.js to update data.
Here is what I have done to get those dates:
/**
* Get dates from datepicker and format it to the same format that fully booked array has it's dates.
**/
var day1 = moment( this.startDate, 'DD/MM/Y').format('Y,M,D');
var day2 = moment( this.endDate, 'DD/MM/Y').format('Y,M,D');
var start = new Date(day1);
var end = new Date(day2);
/**
* Get dates between start and stop and return them in the dateArray.
**/
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
};
function getDates(startDate, stopDate) {
var dateArray = [];
var currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(currentDate);
currentDate = currentDate.addDays(1);
}
return dateArray;
}
var dateArray = getDates(start, end);
/**
* Set dateArray in to Vue.js data.
**/
this.$set('daysBetweenStartStop', dateArray);
/**
* Get arrays of dates from the Vue.js data. calendar = Booked dates | matchingDays = Dates between start and stop.
**/
var calendar = this.fullDates;
var matchingDays = this.daysBetweenStartStop;
/**
* #description determine if an array contains one or more items from another array.
* #param {array} haystack the array to search.
* #param {array} arr the array providing items to check for in the haystack.
* #return {boolean} true|false if haystack contains at least one item from arr.
*/
var findIfMatch = function (haystack, arr) {
return arr.some(function (v) {
return haystack.indexOf(v) >= 0;
});
};
var matching = findIfMatch(calendar, matchingDays);
/**
* Check the results. If false we are good to go.
**/
if (matching){
alert('WE FOUND A MATCH');
} else {
alert('GOOD TO GO');
}
Arrays are in the following format:
var calendar = [
Sun Oct 02 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 09 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 16 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 23 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
]
var matchingDays = [
Fri Oct 28 2016 00:00:00 GMT+0300 (EEST),
Sat Oct 29 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
]
My problem is that even if those two arrays have exactly same dates they will still somehow be considered as a not identical. Any ideas how to get this working?
Your match function should look like this :
findIfMatch = function (haystack, arr){
var i = 0;//array index
var j = 0;//array index
while(j < arr.length && i < haystack.length){
cur_cal = Date.parse(haystack[i]);
cur_match = Date.parse(arr[j]);
if(cur_cal > cur_match){
j++;
}else if(cur_cal < cur_match){
i++;
}else{
return true;
}
}
return false;
}
To get matching records from two array use this
var calendar = [
Sun Oct 02 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 09 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 16 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 23 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
];
var matchingDays = [
Fri Oct 28 2016 00:00:00 GMT+0300 (EEST),
Sat Oct 29 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
];
var newCalendar = [];
var newMatchingDays = []
$.map(calendar, function(date){
newCalendar.push(date.toString())
});
$.map(matchingDays, function(date){
newMatchingDays.push(date.toString())
});
var result = [];
$.map(newCalendar, function (val, i) {
if ($.inArray(val, newMatchingDays) > -1) {
result.push(val);
}
});
console.log(result);
Firstly you can't compare dates like that, Date is an object.
eg.
var d1 = new Date('2016-09-30');
var d1 = new Date('2016-09-30');
console.log(d1 === d2); // = false
You would need to loop the array and compare each item, rather than use indexOf.
or maybe use the Array.filter(). Or alternatively use and object as a lookup.
eg. If say you had ->
var calendar = {
"Sun Oct 02 2016 00:00:00 GMT+0300 (EEST)": true,
"Sun Oct 09 2016 00:00:00 GMT+0300 (EEST)": true,
"Sun Oct 16 2016 00:00:00 GMT+0300 (EEST)": true,
"Sun Oct 23 2016 00:00:00 GMT+0300 (EEST)": true,
"Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)": true
};
if (calendar["Sun Oct 16 2016 00:00:00 GMT+0300 (EEST)"]) {
console.log("We have date");
}
Notice how I use a string representation for the date, this could be a number too, eg. from Date.getTime().
Here is using Array.filter, I don't think it's as fast a Object lookup's. But here we go.
var calendar = [
new Date('2016-09-01'),
new Date('2016-09-12'),
new Date('2016-09-10')
];
var finddate = new Date('2016-09-12');
var found = calendar.filter(function (a) { return a.getTime() === finddate.getTime();});
And if you don't mind using third party library, try underscore..
eg.
var days = [new Date('2016-09-01'), new Date('2016-09-10'), new Date('2016-09-30')];
var finddays = [new Date('2016-09-01'), new Date('2016-09-30')];
var found = _.intersectionWith(days, finddays,
function (a,b) { return a.getTime() === b.getTime(); });

creating a date range from 2 dates with linq.js and momentjs

I want to get all dates between a startDate and an endDate.
I wrap the startDate/endDate with moment() again to clone the start/endDate because they must not be changed.
But still the getDateRange gives me odd results about dates:
testCase.startDate = moment(new Date(2014, 0, 1));
testCase.endDate = moment(new Date(2014, 0, 27));
Although both dates are in 2014 I get a dateRange from december 2013 days?
Why is that?
function getDateRange(startDate, endDate) {
return Enumerable.range(0, moment(endDate).diff(moment(startDate), 'days') + 1)
.select(function (offset) {
return moment(startDate).add(offset, 'days')
})
.toArray();
}
UPDATE
Your query looks like it should work. Maybe you're interpreting the dates incorrectly. Remember, only the month starts at 0. Maybe you offset the year too when you looked at the values.
Here's an alternate way you can write the query:
function getDateRange(startDate, endDate) {
return Enumerable.Unfold(startDate, "moment($).add(1, 'd')")
.TakeWhile(function (d) { return d <= endDate; })
.ToArray();
}
Based on what I'm seeing in the comments, it appears you're using methods which mutates the dates. You'll either want to avoid using these methods or clone the date first and manipulate the clones.
// without cloning
var date1 = moment.utc([2014, 0, 1]);
console.log(String(date1)); // Wed Jan 01 2014 00:00:00 GMT+0000
var startOfDate1 = date1.startOf('week'); // mutated
console.log(String(date1)); // Sun Dec 29 2013 00:00:00 GMT+0000
// using moment()
var date2 = moment.utc([2014, 0, 1]);
console.log(String(date2)); // Wed Jan 01 2014 00:00:00 GMT+0000
var startOfDate2 = moment(date2).startOf('week'); // not mutated
console.log(String(date2)); // Wed Jan 01 2014 00:00:00 GMT+0000
// using clone()
var date3 = moment.utc([2014, 0, 1]);
console.log(String(date3)); // Wed Jan 01 2014 00:00:00 GMT+0000
var startOfDate3 = date3.clone().startOf('week'); // not mutated
console.log(String(date3)); // Wed Jan 01 2014 00:00:00 GMT+0000

Using a Date as the hash table key

How can I create a hash table object in JavaSript and use a date as the key? So far I've got this:
var eventHash = {};
for (var i = 0, l = events.length; i < l; i += 1) {
eventHash[events[i].date.getTime()] = events[i];
}
And then when I want to find the event associated with today I would use this:
var event = eventHash[(new Date(2011, 04, 26, 0, 0, 0, 0)).getTime()];
Can anyone see any pitfalls with this solution, or have any suggestions for improvement?
Why wouldn't you just use an ISO8601 representation of the date, so the key would be like 20110426. Creating a date object seems a bit inefficient.
It would also make debugging easier as the property names are more human readable, even if you add hhmmss also.
The only issue I see is that it's pretty limiting if you suddenly need to have multiple events with the same date. Otherwise it should be alright.
Also: Today is May 23, not Apr 26 :)
I have a somewhat similar problem and my solution may help others.
I have a list of "entries", each entry has a timestamp and a value.
I want to divide them up into "buckets", one for each day.
In Python I would have used collections.defaultdict but since JavaScript does not have something like that I do the following.
If you want to read the keys, remember that when you use a Date as an object key it gets converted as a string.
var get_entries = function() {
var entries = [];
entries.push({
'timestamp': 1381831606,
'value': 3
});
entries.push({
'timestamp': 1381831406,
'value': 2
});
entries.push({
'timestamp': 1381531606,
'value': 6
});
entries.push({
'timestamp': 1381221606,
'value': 9
});
entries.push({
'timestamp': 1381221601,
'value': 8
});
entries.push({
'timestamp': 1381221656,
'value': 7
});
return entries;
};
var normalize_date = function(timestamp) {
// JavaScript timestamps work with milliseconds.
var dt = new Date(timestamp * 1000);
return new Date(
dt.getFullYear(),
dt.getMonth(),
dt.getDate()
);
};
var prepare_data = function() {
var entry,
line = {};
var entries_raw = get_entries();
for (var i = 0; i < entries_raw.length; i++) {
entry = entries_raw[i];
entry.date = normalize_date(entries_raw[i].timestamp);
// If date not exists in line, create it.
console.log('Found entry for date', entry.date, 'with value', entry.value);
if (typeof(line[entry.date]) === 'undefined'){
line[entry.date] = 0;
}
line[entry.date] += entry.value;
}
console.log(line);
return line;
};
prepare_data();
Output:
$ nodejs diaryindex.js
Found entry for date Tue Oct 15 2013 00:00:00 GMT+0200 (CEST) with value 3
Found entry for date Tue Oct 15 2013 00:00:00 GMT+0200 (CEST) with value 2
Found entry for date Sat Oct 12 2013 00:00:00 GMT+0200 (CEST) with value 6
Found entry for date Tue Oct 08 2013 00:00:00 GMT+0200 (CEST) with value 9
Found entry for date Tue Oct 08 2013 00:00:00 GMT+0200 (CEST) with value 8
Found entry for date Tue Oct 08 2013 00:00:00 GMT+0200 (CEST) with value 7
{ 'Tue Oct 15 2013 00:00:00 GMT+0200 (CEST)': 5,
'Sat Oct 12 2013 00:00:00 GMT+0200 (CEST)': 6,
'Tue Oct 08 2013 00:00:00 GMT+0200 (CEST)': 24 }

Categories

Resources