简体   繁体   中英

How to handle client timezone for retrieving data?

I store to my database events from different sports.

Example:

{
  "sport": "NBA",
  "name": "Warrios v Wizards",
  "date": "2022-10-01 02:00:00"
}

All dates/times are stored in UTC. Through an API (Node.js - Express) the client will request events from a current day. I have difficulty understanding on how to request/query events from the server/database based on the client timezone.

Example:

The following API route returns events for a specific day api/events/?date=2022-10-01 . A user with UTC offset (−10:00) should get different data from a user with UTC offset (+12:00) especially for events that are after or before midnight time of each user.

One option that I thought is to figure out the timezone on client level and then pass the data to the server and use that data to convert and query the database based on that timezone.

Is there another better way?

If all data is stored as UTC, then you should send UTC to the client and convert to local there.

To get all events for a particular day, use the client to calculate the start and end of the day UTC and get events in that range.

Eg the following returns and start and end of the day as UTC in ISO 8601 format based on host settings. That can then be used at the server to get events within the range. At the client, the UTC values can be converted to local.

 /* Return UTC values for start and end of local day * * @param {string} date - format yyyy-mm-dd * @returns {Array<string>} start and end of day as UTC in * ISO 8601 format * endOfDay is 1ms before midnight */ function getLocalDayRange(date) { let [Y, M, D] = date.split(/\D/); let startOfDay = new Date(Y, M-1, D); let endOfDay = new Date(Y, M-1, Number(D)+1, 0, 0, 0, -1); return [startOfDay.toISOString(), endOfDay.toISOString()]; } // Start and end of 30 Sep 2022 based on client settings console.log('Start and end for 30 Sep 2022:\n' + getLocalDayRange('2022-09-30').join('\n') ); // Current date in YYYY-MM-DD format let d = new Date().toLocaleDateString('en-ca'); console.log('Start and end for today (' + d + '):\n' + getLocalDayRange(d).join('\n') );

Always include either assumed timezone name or offset, or both, when presenting values so the client can confirm that they are correct for their location.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM