Skip to content

Commit

Permalink
--amend
Browse files Browse the repository at this point in the history
  • Loading branch information
icambron committed May 9, 2022
1 parent 2ee261b commit abe9bdf
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 6 deletions.
30 changes: 26 additions & 4 deletions src/datetime.js
Expand Up @@ -207,7 +207,14 @@ function toISODate(o, extended) {
return c;
}

function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOffset) {
function toISOTime(
o,
extended,
suppressSeconds,
suppressMilliseconds,
includeOffset,
extendedZone
) {
let c = padStart(o.c.hour);
if (extended) {
c += ":";
Expand All @@ -229,7 +236,7 @@ function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOf
}

if (includeOffset) {
if (o.isOffsetFixed && o.offset === 0) {
if (o.isOffsetFixed && o.offset === 0 && !extendedZone) {
c += "Z";
} else if (o.o < 0) {
c += "-";
Expand All @@ -243,6 +250,10 @@ function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOf
c += padStart(Math.trunc(o.o % 60));
}
}

if (extendedZone) {
c += "[" + o.zone.ianaName + "]";
}
return c;
}

Expand Down Expand Up @@ -1554,6 +1565,7 @@ export default class DateTime {
* @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0
* @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0
* @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
* @param {boolean} [opts.extendedZone=true] - add the time zone format extension
* @param {string} [opts.format='extended'] - choose between the basic and extended format
* @example DateTime.utc(1983, 5, 25).toISO() //=> '1982-05-25T00:00:00.000Z'
* @example DateTime.now().toISO() //=> '2017-04-22T20:47:05.335-04:00'
Expand All @@ -1566,6 +1578,7 @@ export default class DateTime {
suppressSeconds = false,
suppressMilliseconds = false,
includeOffset = true,
extendedZone = false,
} = {}) {
if (!this.isValid) {
return null;
Expand All @@ -1575,7 +1588,7 @@ export default class DateTime {

let c = toISODate(this, ext);
c += "T";
c += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset);
c += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone);
return c;
}

Expand Down Expand Up @@ -1610,6 +1623,7 @@ export default class DateTime {
* @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0
* @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0
* @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
* @param {boolean} [opts.extendedZone=true] - add the time zone format extension
* @param {boolean} [opts.includePrefix=false] - include the `T` prefix
* @param {string} [opts.format='extended'] - choose between the basic and extended format
* @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime() //=> '07:34:19.361Z'
Expand All @@ -1623,6 +1637,7 @@ export default class DateTime {
suppressSeconds = false,
includeOffset = true,
includePrefix = false,
extendedZone = false,
format = "extended",
} = {}) {
if (!this.isValid) {
Expand All @@ -1632,7 +1647,14 @@ export default class DateTime {
let c = includePrefix ? "T" : "";
return (
c +
toISOTime(this, format === "extended", suppressSeconds, suppressMilliseconds, includeOffset)
toISOTime(
this,
format === "extended",
suppressSeconds,
suppressMilliseconds,
includeOffset,
extendedZone
)
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/impl/regexParser.js
Expand Up @@ -32,7 +32,7 @@ function combineExtractors(...extractors) {
.reduce(
([mergedVals, mergedZone, cursor], ex) => {
const [val, zone, next] = ex(m, cursor);
return [{ ...mergedVals, ...val }, mergedZone || zone, next];
return [{ ...mergedVals, ...val }, zone || mergedZone, next];
},
[{}, null, 1]
)
Expand Down Expand Up @@ -67,7 +67,7 @@ function simpleParse(...keys) {

// ISO and SQL parsing
const offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/;
const isoExtendedZone = `(?:${offsetRegex.source}|\\[(${ianaRegex.source})\\])?`;
const isoExtendedZone = `(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`;
const isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;
const isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`);
const isoTimeExtensionRegex = RegExp(`(?:T${isoTimeRegex.source})?`);
Expand Down
4 changes: 4 additions & 0 deletions src/zone.js
Expand Up @@ -22,6 +22,10 @@ export default class Zone {
throw new ZoneIsAbstractError();
}

get ianaName() {
return this.name;
}

/**
* Returns whether the offset is known to be fixed for the whole year.
* @abstract
Expand Down
8 changes: 8 additions & 0 deletions src/zones/fixedOffsetZone.js
Expand Up @@ -62,6 +62,14 @@ export default class FixedOffsetZone extends Zone {
return this.fixed === 0 ? "UTC" : `UTC${formatOffset(this.fixed, "narrow")}`;
}

get ianaName() {
if (this.fixed === 0) {
return "Etc/UTC";
} else {
return `Etc/GMT${formatOffset(-this.fixed, "narrow")}`;
}
}

/** @override **/
offsetName() {
return this.name;
Expand Down
23 changes: 23 additions & 0 deletions test/datetime/format.test.js
Expand Up @@ -85,6 +85,29 @@ test("DateTime#toISO() renders 00:00 for non-offset but non utc datetimes", () =
expect(negativeYear.toISO()).toBe("1982-05-25T09:23:54.123+00:00");
});

test("DateTime#toISO() supports the extendedZone option", () => {
let zoned = dt.setZone("America/Chicago");
expect(zoned.toISO({ extendedZone: true })).toBe(
"1982-05-25T04:23:54.123-05:00[America/Chicago]"
);
expect(zoned.toISO({ includeOffset: false, extendedZone: true })).toBe(
"1982-05-25T04:23:54.123[America/Chicago]"
);

zoned = dt.setZone("UTC+6");
expect(zoned.toISO({ extendedZone: true })).toBe("1982-05-25T15:23:54.123+06:00[Etc/GMT-6]");
expect(zoned.toISO({ includeOffset: false, extendedZone: true })).toBe(
"1982-05-25T15:23:54.123[Etc/GMT-6]"
);

zoned = dt.setZone("UTC");
// note no Z
expect(zoned.toISO({ extendedZone: true })).toBe("1982-05-25T09:23:54.123+00:00[Etc/UTC]");
expect(zoned.toISO({ includeOffset: false, extendedZone: true })).toBe(
"1982-05-25T09:23:54.123[Etc/UTC]"
);
});

//------
// #toISODate()
//------
Expand Down
31 changes: 31 additions & 0 deletions test/datetime/regexParse.test.js
Expand Up @@ -575,6 +575,37 @@ test("DateTime.fromISO() accepts extended zones", () => {
});
});

test("DateTime.fromISO() accepts extended zones and offsets", () => {
let dt = DateTime.fromISO("2016-05-14T10:23:54+01:00[Europe/Paris]", {
setZone: true,
});
expect(dt.isValid).toBe(true);
expect(dt.zoneName).toBe("Europe/Paris");
expect(dt.toObject()).toEqual({
year: 2016,
month: 5,
day: 14,
hour: 10,
minute: 23,
second: 54,
millisecond: 0,
});

dt = DateTime.fromISO("2016-05-14T10:23:54+00:00[Etc/UTC]", { setZone: true });
expect(dt.isValid).toBe(true);
expect(dt.zoneName).toBe("Etc/UTC");
expect(dt.offset).toBe(0);
expect(dt.toObject()).toEqual({
year: 2016,
month: 5,
day: 14,
hour: 10,
minute: 23,
second: 54,
millisecond: 0,
});
});

test("DateTime.fromISO() accepts extended zones on bare times", () => {
const { year, month, day } = DateTime.now().setZone("Europe/Paris");
let dt = DateTime.fromISO("10:23:54[Europe/Paris]", {
Expand Down

0 comments on commit abe9bdf

Please sign in to comment.