luxon icon indicating copy to clipboard operation
luxon copied to clipboard

[Feature request] Parsing token for Zulu

Open lirbank opened this issue 3 years ago • 2 comments

Thanks a bunch for an awesome library!

It would be great if the Z, ZZ and ZZZ parsing tokens accepted date strings with "Z" timezone (which is the same as -00:00 or +00:00. Or alternatively a token for matching the Zulu time ("Z").

Consider the following:

import { DateTime } from "luxon";

const expected = "2020-10-07T15:00:00.000Z";

describe("short offset ZZ", () => {
  const format = "yyyy-MM-dd'T'HH:mm:ssZZ";

  test(`Offset "-01:00" - pass`, () => {
    const t = "2020-10-07T14:00:00-01:00";
    expect(DateTime.fromFormat(t, format).toUTC().toISO()).toBe(expected);
  });

  test(`Offset "-00:00" - pass`, () => {
    const t = "2020-10-07T15:00:00-00:00";
    expect(DateTime.fromFormat(t, format).toUTC().toISO()).toBe(expected);
  });

  test(`Offset "Z" - fail`, () => {
    // The "ZZ" parsing token does not accept "Z" as a timezone
    //
    // Expected: "2020-10-07T15:00:00.000Z"
    // Received: null
    const t = "2020-10-07T15:00:00Z";
    expect(DateTime.fromFormat(t, format).toUTC().toISO()).toBe(expected);
  });
});

// To be able to match strings with `Z` timezones I have to add a literal `'Z'`
// to the format, and below you see why that is a problem (or inconsistency):
describe("zulu offset", () => {
  const format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
  const t = "2020-10-07T15:00:00Z";

  test(`Offset "'Z'" without zone hint - fail`, () => {
    // Since "'Z'" is not a parsing token, Luxon assumes the time is in the
    // timezone of the browser/server - so this test fails.
    //
    // Expected: "2020-10-07T15:00:00.000Z"
    // Received: "2020-10-07T22:00:00.000Z"
    expect(DateTime.fromFormat(t, format).toUTC().toISO()).toBe(expected);
  });

  test(`Offset "'Z'" with zone hint - pass`, () => {
    // Here we tell Luxon the tz of the input date is UTC, so it creates the
    // correct datetime, and the test pass. 
    expect(
      DateTime.fromFormat(t, format, { zone: "UTC" }).toUTC().toISO()
    ).toBe(expected);
  });
});

Essentially, I think it would make sense if fromFormat() would understand that what timezone the input is for Zulu time stings, just as it already does with -00:00 and +00:00.

lirbank avatar Oct 03 '20 05:10 lirbank

More importantly, I would expect the fromISO() to parse the string properly, since new Date.toISOString() returns the UTC date with the Z. If you run that through fromISO() right now it will parse as invalid. I'm having to add additional code to compensate

const iso = value.slice(-1) === 'Z' ? value.slice(0, -1) : value;
const dateObj = DateTime.fromISO(iso, options);

EDIT: I was wrong. It does work. But I agree with you on figuring it out with the fromFormat in some way

cutterbl avatar Oct 08 '20 12:10 cutterbl

I agree that fromFormat should support that token one way or another.

Note, though, that all your use cases presented there would get parsed fine by fromISO. That's most of the situations in which Zulu is used, and it's explicitly supported

icambron avatar Oct 23 '20 01:10 icambron

Hello @icambron I believe this issue should not be considered as an enhancement but a bug/missing feature because fromFormat is not compliant with the ISO format as it does not handle the 'Z' format properly when given 'Z' (Zulu) timezone.

Since already implemented in fromISO, why not make fromFormat also consistent and compliant?

As of 29/12/2022 using Luxon 3.1.1 the code below does not work properly while not even being documented as not standard compliant in the documentation:

DateTime.fromFormat('10:11:12Z', 'hh:mm:ssZ') -> null, DateTime.fromFormat('2022-12-29Z', 'yyyy-MM-ddZ) -> null, DateTime.fromFormat('2022-12-29T10:11:12Z', 'yyyy-MM-dd'T'hh:mm:ssZ') -> null

QTimort avatar Dec 29 '22 02:12 QTimort

@QTimort A "missing feature" is just a feature you want that doesn't exist yet, and hence adding it would be an enhancement. But you can call it whatever you want; either way it won't be implemented until someone implements it.

icambron avatar Dec 29 '22 03:12 icambron