Time difference between an ISO 8601 date and now - javascript

I have a comment section on my website and each message have its created_at date time. After fetching it from the MariaDB database, I get a string like "2021-06-15T12:45:28.000Z" (ISO 8601). Then, I convert it to a "x minutes ago" text instead of the full date.
But then, I'm having some trouble when the date is parsed.
const epochs = [
["année", 31536000],
["mois", 2592000],
["jour", 86400],
["heure", 3600],
["minute", 60],
["seconde", 1]
];
function getInterval(timeAgo) {
for (let [ name, seconds ] of epochs) {
const interval = Math.floor(timeAgo / seconds);
if (interval >= 1) {
return { interval: interval, epoch: name };
}
}
}
function dateToString(d) {
const date = new Date(d);
console.log("Created at:", date);
console.log("Now:", new Date());
const timeAgo = Math.floor((new Date() - date) / 1000);
console.log("Time ago:", timeAgo);
const { interval, epoch } = getInterval(timeAgo);
const plural = (interval === 1 || epoch.slice(-1) === "s") ? "" : "s";
console.log("----------------------------");
return `Il y a ${interval} ${epoch}${plural}`;
}
dateToString("2021-06-15 12:45:28"); // Works fine
dateToString("2021-06-15T12:45:28.000Z"); // The "timeAgo" is negative
Subtracting the ISO date gives a negative number. I'm pretty sure this is a timezone problem because the
minimal value of the substraction is almost -7200 which is two hour and I'm in a UTC+2 timezone.
Have you any idea how can I fix this?
Thanks

Try adding or subtracting the timezoneOffset of the local computer from the UTC you get when you pass Z
I fixed your plural too
const epochs = {
"années": 31536000,
"mois": 2592000,
"jours": 86400,
"heures": 3600,
"minutes": 60,
"secondes": 1
};
const singular = {
"années": "ans",
"mois": "mois",
"jours": "jour",
"heures": "heure",
"minutes": "minute",
"secondes": "seconde"
};
const getInterval = timeAgo => {
const epoch = Object.entries(epochs).filter(([key, val]) => timeAgo >= val).shift();
const obj = {
epoch: epoch[0],
interval: parseInt(timeAgo / epoch[1])
}
if (obj.interval === 1) obj.epoch = singular[obj.epoch]
return obj
};
const aMinute = 60 * 1000
function dateToString(d) {
const date = new Date(d);
if (d.includes("Z")) {
let tzo = date.getTimezoneOffset();
tzo = (tzo > 0 ? tzo * -1 : tzo);
tzo *= aMinute
date.setTime(date.getTime() + tzo)
}
console.log("Created at:", date.toLocaleString());
console.log("Now:", new Date());
const timeAgo = Math.floor((new Date() - date) / 1000);
console.log("Time ago:", timeAgo);
console.log(getInterval(timeAgo))
const { epoch, interval } = getInterval(timeAgo);
console.log(epoch)
console.log("----------------------------");
return `Il y a ${interval} ${epoch}`;
}
console.log(
dateToString("2021-06-15 12:45:28"), "\n",
dateToString("2021-06-15T12:45:28.000Z"), "\n",
dateToString("2019-06-15T12:45:28.000Z"), "\n"
)

Related

Javascript time zone calculation issues

I am trying to make a countdown timer for ticket response expiry. My code will successfully calculate the time left when dealing with hours bar the extra hour (+0100) GMT.
I have tried dealing with this in all manner of ways suggested on here to no avail. Any suggestions? Should I give in & learn Luxon?
The converttoUTC function seen is not called as it has not worked & only messed up the calculation further.
The dates that's been pulled from the table is in the following format 2022-04-15 17:47:19
The Time Limits being pulled from the table are in the following format, "15 mins" "6 hours".
<!--===========================================================================================-->
<script>
function func(creationDatePlusLimit) {
// var dateValue= document.getElementById("date").value;
var date = Math.abs((new Date().getTime() / 1000).toFixed(0));
var date2 = Math.abs((new Date(createdOnDate).getTime() / 1000).toFixed(0));
var diff = date2 - date;
var days = Math.floor(diff / 86400);
var hours = Math.floor(diff / 3600) % 24;
var mins = Math.floor(diff / 60) % 60;
var secs = diff % 60;
// document.getElementById("data").innerHTML = days + " days, " + hours + ":" + mins + ":" + secs;
if (days>=0) {
return days + " days, " + hours + ":" + mins + ":" + secs;
} else {
return "late";
}
}
const loopThroughTableRows = () => {
const tableRows = Array.from(document.getElementsByTagName('tr'));
tableRows.shift(); // removes first one, header
tableRows.forEach(row => {
var rowCols = row.getElementsByTagName('td');
var createdOnDate = rowCols[3];
var timeLimit = rowCols[7];
function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
const createdDate = new Date(createdOnDate.innerText);
// if time limit is in days, remove text, & add to creation date-------------------//
var limitdays = timeLimit.innerText;
if (limitdays.includes(" days")) {
limitdays = limitdays.replace("days", "");
limitdays= parseInt(limitdays);
function addDaysToDate(createddate, days) {
var result = createddate;
result.setDate(createddate.getDate()+days);
return result;
}
var newDate = addDaysToDate(createdDate, limitdays);
// format newdate to iso & remove unwanted characters
newDate = newDate.toISOString();
if (newDate.includes("T")) {
newDate = newDate.replace("T", " ");
}
if (newDate.includes(".000Z")) {
newDate = newDate.replace(".000Z", "");
}
};
//===================================================================================//
// if time limit is in hours, remove text, & add to creation date-------------------//
// var limithours = timeLimit.innerText;
// if (limithours.includes(" hours")) {
// limithours = limithours.replace("hours", "");
// limithours= parseInt(limithours);
//
// function addHoursToDate(createddate, hours) {
// var result = createddate;
// // result.setHours(createddate.getDate()+6);
// return result;
// }
// var newDate = addHoursToDate(createdDate, limithours);
//
// // format newdate to iso & remove unwanted characters
// newDate = newDate.toISOString();
// if (newDate.includes("T")) {
// newDate = newDate.replace("T", " ");
// }
// if (newDate.includes(".000Z")) {
// newDate = newDate.replace(".000Z", "");
// }
// };
//===================================================================================//
const testRow = rowCols[8];
const timeDifference = func(newDate);
testRow.innerText = newDate;
});
}
loopThroughTableRows();
setInterval(loopThroughTableRows, 1000)
</script>
Given you have a creation date like "2022-04-15 17:47:19" and duration to expiry in the format "n [days|hours|minutes]", you probably want to do everything as local to avoid timezone issues. If you use Date objects, then it's simple represent it as a UTC timestamp using toISOString.
Consider the following, which returns a Date object for the expiry based on the creationDate and time limit. It does everything as local, so timezone and daylight saving issues are handled by the Date object. There's no validation of input, so that should be added.
// Parse YYYY-MM-DD HH:mm:ss as local
function parseISOLocal (ts) {
let [Y, M, D, H, m, s] = ts.split(/\D/);
return new Date(Y, M-1, D, H, m, s);
}
// Format a Date as YYYY-MM-DD HH:mm:ss
function formatISOLocal(date = new Date()) {
return date.toLocaleString('en-CA',{hour12: false}).replace(',','');
}
// Parse limit in "value [days|hours|minutes]" to {value, unit}
// e.g. "3 days" to {value: 3, unit:'day'}
function normaliseLimit(limit) {
let [value, unit] = limit.toLowerCase().split(/\s+/);
return {value: +value, unit: {d:'day', h:'hour', m:'minute'}[unit[0]]};
}
// Given:
// createdAt in YYYY-MM-DD HH:mm:ss format and
// limit as "number [days|hours|minutes]" return a Date for expiry
// I.e. createdAt plus limit
function getExpiryDate(createdAt, limitString) {
let expiry = parseISOLocal(createdAt);
let limit = normaliseLimit(limitString);
let method = {day:'Date', hour:'Hours', minute:'Minutes'}[limit.unit];
return new Date(expiry[`set${method}`](expiry[`get${method}`]() + limit.value));
}
let createdAt = formatISOLocal();
[{createdAt: createdAt, limit:'1 Day'},
{createdAt: createdAt, limit:'3 hours'},
{createdAt: createdAt, limit:'12 minutes'}
].forEach(({createdAt, limit}) => console.log(
`createdAt: ${createdAt}\n` +
`limit : ${limit}\n` +
`Expires : ${formatISOLocal(getExpiryDate(createdAt, limit))}`
));
Once you have the expiry date, you can work out the remaining time as days, hours, minutes, seconds as given at Difference between two dates in years, months, days in JavaScript and use it in a timer to show a count down, to work out which items have expired, etc.

How do I convert this date from momentjs to plain JavaScript

I have a timestamp that I am trying to roundto the nearest UTC Monday 00:00:00:00:000Z
My code in moment looks like this
let now = Date.now()
moment.unix(now / 1000).utc().startOf("isoWeek").valueOf()
I am trying to do this in plain JS without moment and I am not getting the same answer
const nearestMonday = date => {
const monday = 1;
const currentDay = date.getDay();
const distance = (monday + 7 - currentDay) % 7;
const newDate = new Date(date.getTime());
newDate.setDate(date.getDate() + distance);
newDate.setHours(0, 0, 0, 0);
return newDate;
}
> d = Date.now()
1545989455067
> nearestMonday(new Date(d)).getTime()
1546194600000
> m.unix(Date.now() / 1000).utc().startOf("isoWeek").valueOf()
1545609600000
I am in GMT + 530 zone , what do I change to get the same answer as moment
Ok, so we have a few problems here:
First: Timezones
Date works with your local timezone, so when you do newDate.setHours(0, 0, 0, 0); and stuff like that, it sets the object to that hours in your timezone. When you do .getTime(), however, it does return millis from epoch in UTC.
The result of this being: if you are in gmt+530 (India, I believe) when you do a .getTime() the millis from epoch will be off by that difference (5h 30m).
To compensate that, you can use getTimezoneOffset():
const nearestMonday = date => {
const monday = 1;
const currentDay = date.getDay();
const distance = (monday + 7 - currentDay) % 7;
const newDate = new Date(date.getTime());
newDate.setDate(date.getDate() + distance);
newDate.setHours(0, 0, 0, 0);
newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
return newDate;
}
On the other hand, your code using moment will work properly with timezones, so there's no need to change it.
Second: What monday?
Your function nearestMonday calculates the next Monday.
The function startOf('isoWeek') sets the date to the Monday of the current week.
If you want both to calculate the current, you should modify your nearestMonday like:
const nearestMonday = date => {
const monday = 1;
const currentDay = date.getDay();
const distance = monday - currentDay;
console.log('dist', distance);
const newDate = new Date(date.getTime());
newDate.setDate(date.getDate() + distance);
newDate.setHours(0, 0, 0, 0);
newDate.setTime(newDate.getTime()-1000*60*newDate.getTimezoneOffset());
return newDate;
}
Last: Sundays?
getDay() on Sunday will return a 0. Therefore, the "nearestMonday" will be the day after that. I haven't corrected it since I don't know if that's the desired behaviour, but noting it just for completion sake
I think this may do what you want:
const nearestMonday = date => {
const day = 1000*60*60*24;
const week = day*7;
return new Date(Math.floor(date.getTime()/week)*week-3*day);
}

Get duration (in Hours and minutes) between two Date objects - JavaScript

Although, I've seen multiple similar questions here on SO but none of them could help me to figure out what's wrong with my calculation. I know I can use library such as Moment.JS to simplify my solution but I want native JavaScript only solution.
I'm trying to calculate duration (in hours and minutes) between two Date objects but I'm getting negative (incorrect) duration.
function padNumber(number, width = 2, padWith = '0') {
const strNum = number.toString();
return strNum.length >= width ? strNum : new Array(width - strNum.length + 1).join(padWith) + strNum;
}
// Get UTC date time from PHP date (Y-m-d) and time (H:i:s) strings
function getUTCDateTime(date, time, timezoneOffset = -480) {
const dateParts = date.split('-').map((el) => Number(el)); // Y-m-d
const timeParts = time.split(':').map((el) => Number(el)); // H:i:s
const dateTimeUTC = new Date(Date.UTC(dateParts[0], dateParts[1], dateParts[2], timeParts[0], timeParts[1], timeParts[2]));
// Set back Singapore specific time (GMT+8:00)
dateTimeUTC.setUTCHours(dateTimeUTC.getUTCHours() + timezoneOffset / 60);
return dateTimeUTC;
}
function getDuration(timeStart, timeEnd = new Date()) {
const msDiff = timeEnd.getTime() - timeStart.getTime();
const minDiff = msDiff / 60000;
const hourDiff = Math.floor(msDiff / 3600000);
return {
hours: this.padNumber(hourDiff, 2),
minutes: this.padNumber(Math.floor(minDiff - 60 * hourDiff), 2)
};
}
// Got from server (in Singapore timezone)
const serverDate = '2018-10-18';
const serverTime = '00:22:51';
// Convert server date and time (timezone specific) strings to Date object
const serverUTC = getUTCDateTime(serverDate, serverTime);
// Get duration between server time and now
const duration = getDuration(serverUTC);
// Expected positive value but getting negative as server time is in past
console.log(duration);
I expected positive value in console log but I'm getting negative. Have I missed anything?
The problem stems from the fact that months are zero-based in JavaScript (i.e. January is 0, February is 1, and so on). Your date construction in getUTCDateTime() doesn't take this into account.
This line:
const dateTimeUTC = new Date(Date.UTC(dateParts[0], dateParts[1], dateParts[2], timeParts[0], timeParts[1], timeParts[2]));
Should be:
const dateTimeUTC = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2], timeParts[0], timeParts[1], timeParts[2]));
Complete snippet:
function padNumber(number, width = 2, padWith = '0') {
const strNum = number.toString();
return strNum.length >= width ? strNum : new Array(width - strNum.length + 1).join(padWith) + strNum;
}
// Get UTC date time from PHP date (Y-m-d) and time (H:i:s) strings
function getUTCDateTime(date, time, timezoneOffset = -480) {
const dateParts = date.split('-').map((el) => Number(el)); // Y-m-d
const timeParts = time.split(':').map((el) => Number(el)); // H:i:s
const dateTimeUTC = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2], timeParts[0], timeParts[1], timeParts[2]));
// Set back Singapore specific time (GMT+8:00)
dateTimeUTC.setUTCHours(dateTimeUTC.getUTCHours() + timezoneOffset / 60);
return dateTimeUTC;
}
function getDuration(timeStart, timeEnd = new Date()) {
const msDiff = timeEnd.getTime() - timeStart.getTime();
const minDiff = msDiff / 60000;
const hourDiff = Math.floor(msDiff / 3600000);
return {
hours: this.padNumber(hourDiff, 2),
minutes: this.padNumber(Math.floor(minDiff - 60 * hourDiff), 2)
};
}
// Got from server (in Singapore timezone)
const serverDate = '2018-10-18';
const serverTime = '00:22:51';
// Convert server date and time (timezone specific) strings to Date object
const serverUTC = getUTCDateTime(serverDate, serverTime);
// Get duration between server time and now
const duration = getDuration(serverUTC);
// Expected positive value but getting negative as server time is in past
console.log(duration);

How to return the next available date

I'm building a project with express and I have a scheduling calendar. I want to give to my users next available day. Format YYYY-MM-DD.
Rules:
The next available day is usually tomorrow unless:
- After 4pm the next available day is two days from now (i.e. Monday afternoon they can book Wednesday);
- Friday after 4pm the next available day is Monday;
- For Saturday it's Monday;
- For Sunday it's Tuesday;
I also have an array of public holidays, which are also unavailable. If the next day is a public holiday, the app should return the day after.
When there is a public holiday my app goes into a loop and it runs the whole loop. I don't know how to fix this. I thought it would skip the loop when it runs the second time.
const publicHolidays = ['2018-09-28', '2018-12-25']
const availableDay = (nextDay) => {
const d = new Date();
const utc = d.getTime() + (d.getTimezoneOffset() * 60000);
const nd = new Date(utc + (3600000 * 8));
if (nextDay === undefined) {
nextDay = 1;
}
if (nd.getDay() === 5 && nd.getHours() > 15) {
nextDay = 3;
} else if ([0, 6].includes(nd.getDay()) || nd.getHours() > 15) {
nextDay = 2;
}
const day = new Date();
const tomorrow = new Date(day);
tomorrow.setDate(tomorrow.getDate() + nextDay);
const yy = tomorrow.getFullYear();
let mm = tomorrow.getMonth() + 1;
if (mm < 10) {
mm = `0${mm}`;
}
let dd = tomorrow.getDate();
if (dd < 10) {
dd = `0${dd}`;
}
const available = `${yy}-${mm}-${dd}`;
if (publicHolidays.includes(available)) {
const nextDay = 7;
for (let i = 2; i < nextDay; i += 1) {
availableDay(i);
}
} else {
console.log('returning available', available);
return(available);
}
}
availableDay()
I think this logic will work - I've created a function to do the "date string - yyyy-mm-dd" thing because it's used in two places now
I also check for weekends by tomorrow.getDay() % 6 === 0 - you can of course use [0, 6].includes(tomorrow.getDay()) if you prefer
const publicHolidays = ['2018-09-28', '2018-12-25']
const availableDay = () => {
let nextDay = 1; // since we are not recursive any more
const d = new Date();
const utc = d.getTime() + (d.getTimezoneOffset() * 60000);
const nd = new Date(utc + (3600000 * 8));
if (nd.getDay() === 5 && nd.getHours() > 15) {
nextDay = 3;
} else if ([0, 6].includes(nd.getDay()) || nd.getHours() > 15) {
nextDay = 2;
}
const day = new Date();
const tomorrow = new Date(day);
tomorrow.setDate(tomorrow.getDate() + nextDay);
// changes start here
const dateString = d => `${.getFullYear()}-${('0' + (d.getMonth() + 1)).toString(-2)}-${('0' + d.getDate()).toString(-2)}`;
let available = dateString(tomorrow);
while (publicHolidays.includes(available) || (tomorrow.getDay() === 0)) {
tomorrow.setDate(tomorrow.getDate() + 1);
available = dateString(tomorrow);
}
console.log('returning available', available);
return(available);
}
availableDay()
There's probably more you can do to streamline the code - but this should fix the problem at least
I think you should always + 1 to nextDay. so if today is public holiday, try get the next day. the cycle repeat until it is not public holiday.
if (publicHolidays.includes(available)) {
availableDay(nextDay +1 );
} else {
console.log('returning available', available);
return(available);
}
Here is a more generic solution that might be applicable for people searching for something similar:
/**
* #summary Finds the next available date between a range, excluding a list of unavailable dates
* #param {Date} startDate The beginning of the date range.
* #param {Date} endDate The beginning of the date range.
* #param {Array of Date} excludeDates Dates that are not available.
*/
export const findNextAvailableDate = (startDate, endDate, excludeDates) => {
const excludeDatesStrArr = excludeDates.map(date => {
// Make sure dates are in a consistent string format so we can check for equality
excludeDate.setUTCHours(0, 0, 0, 0)
return excludeDate.toISOString()
})
let possibleDate = startDate
possibleDate.setUTCHours(0, 0, 0, 0)
let possibleDateStr = possibleDate.toISOString()
while (possibleDateStr !== endDate) {
if (!excludeDatesStrArr.includes(possibleDateStr)) {
// Date is not in exclude array, return available date
return possibleDate
} else {
// Date is included in exclude array, iterate to the next day
const newDate = possibleDate.setDate(possibleDate.getDate() + 1)
possibleDate = new Date(newDate)
possibleDate.setUTCHours(0, 0, 0, 0)
possibleDateStr = possibleDate.toISOString()
}
}
// Did not find next available date
return false
}

How to get start and end of day in Javascript?

How to get start ( 00:00:00 ) and end ( 23:59:59 ) of today in timestamp ( GMT )? Computer use a local time.
var start = new Date();
start.setUTCHours(0,0,0,0);
var end = new Date();
end.setUTCHours(23,59,59,999);
alert( start.toUTCString() + ':' + end.toUTCString() );
If you need to get the UTC time from those, you can use UTC().
With dayjs library, use startOf and endOf methods as follows:
Local GMT:
const start = dayjs().startOf('day'); // set to 12:00 am today
const end = dayjs().endOf('day'); // set to 23:59 pm today
For UTC:
const utc = require('dayjs/plugin/utc');
dayjs.extend(utc);
const start = dayjs.utc().startOf('day');
const end = dayjs.utc().endOf('day');
Using the (deprecated) momentjs library, this can be achieved with the startOf() and endOf() methods on the moment's current date object, passing the string 'day' as arguments:
Local GMT:
var start = moment().startOf('day'); // set to 12:00 am today
var end = moment().endOf('day'); // set to 23:59 pm today
For UTC:
var start = moment.utc().startOf('day');
var end = moment.utc().endOf('day');
Using the luxon.js library, same can be achieved using startOf and endOf methods by passing the 'day' as parameter
var DateTime = luxon.DateTime;
DateTime.local().startOf('day').toUTC().toISO(); //2017-11-16T18:30:00.000Z
DateTime.local().endOf('day').toUTC().toISO(); //2017-11-17T18:29:59.999Z
DateTime.fromISO(new Date().toISOString()).startOf('day').toUTC().toISO(); //2017-11-16T18:30:00.000Z
remove .toUTC() if you need only the local time
and you may ask why not moment.js, answer is here for that.
FYI (merged version of Tvanfosson)
it will return actual date => date when you are calling function
export const today = {
iso: {
start: () => new Date(new Date().setHours(0, 0, 0, 0)).toISOString(),
now: () => new Date().toISOString(),
end: () => new Date(new Date().setHours(23, 59, 59, 999)).toISOString()
},
local: {
start: () => new Date(new Date(new Date().setHours(0, 0, 0, 0)).toString().split('GMT')[0] + ' UTC').toISOString(),
now: () => new Date(new Date().toString().split('GMT')[0] + ' UTC').toISOString(),
end: () => new Date(new Date(new Date().setHours(23, 59, 59, 999)).toString().split('GMT')[0] + ' UTC').toISOString()
}
}
// how to use
today.local.now(); //"2018-09-07T01:48:48.000Z" BAKU +04:00
today.iso.now(); // "2018-09-06T21:49:00.304Z" *
* it is applicable for Instant time type on Java8 which convert your local time automatically depending on your region.(if you are planning write global app)
In MomentJs We can declare it like :
const start = moment().format('YYYY-MM-DD 00:00:01');
const end = moment().format('YYYY-MM-DD 23:59:59');
One liner - considering local timezone and without libraries
const todayStart = new Date(new Date().setHours(0, 0, 0, 0))
const todayEnd = new Date(new Date().setHours(23, 59, 59, 999))
const tomorrowStart = new Date(new Date(new Date().setHours(0, 0, 0, 0)).setDate(new Date().getDate() + 1))
const tomorrowEnd = new Date(new Date(new Date().setHours(23, 59, 59, 999)).setDate(new Date().getDate() + 1))
const monthStart = new Date(new Date(new Date().getFullYear(), new Date().getMonth(), 1).setHours(0, 0, 0, 0))
const monthEnd = new Date(new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).setHours(23, 59, 59, 999))
const nextMonthStart = new Date(new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1).setHours(0, 0, 0, 0))
const nextMonthEnd = new Date(new Date(new Date().getFullYear(), new Date().getMonth() + 2, 0).setHours(23, 59, 59, 999))
console.log({
todayStart,
todayEnd,
tomorrowStart,
tomorrowEnd,
monthStart,
monthEnd,
nextMonthStart,
nextMonthEnd,
})
If you're just interested in timestamps in GMT you can also do this, which can be conveniently adapted for different intervals (hour: 1000 * 60 * 60, 12 hours: 1000 * 60 * 60 * 12, etc.)
const interval = 1000 * 60 * 60 * 24; // 24 hours in milliseconds
let startOfDay = Math.floor(Date.now() / interval) * interval;
let endOfDay = startOfDay + interval - 1; // 23:59:59:9999
I prefer to use date-fns library for date manipulating. It is really great modular and consistent tool. You can get start and end of the day this way:
var startOfDay = dateFns.startOfDay;
var endOfDay = dateFns.endOfDay;
console.log('start of day ==> ', startOfDay(new Date('2015-11-11')));
console.log('end of day ==> ', endOfDay(new Date('2015-11-11')));
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.29.0/date_fns.min.js"></script>
We can use moment for this.
// for day start time
moment(moment().startOf('day')).format('HH:mm')
// for day end time
moment(moment().endOf('day')).format('HH:mm')
As you are interested in the UTC start/end of day, you can also use the modulo operator:
const now = new Date().getTime();
let startOfDay = now - (now % 86400000);
let endDate = startOfDay + 86400000;
where 86400 is the number of seconds of one day and the resulting variables are the Epoch in milliseconds.
If you prefer Date Objects:
const now = new Date().getTime();
let startOfDay = new Date(now - (now % 86400000));
let endDate = new Date(now - (now % 86400000) + 86400000);
Based on the most rated answer, but to define the dates in just one line:
const startToday = new Date(new Date().setUTCHours(0,0,0,0));
const endToday = new Date(new Date().setUTCHours(23,59,59,999));
Explanation:
new Date().setUTCHours(0,0,0,0) // returns the epoch time number
new Date(/* epoch number */) // returns that epoch Date object
that is why both new Date constructors are needed.
It might be a little tricky, but you can make use of Intl.DateTimeFormat.
The snippet bellow can help you convert any date with any timezone to its begining/end time.
const beginingOfDay = (options = {}) => {
const { date = new Date(), timeZone } = options;
const parts = Intl.DateTimeFormat("en-US", {
timeZone,
hourCycle: "h23",
hour: "numeric",
minute: "numeric",
second: "numeric",
}).formatToParts(date);
const hour = parseInt(parts.find((i) => i.type === "hour").value);
const minute = parseInt(parts.find((i) => i.type === "minute").value);
const second = parseInt(parts.find((i) => i.type === "second").value);
return new Date(
1000 *
Math.floor(
(date - hour * 3600000 - minute * 60000 - second * 1000) / 1000
)
);
};
const endOfDay = (...args) =>
new Date(beginingOfDay(...args).getTime() + 86399999);
const beginingOfYear = () => {};
console.log(beginingOfDay({ timeZone: "GMT" }));
console.log(endOfDay({ timeZone: "GMT" }));
console.log(beginingOfDay({ timeZone: "Asia/Tokyo" }));
console.log(endOfDay({ timeZone: "Asia/Tokyo" }));
// get current time for UTC timezone
const d = new Date();
const year = d.getUTCFullYear();
const month = d.getUTCMonth();
const day = d.getUTCDate();
// set time to begin day UTC
const startTime = Date.UTC(year, month, day, 0, 0, 0, 0);
//set time to end day UTC
const endTime = Date.UTC(year, month, day, 23, 59, 0, 0);

Categories

Resources