FIX: Resolve timezone issues with date-time-input (#21414)

- Ensure changing timezones are reflected immediately in the date-time-input (the computed property was missing a dependent key)

- Ensure date-input doesn't lose timezone information (calling `toDate()` causes moment timestamps to lose timezone information)

This was created to resolve issues in the discourse-calendar plugin (https://github.com/discourse/discourse-calendar/pull/399)
This commit is contained in:
David Taylor 2023-05-05 18:18:24 +01:00 committed by GitHub
parent 37cacf72ae
commit c9a6d9ac89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 4 deletions

View File

@ -54,7 +54,7 @@ export default Component.extend({
if (this._picker && this.date) { if (this._picker && this.date) {
const parsedDate = const parsedDate =
this.date instanceof moment ? this.date : moment(this.date); this.date instanceof moment ? this.date : moment(this.date);
this._picker.setDate(parsedDate.toDate(), true); this._picker.setDate(parsedDate, true);
} }
}); });
}); });
@ -66,7 +66,7 @@ export default Component.extend({
if (this._picker && this.date) { if (this._picker && this.date) {
const parsedDate = const parsedDate =
this.date instanceof moment ? this.date : moment(this.date); this.date instanceof moment ? this.date : moment(this.date);
this._picker.setDate(parsedDate.toDate(), true); this._picker.setDate(parsedDate, true);
} }
if (this._picker && this.relativeDate) { if (this._picker && this.relativeDate) {
@ -75,7 +75,7 @@ export default Component.extend({
? this.relativeDate ? this.relativeDate
: moment(this.relativeDate); : moment(this.relativeDate);
this._picker.setMinDate(parsedRelativeDate.toDate(), true); this._picker.setMinDate(parsedRelativeDate, true);
} }
if (this._picker && !this.date) { if (this._picker && !this.date) {

View File

@ -66,7 +66,7 @@ export default Component.extend({
); );
}, },
@computed @computed("timezone")
get resolvedTimezone() { get resolvedTimezone() {
return this.timezone || moment.tz.guess(); return this.timezone || moment.tz.guess();
}, },

View File

@ -54,4 +54,20 @@ module("Integration | Component | date-input", function (hooks) {
assert.ok(this.date.isSame(moment("2019-02-02"))); assert.ok(this.date.isSame(moment("2019-02-02")));
}); });
test("always shows date in timezone of input timestamp", async function (assert) {
this.setProperties({
date: moment.tz("2023-05-05T10:00:00", "ETC/GMT-12"),
});
await render(
hbs`<DateInput @date={{this.date}} @onChange={{this.onChange}} />`
);
assert.strictEqual(dateInput().value, "2023-05-05");
this.setProperties({
date: moment.tz("2023-05-05T10:00:00", "ETC/GMT+12"),
});
assert.strictEqual(dateInput().value, "2023-05-05");
});
}); });

View File

@ -63,4 +63,23 @@ module("Integration | Component | date-time-input", function (hooks) {
assert.notOk(exists(timeInput())); assert.notOk(exists(timeInput()));
}); });
test("supports swapping timezone without changing visible date/time", async function (assert) {
this.setProperties({
date: moment.tz("2023-05-05T12:00:00", "Europe/London"),
timezone: "Europe/London",
onChange: setDate,
});
await render(
hbs`<DateTimeInput @date={{this.date}} @timezone={{this.timezone}} @onChange={{this.onChange}} />`
);
dateInput().dispatchEvent(new Event("change"));
assert.strictEqual(this.date.format(), "2023-05-05T12:00:00+01:00");
this.setProperties({ timezone: "Australia/Sydney" });
dateInput().dispatchEvent(new Event("change"));
assert.strictEqual(this.date.format(), "2023-05-05T12:00:00+10:00");
});
}); });