How to round to the nearest date using JavaScript Date Object?
I have 2020-10-14T18:10:48.960Z and I want it a function that returns 2020-10-15T05:00:00.000Z which is the closest date in my timezone CST. Or if I give it 2020-10-14T16:10:48.960Z I want it to return 2020-10-14T05:00:00.000Z.
The easiest way I can think of is to just add 12 hours to the date, then truncate the time portion. This has the effect of rounding to the nearest date (anything before noon just has the time truncated, anything after goes to the next day, then has the time truncated).
let d = new Date();
// add 12 hours to the date
d.setTime(d.getTime() + (12*60*60*1000));
// truncate the time
d.setHours(0,0,0,0);
console.log(d);
You can check the hour and if it's before 12, set to the time to 00:00:00. If it's 12 or after, set the time to 24:00:00, e.g.
let d = new Date();
d.setHours(d.getHours() < 12? 0 : 24, 0,0,0);
console.log(d.toISOString() + '\n' + d.toString());
//this code will round to the nearest date
const roundToNearestDay = (date) => {
let isPastNoon = date.getHours() >= 12
if (isPastNoon)
//if first parameter > 23, will increment date +1
date.setHours(24,0,0,0)
else
date.setHours(0,0,0,0)
return date
}
let nearestDay = roundToNearestDay(new Date())
console.log(nearestDay)
Related
I am using the following function to convert my date in RFC3339. I want it to convert in upper limit.
Can anyone assist me, how do I convert it to upper limit?
const date = new Date();
// RFC 3339 format
const targetTime = date.toISOString();
Current output is:
2022-12-20T05:26:12.968Z
Expected output should be
2022-12-20T06:00:00Z
See this answer, very similar but you can replace Math.round with Math.ceil to round up like you want and in addition you'll need to get the percentage the hour is complete (assuming you don't want to round up exact hours).
const milliSecondsInHour = 60*60*1000;
const roundDateToNextHour = (date: Date) => {
const percentHourComplete = (x.getTime() % milliSecondsInHour) / milliSecondsInHour;
date.setHours(date.getHours() + Math.ceil(percentHourComplete));
date.setMinutes(0, 0, 0); // Resets also seconds and milliseconds
return date;
}
If the intention is to the next full UTC hour, test if UTC minutes, seconds or milliseconds are greater than zero. If any of them are, increment the hour and zero the other values, e.g.:
// If the provided date is not exactly on the UTC hour,
// return a date that is the next full UTC hour after
// the provided date.
function toFullUTCHour(date) {
let d = new Date(+date);
d.setUTCHours(d.getUTCHours() + (d.getUTCMinutes() || d.getUTCSeconds() || d.getUTCMilliseconds? 1 : 0), 0,0,0);
return d;
}
let d = new Date()
console.log(d.toISOString() + '\n' +
toFullUTCHour(d).toISOString());
// Simplified version, only works in general for UTC hour
function ceilUTCHour(date = new Date()) {
let d = new Date(+date);
d.setHours(d.getHours() + (d%3.6e6? 1 : 0), 0, 0, 0);
return d;
}
console.log(ceilUTCHour(d).toISOString());
Since, in ECMAScript, UTC days are always exactly 8.64e7 ms long and hours are always exactly 3.6e6 ms long, you can just get the remainder of the current UTC time value and if it's not zero (which will be almost always) add 1 to the UTC hour, then zero the minutes seconds and milliseconds as for the ceilUTCHour function above.
I am given a unix timestamp like this: 1655402413 and am needing to find find the midnight of the Monday (in UTC/GMT format) of the same week, regardless of what day it is or what time zone. I then need to represent that Monday as a unix timestamp and return it. The function I have is as follows:
function findMonday(unixTimeStamp) {
let startDate = new Date(unixTimeStamp);
let startDay = startDate.getDay();
let diff = startDate.getDate() - startDay + (startDay === 0 ? -6 : 1);
let monday = new Date(startDate.setDate(diff));
monday.setHours(0, 0, 0, 0);
monday = new Date(monday).valueOf();
return monday;
}
That function almost works, but there are two problems, both related to the fact that the Date seems to always work with the user's current timezone:
If given a timestamp that evaluates to midnight on a Monday in UTC/GMT format, depending on the time zone of the user, it returns the Monday of the previous week (because startDate evaluates to the Sunday before the Monday), which is not good.
The monday that is returned is in local time, not UTC/GMT time.
This is driving me absolutely insane. Working with dates in JavaScript is a nightmare, and I would appreciate any direction you can give me.
Multiply the unix timestamp by 1000, and use the UTC methods like getUTCDate instead of getDate, setUTCHours instead of setHours etc..
Of course to return as unix time, just divide by 1000.
eg.
function findMonday(unixTimeStamp) {
let startDate = new Date(unixTimeStamp * 1000);
let startDay = startDate.getUTCDay();
let diff = startDate.getUTCDate() - startDay + (startDay === 0 ? -6 : 1);
let monday = new Date(startDate.setUTCDate(diff));
monday.setUTCHours(0, 0, 0, 0);
monday = new Date(monday).valueOf();
return monday;
}
const monday = findMonday(1655402413);
const unixMonday = Math.trunc(monday / 1000);
console.log('The Date: ' + new Date(monday).toISOString());
console.log('Unix time: ' + unixMonday);
As for Keith's answer but a little more concise. It returns seconds, not milliseconds. ;-)
// Given UNIX timestamp, return similar timestamp for
// previous UTC Monday at 00:00:00
let getLastUTCMonday = ts => {
let d = new Date(ts * 1e3);
d.setUTCDate(d.getUTCDate() - (d.getUTCDay() || 7) + 1);
return d.setUTCHours(0,0,0,0) / 1e3 | 0;
};
let ts = 1655402413;
let tsPriorMonday = getLastUTCMonday(ts)
console.log(
`Start date : ${new Date(ts*1e3).toUTCString()}\n` +
`Prior Monday: ${new Date(tsPriorMonday * 1e3).toUTCString()}`
);
In ECMA-262, offsets from the epoch (in milliseconds) are called "time values". A timestamp is anything that represents a time or date, so a time value is a timestamp. ;-)
Given that ECMAScript UTC days are always exactly 8.64e7 milliseconds long, you can work out the previous UTC Monday from today by some simple arithmetic.
The ECMAScript epoch was Thursday, 1 Jan 1970 00:00:00, so you can:
Subtract 4 UTC days worth of milliseconds (34.56e7) from the date to align with Monday instead of Thursday
Get the remainder of dividing that value by the number of milliseconds in 7 UTC days (7 * 8.64e7 or 60.48e7)
Subtract the remainder from the current date, which will return the previous Monday and also remove the time component
The above algorithm only works for dates after the epoch. Dates before then have time values are negative so add 3 days before getting the remainder, then subtract the remainder + 7 days (i.e. date - remainder - 7 days).
The following just does the post–epoch calculation:
let getPreviousUTCMonday = date => {
let weekRem = (date - 34.56e7) % 60.48e7;
return date - weekRem;
}
let d = new Date();
for (let i=0; i<12; i++) {
console.log(`${d.toUTCString()}\n` +
`${new Date(getPreviousUTCMonday(d)).toUTCString()}`);
d.setDate(d.getDate() + 1);
}
I get a date from a RSS FEED JSON file , the date is something like "2018-02-09 00:00:00" , It's a string but I know that I can turn it into integer using Number() or parseInt() and get the date with Date() , I want to get the time passed since it happened , Like 1 day ago , 2 hours ago .. etc , How to achieve that ?
Credit to Robert Gravelle at https://www.htmlgoodies.com/html5/javascript/calculating-the-difference-between-two-dates-in-javascript.html
Calculating the Difference between Two Known Dates
Unfortunately, calculating a date interval such as days, weeks, or months between two known dates is not as easy because you can't just add Date objects together. In order to use a Date object in any sort of calculation, we must first retrieve the Date's internal millisecond value, which is stored as a large integer. The function to do that is Date.getTime(). Once both Dates have been converted, subtracting the later one from the earlier one returns the difference in milliseconds. The desired interval can then be determined by dividing that number by the corresponding number of milliseconds. For instance, to obtain the number of days for a given number of milliseconds, we would divide by 86,400,000, the number of milliseconds in a day (1000 x 60 seconds x 60 minutes x 24 hours):
Date.daysBetween = function( date1, date2 )
{
//Get 1 day in milliseconds
var one_day=1000*60*60*24;
// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();
// Calculate the difference in milliseconds
var difference_ms = date2_ms - date1_ms;
// Convert back to days and return
return Math.round(difference_ms/one_day);
}
//Set the two dates
var y2k = new Date(2000, 0, 1);
var Jan1st2010 = new Date(y2k.getFullYear() + 10, y2k.getMonth(), y2k.getDate());
var today= new Date();
//displays 726
console.log( 'Days since '
+ Jan1st2010.toLocaleDateString() + ': '
+ Date.daysBetween(Jan1st2010, today));
The rounding is optional, depending on whether you want partial days or not.
First we define the desired units of time (conversions from milliseconds):
timeTypes={ year: 1000*60*60*24*365, month: 1000*60*60*24*30, day: 1000*60*60*24, hour: 1000*60*60, minute: 1000*60, second: 1000, millisecond: 1 };
Start with td being the time difference in milliseconds, the result of Date object .getTime() values:
td = d1.getTime() - d2.getTime();
And then we reduce it by the largest units and build a string as we go:
timeString='';
remaining=td;
for (i in timeTypes)
if (remaining > timeTypes[i]) {
count = parseInt(remaining/timeTypes[i]);
remaining -= timeTypes[i]*count;
timeString += count+' '+i+(count>1 ? 's' : '')+' ';
}
Now, timeString will contain something like:
1 month 9 days 42 seconds
This is treating every month as having 30 days, so that is a source of minor imprecision, but times less than a month are exact.
How can I convert time taken from form in html in the format of Hours:Minutes AM/PM to Date class object in javascript.
You could use regex to parse the time and set it to a date object.
var d = new Date(),
s ='7:30 AM',
parts = s.match(/(\d+)\:(\d+) (\w+)/),
hours = /am/i.test(parts[3]) ? parseInt(parts[1], 10) : parseInt(parts[1], 10) + 12,
minutes = parseInt(parts[2], 10);
d.setHours(hours, minutes,0,0); // As suggested by #RobG
// d.setHours(hours);
// d.setMinutes(minutes);
console.log(d);
Let's assume you have your input in the form var time = "7:30 AM".
The first thing we want to do is get the AM/PM out of the way.
time.split(' ') gives us ["7:30", "AM"], so we do:
var timePeriod = time.split(' ')[1];
time = time.split(' ')[0];
See MDN's article on .split if you have any questions
We now have timePeriod === 'AM' and time === '7:30'.
We can use the same trick to get hour and minute.
var hour = time.split(':')[0];
var minute = time.split(':')[1];
It would be easier to just use numbers, so we'll normalize our data a bit here.
if (timePeriod === 'AM') {
// Do not use `hour += 12` here as that will not convert the result to a number
hour = 12 + hour
}
And now we just have numbers to work with. Let's start with the current date:
var currentDate = new Date();
and modify the hour and minute to match the data we just parsed:
currentDate.setHours(hour);
currentDate.setMinutes(minute);
Now we should have a date that we can work with!
*See MDN's article on the Date object if you have any questions******
how to compare date with the today's date where date is in format dd-mm-yyyy
var sdate = document.getElementById('datepicker-example2').value;
if (Date.parse(document.getElementById("datepicker-example2").value) < Date.parse(dateToday.getDate() + "/" + dateToday.getmonth() + "/" + dateToday.getYear())) {
alert("dsd");
}
Use Date.now()
var sdate = document.getElementById('datepicker-example2').value;
if (Date.parse(sdate) < Date.now()) {
alert("dsd");
}
Also I dont see why you retrieve the datepickers value second time while you have stored it in the first place. Its better to use the stored one.
date = new Date()
is today's date. Use the different methods of the javascript date objects to collect the month, day, and year from today and the date you are comparing,
http://www.comptechdoc.org/independent/web/cgi/javamanual/javadate.html
getMonth ( date ) + "-" + getDay ( date ) + "-" + getYear ( date )
That point you in the right direction.
Not super accurate but this will get you time difference in days between two dates. Invert the operands for future dates. Of course the time conversion could be better but you get the idea:
var today = new Date();
var date = new Date('10/23/12')
var diff = ~~(((today.getTime() - date.getTime()) * 2.76e-7) / 24);
var currentDate = Date.now();
if (currentDate > date2.getTime()) {
alert("The current date is after the second date!");
}
The now() method returns the milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now as a number.
The getTime() returns the Milliseconds since midnight January 1, 1970
Working Demo
Parse your date :
var m = date.match (/(\d\d)-(\d\d)-(\d\d\d\d)/);
Create a new date object for that date :
if (m) {// check if date was matched
m = new Date (+m[3], +m[2] - 1, +m[1]);
And compare with todays date :
if ((new Date ()).getTime () < m.getTime ()) {
...
}
} else { // Bad date format
}