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?
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);
There are two problems here:
Date.parse()
to get a number, or new Date()
to get a Date object..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')
.
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));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.