Skip to content
This repository was archived by the owner on Aug 1, 2024. It is now read-only.

Commit 84c9372

Browse files
Closure Teamcopybara-github
authored andcommitted
Fix a daylight saving time bug in formatDay.
If the current date-time is 23:MM PST on the day daylight saving time ends, and the passed in date-time is also 23:MM PST on the day daylight saving time ends (possibly for some other MM), then `formatDay` returns 'Tomorrow' rather than 'Today'. See the explanation in the comment added in this CL for why (and for the explanation of the fix). RELNOTES: Fix a daylight saving time bug in `formatDay`. PiperOrigin-RevId: 417926514 Change-Id: I2eefc039f16584abcbf4b321349dd18918805995
1 parent 095389c commit 84c9372

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

closure/goog/date/relative.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,29 @@ goog.date.relative.formatPast = function(dateMs) {
395395
goog.date.relative.formatDay = function(dateMs, opt_formatter) {
396396
'use strict';
397397
var today = new Date(goog.now());
398+
const originalTimezoneOffset = today.getTimezoneOffset();
398399

399400
today.setHours(0);
400401
today.setMinutes(0);
401402
today.setSeconds(0);
402403
today.setMilliseconds(0);
403404

404-
var dayOffset = (dateMs - today.getTime()) / goog.date.relative.DAY_MS_;
405+
// It is possible for the time zone to differ between 00:00 and HH:MM on a
406+
// given day if daylight saving time ended on that day some time before HH:MM.
407+
// In this case, the number of hours between 00:MM and HH:MM is not HH. It is
408+
// HH + 1. In most cases this doesn't matter, but if the current date-time is
409+
// 23:MM in PST on the day daylight saving time ended (e.g. Nov 7, 2021) and
410+
// `dateMs` is in that same hour, then without correction, the number of hours
411+
// between 00:00 and 23:MM would be calculated as 24+ hours, causing
412+
// date-times corresponding to 'Today' to be formatted as 'Tomorrow' (e.g.
413+
// b/205512072). Here we correct the offset by computing the difference
414+
// between today's original time zone and the time zone at 00:00.
415+
const timezoneOffsetCorrection =
416+
(today.getTimezoneOffset() - originalTimezoneOffset) *
417+
goog.date.relative.MINUTE_MS_;
418+
419+
let dayOffset = (dateMs - today.getTime() + timezoneOffsetCorrection) /
420+
goog.date.relative.DAY_MS_;
405421

406422
dayOffset = Math.floor(dayOffset);
407423

closure/goog/date/relativecommontests.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,10 @@ function timestamp(str) {
7474
}
7575

7676
testSuite({
77-
setUpPage() {
77+
setUp() {
7878
// Ensure goog.now returns a constant timestamp.
7979
goog.now = () => baseTime;
80-
},
8180

82-
setUp() {
8381
stubs.replace(goog, 'LOCALE', 'en-US');
8482
/** @suppress {missingRequire} */
8583
stubs.set(goog.i18n, 'NumberFormatSymbols', NumberFormatSymbols_en);
@@ -209,6 +207,21 @@ testSuite({
209207
assertEquals(expected, fn(timestamp('1 January 2010 01:22:11'), format));
210208
},
211209

210+
testFormatDay_daylightSavingTime() {
211+
// November 7th 2021, 11:57:16 pm PST-08:00 (the day daylight saving time
212+
// ended that year, at a time after it ended that day)
213+
const daylightSavingEndMs = 1636358236277;
214+
goog.now = () => daylightSavingEndMs;
215+
assertEquals('today', relative.formatDay(daylightSavingEndMs));
216+
217+
// March 14, 2021 11:12:34 pm PDT-07:00 (end of the day DST began)
218+
const daylightSavingStartMs = 1615788754000;
219+
// March 15, 2021 00:12:34 am PDT-07:00 (the day _after_ DST began)
220+
const nextDayMs = daylightSavingStartMs + 3600000;
221+
goog.now = () => daylightSavingStartMs;
222+
assertEquals('tomorrow', relative.formatDay(nextDayMs));
223+
},
224+
212225
testGetDateString() {
213226
const fn = relative.getDateString;
214227

0 commit comments

Comments
 (0)