moment / luxon

⏱ A library for working with dates and times in JS
https://moment.github.io/luxon
MIT License
15.31k stars 729 forks source link

Luxon "toLocaleString" uses an unusal space unicode when "setZone" flag is set #1619

Open AliD201 opened 5 months ago

AliD201 commented 5 months ago

Describe the bug When converting a time to simple time "TIME_SIMPLE" the returned string have an unusual space. such that if you happen to want to reuse it and create a new DateTime object it will not be accepted. this only happens when setzone flag is set { setZone: true }

To Reproduce

  let y = DateTime.fromISO("2024-04-17T"+"10:30:00.000"+"Z", { setZone: true })
  let time = y.toLocaleString(DateTime.TIME_SIMPLE)
  let compare = "10:30 AM" == time
  console.log(compare)
  let parsedTime = DateTime.fromFormat(time, "h:mm a");

  console.log(parsedTime.toFormat("HH:mm"));

Actual vs Expected behavior Actual: Returns the string "Invalid DateTime"

Expected : Should parse the time normally and output 10:30

Desktop (please complete the following information):

Additional info: Luxon inserted space: \u202f Normal space: \u0020

diesieben07 commented 5 months ago

Several points here:

  1. The result of toLocaleString is not intended to be parsed. Attempting to do so is a fruitless endeavor that will usually not yield helpful results. If you must format to string and parse again, I highly recommend using a properly defined format like ISO 8601 via toISO and fromISO or a custom format via toFormat and fromFormat.
  2. If you must for some reason parse a locale-dependent date (this is highly inadvisable and will probably not always parse correctly) you need to use the macro tokens like t for TIME_SIMPLE. These analyze how the corresponding toLocaleString format would be formatted by the browser and then reverse-engineer that into a parser.
  3. The result of toLocaleString is not guaranteed to be the same between different browsers or JavaScript runtimes or even different versions of the same browser. The output is entirely implementation defined and actually not controlled by Luxon at all. For toLocaleStringLuxon uses Intl.DateTimeFormat#format under the hood, with some minor enhancements. You can read some more information about this in the relevant documentation, especially here. If you are seeing a specific output here (including the \u202f space), it is not generated by Luxon but by your browser. This is documented in the Luxon documentation as well, see here.