I am getting back UTC time from an API, so in my next project, i am converting the UTC times to the users local time based on a timezone setting coming also from the API.
I am trying to use the isWithinInterval
function of date-fns
to check if the current time (in that users timezone) is within a start and end time, but it keeps throwing back a
invalid interval
At the top of the file, i am declaring the current time based on timezone;
const nowInUsersTimezone = new Date().toLocaleString('en-AU', { timeZone: user.timezone })
When i console log this, it shows perfect.
When i got to use the isWithinInterval
im using the following to check if the nowInUsersTimezone
is between 2 dates, if it is, then i just print within
, but i cant get it to work;
{
isWithinInterval(
parseISO(nowInUsersTimezone),
{
start: parseISO(formatInTimeZone(job.start_time, user.timezone, 'dd/MM/yyyy, h:mm:ss aaa')),
end: parseISO(formatInTimeZone(job.end_time, user.timezone, 'dd/MM/yyyy, h:mm:ss aaa')),
}
) && (
<>
<p>Within</p>
</>
)
}
console logging the start
and end
dates works perfect, just when its in the isWithinInterval
doesnt work.
Looking at the documentation the isWithinInterval
function from date-fns
library checks if a date is within a given interval. It expects Date objects as arguments, not ISO strings.
The toLocaleString
method returns a string, not a Date object, and the format of this string depends on the locale.
I would suggest using parseISO
with ISO strings. But new Date()
with a timezone conversion does not return an ISO string. That's likely why you're getting the "Invalid Interval" error.
Heres how i would do it:
const now = new Date();
const nowInUsersTimezone = new Date(
now.toLocaleString('en-AU', { timeZone: user.timezone })
);
const jobStart = new Date(
job.start_time.toLocaleString('en-AU', { timeZone: user.timezone })
);
const jobEnd = new Date(
job.end_time.toLocaleString('en-AU', { timeZone: user.timezone })
);
{
isWithinInterval(nowInUsersTimezone, {
start: jobStart,
end: jobEnd,
}) && (
<>
<p>Within</p>
</>
)
}
EDIT: Changed approach
It sounds like the issue is not with the isWithinInterval
function itself, but rather with the comparison of times. The first thing to check is whether the start time is earlier than the end time, and that nowInUsersTimezone
is in between these two times.
const user = {
timezone: 'Australia/Sydney' //Example set
};
const job = {
start_time: new Date('2023-07-29T00:00:00Z'),
end_time: new Date('2023-07-29T23:59:59Z'),
};
// create a new date object for the current time
const now = new Date();
// convert it to the user's timezone
const nowInUsersTimezone = new Date(now.toLocaleString('en-US', { timeZone: user.timezone }));
// convert job start and end times to the user's timezone
const jobStart = new Date(job.start_time.toLocaleString('en-US', { timeZone: user.timezone }));
const jobEnd = new Date(job.end_time.toLocaleString('en-US', { timeZone: user.timezone }));
// check the interval
if(isWithinInterval(nowInUsersTimezone, { start: jobStart, end: jobEnd })) {
console.log("Within");
} else {
console.log("Not within");
}
console.log("Now in user's timezone: ", nowInUsersTimezone);
console.log("Job start time in user's timezone: ", jobStart);
console.log("Job end time in user's timezone: ", jobEnd);