fix(docs-infra): correctly display event dates on all timezones (#41053)
Previously, the event dates displayed on the angular.io "Events" page (`/events`) was off by one day on timezones with a negative offset from UTC. See https://github.com/angular/angular/pull/41050#issuecomment-788958888. This commit fixes it by using the `getUTC*` methods of the `Date` object to extract the date info, which are not affected by the user's timezone. PR Close #41053
This commit is contained in:
parent
5eab6e14f1
commit
cb16035fd3
|
@ -161,6 +161,7 @@
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
"shelljs": "^0.8.4",
|
"shelljs": "^0.8.4",
|
||||||
|
"timezone-mock": "^1.1.3",
|
||||||
"tree-kill": "^1.1.0",
|
"tree-kill": "^1.1.0",
|
||||||
"ts-node": "^8.4.1",
|
"ts-node": "^8.4.1",
|
||||||
"tslint": "~6.1.0",
|
"tslint": "~6.1.0",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Injector } from '@angular/core';
|
import { Injector } from '@angular/core';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import * as tzMock from 'timezone-mock';
|
||||||
import { Duration, Event, EventsComponent } from './events.component';
|
import { Duration, Event, EventsComponent } from './events.component';
|
||||||
import { EventsService } from './events.service';
|
import { EventsService } from './events.service';
|
||||||
|
|
||||||
|
@ -132,6 +133,20 @@ describe('EventsComponent', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getEventDates()', () => {
|
describe('getEventDates()', () => {
|
||||||
|
// Test on different timezones to ensure that event dates are processed correctly regardless of
|
||||||
|
// the user's local time.
|
||||||
|
const timezones: tzMock.TimeZone[] = [
|
||||||
|
'Australia/Adelaide', // UTC+9.5/10.5
|
||||||
|
'Brazil/East', // UTC-3
|
||||||
|
'UTC', // UTC
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const tz of timezones) {
|
||||||
|
describe(`on timezone ${tz}`, () => {
|
||||||
|
// NOTE: `timezone-mock` does not work correctly if used together with Jasmine's mock clock.
|
||||||
|
beforeEach(() => tzMock.register(tz));
|
||||||
|
afterEach(() => tzMock.unregister());
|
||||||
|
|
||||||
describe('(without workshops)', () => {
|
describe('(without workshops)', () => {
|
||||||
it('should correctly format the main event date', () => {
|
it('should correctly format the main event date', () => {
|
||||||
const testEvent = createMockEvent('Test', {start: '2020-06-20', end: '2020-06-20'});
|
const testEvent = createMockEvent('Test', {start: '2020-06-20', end: '2020-06-20'});
|
||||||
|
@ -147,6 +162,11 @@ describe('EventsComponent', () => {
|
||||||
const testEvent = createMockEvent('Test', {start: '2019-10-30', end: '2019-11-01'});
|
const testEvent = createMockEvent('Test', {start: '2019-10-30', end: '2019-11-01'});
|
||||||
expect(component.getEventDates(testEvent)).toBe('October 30 - November 1, 2019');
|
expect(component.getEventDates(testEvent)).toBe('October 30 - November 1, 2019');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should correctly format event dates at the beginning/end of the year', () => {
|
||||||
|
const testEvent = createMockEvent('Test', {start: '2021-01-01', end: '2021-12-31'});
|
||||||
|
expect(component.getEventDates(testEvent)).toBe('January 1 - December 31, 2021');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('(with workshops)', () => {
|
describe('(with workshops)', () => {
|
||||||
|
@ -213,6 +233,8 @@ describe('EventsComponent', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
class TestEventsService {
|
class TestEventsService {
|
||||||
|
|
|
@ -72,7 +72,7 @@ export class EventsComponent implements OnInit {
|
||||||
// If no work shop date create conference date string
|
// If no work shop date create conference date string
|
||||||
dateString = processDate(event.date);
|
dateString = processDate(event.date);
|
||||||
}
|
}
|
||||||
dateString = `${dateString}, ${new Date(event.date.end).getFullYear()}`;
|
dateString = `${dateString}, ${new Date(event.date.end).getUTCFullYear()}`;
|
||||||
return dateString;
|
return dateString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,14 +83,14 @@ function processDate(dates: Duration) {
|
||||||
const endDate = new Date(dates.end);
|
const endDate = new Date(dates.end);
|
||||||
|
|
||||||
// Create a date string in the start like January 31
|
// Create a date string in the start like January 31
|
||||||
let processedDate = `${MONTHS[startDate.getMonth()]} ${startDate.getDate()}`;
|
let processedDate = `${MONTHS[startDate.getUTCMonth()]} ${startDate.getUTCDate()}`;
|
||||||
|
|
||||||
// If they are in different months add the string '- February 2' Making the final string January 31 - February 2
|
// If they are in different months add the string '- February 2' Making the final string January 31 - February 2
|
||||||
if (startDate.getMonth() !== endDate.getMonth()) {
|
if (startDate.getUTCMonth() !== endDate.getUTCMonth()) {
|
||||||
processedDate = `${processedDate} - ${MONTHS[endDate.getMonth()]} ${endDate.getDate()}`;
|
processedDate = `${processedDate} - ${MONTHS[endDate.getUTCMonth()]} ${endDate.getUTCDate()}`;
|
||||||
} else if (startDate.getDate() !== endDate.getDate()) {
|
} else if (startDate.getUTCDate() !== endDate.getUTCDate()) {
|
||||||
// If not add - date eg it will make // January 30-31
|
// If not add - date eg it will make // January 30-31
|
||||||
processedDate = `${processedDate}-${endDate.getDate()}`;
|
processedDate = `${processedDate}-${endDate.getUTCDate()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return processedDate;
|
return processedDate;
|
||||||
|
|
|
@ -13168,6 +13168,11 @@ timers-ext@^0.1.5:
|
||||||
es5-ext "~0.10.46"
|
es5-ext "~0.10.46"
|
||||||
next-tick "1"
|
next-tick "1"
|
||||||
|
|
||||||
|
timezone-mock@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/timezone-mock/-/timezone-mock-1.1.3.tgz#f5ca25befec2cdd2d64c07ee7a5293275c06b97e"
|
||||||
|
integrity sha512-r+fz9M1tflNkF6mJK0DwmlFyNWeSCXxZ68pu2Bv+DddIHK/czOZwnasEql17VfHqP/OcZRuPq/qi6wm7eQmQow==
|
||||||
|
|
||||||
timsort@^0.3.0:
|
timsort@^0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||||
|
|
Loading…
Reference in New Issue