Home > Back-end >  Change React State based on a specific timezone
Change React State based on a specific timezone

Time:01-04

Let's imagine that a local bakery has a website that shows its working hours along with a tag "Open" or "Closed". This tag needs to change based on the hours of operation.

The solution that I thought of was to have two states:

  1. for status of working hours (open/closed)
  2. for current time

For the second one I used a solution that I found for online clock:

 const [date, setDate] = useState(new Date());


useEffect(() => {
    let timer = setInterval(() => setDate(newDate()), 1000);
    return function cleanup() {
      clearInterval(timer);
    };
  });

And for changing open/closed state I thought of using this handler:

const handleStatus = () => {
    let openHour = new Date();
    let closeHour = new Date();
    openHour.setHours(9, 0, 0);
    closeHour.setHours(18, 30, 0);
    if (date > openHour) {
      //CLOSED
    } else {
     //OPEN
    }
  };

The problem with this approach is that it only works for the state that I am located at and not the other timezone. The goal is to keep the state change for only a specific timezone, so the user that is located in NYC at 9pm will see that the bakery is still open since it is 6pm in LA and it closes only at 6:30pm. How do I go around that? If there is any other approach please let me know!

CodePudding user response:

Maybe you should try to use the browser's timezone instead of the local device's timezone. You can get the browser's timezone with the Intl.DateTimeFormat().resolvedOptions().timeZone method.

You can use this method to update the working hours status based on the browser's timezone:

const handleStatus = () => {
  const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;

  // Set the open and close hours based on the timezone
  let openHour, closeHour;
  if (timezone === 'America/Los_Angeles') {
    openHour = new Date();
    openHour.setHours(9, 0, 0);
    closeHour = new Date();
    closeHour.setHours(18, 30, 0);
  } else {
    // Set the open and close hours for other timezones here
  }

  if (date > openHour && date < closeHour) {
    // The bakery is open
  } else {
    // The bakery is closed
  }
};

This way, the working hours status will always be based on the browser's timezone, regardless of the local device's timezone.

Alternatively, you could use a server-side solution to get the correct time for the browser's timezone. This would involve making a server-side API call to get the current time in the browser's timezone, and then using that time to update the working hours status. This approach would be more accurate, as it takes into account daylight saving time and other factors that can affect the local device's time. However, it would require setting up a server and making API calls, which may not be necessary if you only need to display the working hours status on a static website.

I hope this helps you some ways.

CodePudding user response:

As of now, JavaScript standard library does not have a concept of ZonedDateTime. Until it becomes available, you can calculate the timezone offset manually and operate on the Date objects in UTC.

// Calculate timezone offset of America/Los_Angeles
utcDate = new Date();
utcDate.setHours(0, 0, 0, 0);
strDateLA = utcDate.toLocaleString("en-US", {
    timeZone: "America/Los_Angeles",
});
offset = (new Date(strDateLA) - utcDate) / (1000 * 60 * 60);
console.log(offset);

Now that you have the timezone offset, you can convert the opening and closing hours into UTC date-time.

openHourUTC = new Date();
openHourUTC.setHours(9, 0, 0, 0);
// Opening hour in UTC
openHourUTC = openHourUTC - offset;

closeHourUTC = new Date();
closeHourUTC.setHours(18, 30, 0, 0);
// Closing hour in UTC
closeHourUTC = closeHourUTC - offset;

Note: If the timezone offset is negative e.g. -8, the above code snippet calculates openHourUTC = openHourUTC - (-8) => openHourUTC = openHourUTC 8.


Now, you can do:

if (date >= openHourUTC && date < closeHourUTC) {
    // OPEN
} else {
    // CLOSED
}
  • Related