formkit / tempo

šŸ“† Parse, format, manipulate, and internationalize dates and times in JavaScript and TypeScript.
https://tempo.formkit.com
MIT License
2.34k stars 30 forks source link

Fix `tzDate` #35

Closed lehuygiang28 closed 6 months ago

lehuygiang28 commented 6 months ago

Description:

Changed:

Added:

vercel[bot] commented 6 months ago

@lehuygiang28 is attempting to deploy a commit to the Formkit Team on Vercel.

A member of the Team first needs to authorize it.

justin-schroeder commented 6 months ago

Hmm, perhaps there is some confusion here because as far as I can tell tzDate is doing exactly what it is supposed to. It creates a Date object for an unlocalized time (12:00 noon lets say). Perhaps the easiest way to see this is by using the same "wall clock" time and working our way around the globe:

import { tzDate } from "@formkit/tempo"

// UTC-1000
tzDate("2013-10-01T12:00", "America/Adak")

// UTC-0900
tzDate("2013-10-01T12:00", "America/Anchorage")

// UTC-0800
tzDate("2013-10-01T12:00", "America/Ensenada")

// UTC-0700
tzDate("2013-10-01T12:00", "America/Boise")

// UTC-0600
tzDate("2013-10-01T12:00", "America/Bahia_Banderas")

// UTC-0500
tzDate("2013-10-01T12:00", "America/Atikokan")

// UTC-0400
tzDate("2013-10-01T12:00", "America/New_York")

// UTC-0300
tzDate("2013-10-01T12:00", "America/Araguaina")

// UTC-0200
tzDate("2013-10-01T12:00", "America/Godthab")

// UTC-0100
tzDate("2013-10-01T12:00", "America/Scoresbysund")

// UTC+0000
tzDate("2013-10-01T12:00", "Africa/Abidjan")

// UTC+0100
tzDate("2013-10-01T12:00", "Africa/Algiers")

// UTC+0200
tzDate("2013-10-01T12:00", "Africa/Blantyre")

// UTC+0300
tzDate("2013-10-01T12:00", "Africa/Addis_Ababa")
tzDate("2013-10-01T12:00", "Asia/Tehran")

// UTC+0400
tzDate("2013-10-01T12:00", "Asia/Baku")
tzDate("2013-10-01T12:00", "Asia/Kabul")

// UTC+0500
tzDate("2013-10-01T12:00", "Antarctica/Mawson")
tzDate("2013-10-01T12:00", "Asia/Calcutta")
tzDate("2013-10-01T12:00", "Asia/Kathmandu")

// UTC+0600
tzDate("2013-10-01T12:00", "Asia/Bishkek")
tzDate("2013-10-01T12:00", "Asia/Rangoon")

// UTC+0700
tzDate("2013-10-01T12:00", "Antarctica/Davis")

// UTC+0800
tzDate("2013-10-01T12:00", "Antarctica/Casey")
tzDate("2013-10-01T12:00", "Australia/Eucla")

// UTC+0900
tzDate("2013-10-01T12:00", "Asia/Chita")
tzDate("2013-10-01T12:00", "Australia/Darwin")

// UTC+1000
tzDate("2013-10-01T12:00", "Antarctica/DumontDUrville")
tzDate("2013-10-01T12:00", "Australia/Adelaide")

// UTC+1100
tzDate("2013-10-01T12:00", "Antarctica/Macquarie")

// UTC+1200
tzDate("2013-10-01T12:00", "Asia/Anadyr")

// UTC+1300
tzDate("2013-10-01T12:00", "Antarctica/McMurdo")
tzDate("2013-10-01T12:00", "NZ-CHAT")

// UTC+1400
tzDate("2013-10-01T12:00", "Etc/GMT-14")

In fact tzDate should not in any way take into account the users timezone.

So as far as I can tell this is working properly, but Iā€™m happy to fix any issues you find here so if you can show this is indeed incorrect in some way please let me know.

lehuygiang28 commented 6 months ago

@justin-schroeder Thank you for your answer, but I'm still confused about when, why, and how to use your tzDate in the real world ?

justin-schroeder commented 6 months ago

Sure ā€” real world ā€” someone is checking into a rental apartment in Tokyo. They are shown a datepicker of dates and times. They pick "3pm June 2nd" ā€” their browser which was powering that datepicker was in Berlin germany. How can we get the Date object for the selected time.

tzDate('2024-06-02T15:00', 'Asia/Tokyo')
// Date: 2024-06-02T06:00:00.000Z

Is that example helpful?

lehuygiang28 commented 6 months ago

To clarify, does your tzDate function receive a non-localized time along with a specified timezone? Is the provided timezone intended for the non-localized time, with the output being localized in the user's time zone?

tzDate('2024-06-02T15:00', 'Asia/Tokyo') // Date: 2024-06-02T06:00:00.000Z

Your example indicates that 2024-06-02T15:00 is in Asia/Tokyo, but you want to display it in the user's browser in Europe/Berlin, correct? Tokyo is in UTC+9, while Berlin is in UTC+1. Perhaps we should consider offsetting by 8 hours instead of 9?

justin-schroeder commented 6 months ago

To clarify, does your tzDate function receive a non-localized time along with a specified timezone? Is the provided timezone intended for the non-localized time, with the output being localized in the user's time zone?

Yes it receives a non-localized time. The output is a Date object which represents an absolute time (they are "shown" in your local browser if you console log them, but really they are just a UTC timestamp)

Your example indicates that 2024-06-02T15:00 is in Asia/Tokyo, but you want to display it in the user's browser in Europe/Berlin, correct? Tokyo is in UTC+9, while Berlin is in UTC+1. Perhaps we should consider offsetting by 8 hours instead of 9?

There is no intention of showing it in Berlin time, the point is that the local browser at time of selection is not in tokyo, but the final output needs to be the correct absolute time in Tokyo. Again, date objects are not tz aware, so all we are trying to do with tzDate is get the underlying Date object for a given time/date in a given timezone. If you wanted to show it in berlin time, you could output the resulting Date object in with the format function with the tz option set to Berlin.

Hopefully that clears it up further?