mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 18:17:31 +08:00
chore(datetime): simpler way of doing timezone offsets (#25132)
This commit is contained in:
@ -333,15 +333,12 @@ describe('getToday', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers('modern');
|
||||
// System time is zero based, 1 = February
|
||||
jest.setSystemTime(new Date(2022, 1, 21));
|
||||
jest.setSystemTime(new Date(2022, 1, 21, 18, 30));
|
||||
});
|
||||
|
||||
it('should return today', () => {
|
||||
it('should return today without converting to UTC time', () => {
|
||||
const res = getToday();
|
||||
|
||||
const expected = new Date();
|
||||
expected.setHours(expected.getHours() - expected.getTimezoneOffset() / 60);
|
||||
|
||||
expect(res).toEqual('2022-02-21T00:00:00.000Z');
|
||||
expect(res).toEqual('2022-02-21T18:30:00.000Z');
|
||||
});
|
||||
});
|
||||
|
@ -12,38 +12,44 @@ import { getNextMonth, getPreviousMonth } from './manipulation';
|
||||
*/
|
||||
export const getToday = () => {
|
||||
/**
|
||||
* Grab the current date object
|
||||
* as well as the timezone offset
|
||||
*/
|
||||
const date = new Date();
|
||||
const tzOffset = date.getTimezoneOffset();
|
||||
|
||||
/**
|
||||
* When converting to ISO string, everything is
|
||||
* set to UTC. Since we want to show these dates
|
||||
* relative to the user's timezone, we need to
|
||||
* subtract the timezone offset from the date
|
||||
* so that when `toISOString()` adds it back
|
||||
* there was a net change of zero hours from the
|
||||
* local date.
|
||||
*/
|
||||
const adjustedHours = date.getHours() - tzOffset / 60;
|
||||
|
||||
/**
|
||||
* Some timezones include minute adjustments
|
||||
* such as 30 or 45 minutes.
|
||||
* ion-datetime intentionally does not
|
||||
* parse time zones/do automatic time zone
|
||||
* conversion when accepting user input.
|
||||
* However when we get today's date string,
|
||||
* we want it formatted relative to the user's
|
||||
* time zone.
|
||||
*
|
||||
* When calling toISOString(), the browser
|
||||
* will convert the date to UTC time by either adding
|
||||
* or subtracting the time zone offset.
|
||||
* To work around this, we need to either add
|
||||
* or subtract the time zone offset to the Date
|
||||
* object prior to calling toISOString().
|
||||
* This allows us to get an ISO string
|
||||
* that is in the user's time zone.
|
||||
*
|
||||
* Example:
|
||||
* Time zone offset is 240
|
||||
* Meaning: The browser needs to add 240 minutes
|
||||
* to the Date object to get UTC time.
|
||||
* What Ionic does: We subtract 240 minutes
|
||||
* from the Date object. The browser then adds
|
||||
* 240 minutes in toISOString(). The result
|
||||
* is a time that is in the user's time zone
|
||||
* and not UTC.
|
||||
*
|
||||
* Note: Some timezones include minute adjustments
|
||||
* such as 30 or 45 minutes. This is why we use setMinutes
|
||||
* instead of setHours.
|
||||
* Example: India Standard Time
|
||||
* Timezone offset: -330 = -5.5 hours.
|
||||
*
|
||||
* As a result, we need to make sure we also
|
||||
* increment the minutes as well.
|
||||
* List of timezones with 30 and 45 minute timezones:
|
||||
* https://www.timeanddate.com/time/time-zones-interesting.html
|
||||
*/
|
||||
const minutesRemainder = adjustedHours % 1;
|
||||
const adjustedMinutes = date.getMinutes() + minutesRemainder * 60;
|
||||
date.setHours(adjustedHours);
|
||||
date.setMinutes(adjustedMinutes);
|
||||
const date = new Date();
|
||||
const tzOffset = date.getTimezoneOffset();
|
||||
date.setMinutes(date.getMinutes() - tzOffset);
|
||||
|
||||
return date.toISOString();
|
||||
};
|
||||
|
Reference in New Issue
Block a user