From e5f1c1f7b03b0184a458c7fe875d06b63dfe647c Mon Sep 17 00:00:00 2001 From: Markus Marchewa <43089345+markusmarchewa@users.noreply.github.com> Date: Tue, 14 Jan 2025 08:55:05 +0100 Subject: [PATCH] Fix strftime implementations for format strings "%F" and "%j" (#475) * fix strftime, %F contains %Y (four digit) * fix strftime, %j with DST compensation --- src/php/datetime/strftime.js | 18 +++++++++++++----- test/generated/php/datetime/test-strftime.js | 12 ++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/php/datetime/strftime.js b/src/php/datetime/strftime.js index baa94a07d1..0e0e378f1c 100644 --- a/src/php/datetime/strftime.js +++ b/src/php/datetime/strftime.js @@ -8,6 +8,11 @@ module.exports = function strftime(fmt, timestamp) { // note 1: Uses global: locutus to store locale info // example 1: strftime("%A", 1062462400); // Return value will depend on date and locale // returns 1: 'Tuesday' + // bugfixed by: Markus Marchewa + // example 2: strftime('%F', 1577836800); + // returns 2: '2020-01-01' + // example 3: (() => {let e = process.env, tz = e.TZ; e.TZ = 'Europe/Vienna'; let r = strftime('%j', 1680307200); e.TZ = tz; return r;})(); + // returns 3: '091' const setlocale = require('../strings/setlocale') @@ -71,10 +76,13 @@ module.exports = function strftime(fmt, timestamp) { return _xPad(I === 0 ? 12 : I, 0) }, j: function (d) { - let ms = d - new Date('' + d.getFullYear() + '/1/1 GMT') - // Line differs from Yahoo implementation which would be - // equivalent to replacing it here with: - ms += d.getTimezoneOffset() * 60000 + // calculate the difference between the given date and the start of the year (in localtime), DST shifts may lead + // to deltas less than multiples of 24 hours (the day when DST starts has just 23 hours), compensate by adding + // the difference between timezone offsets (subtract since values are negative for positive offsets), e.g.: + // 2020-05-01 00:00:00 CEST, timezone +0200, offset -120 + // 2020-01-01 00:00:00 CET , timezone +0100, offset -60 + const b = new Date(d.getFullYear(), 0) + const ms = d - b - (d.getTimezoneOffset() - b.getTimezoneOffset()) * 60000 const doy = parseInt(ms / 60000 / 60 / 24, 10) + 1 return _xPad(doy, 0, 100) }, @@ -160,7 +168,7 @@ module.exports = function strftime(fmt, timestamp) { const _aggregates = { c: 'locale', D: '%m/%d/%y', - F: '%y-%m-%d', + F: '%Y-%m-%d', h: '%b', n: '\n', r: 'locale', diff --git a/test/generated/php/datetime/test-strftime.js b/test/generated/php/datetime/test-strftime.js index 5ffdf7c664..136c562aa5 100644 --- a/test/generated/php/datetime/test-strftime.js +++ b/test/generated/php/datetime/test-strftime.js @@ -16,4 +16,16 @@ describe('src/php/datetime/strftime.js (tested in test/generated/php/datetime/te expect(result).to.deep.equal(expected) done() }) + it('should pass example 2', function (done) { + var expected = '2020-01-01' + var result = strftime('%F', 1577836800); + expect(result).to.deep.equal(expected) + done() + }) + it('should pass example 3', function (done) { + var expected = '091' + var result = (() => {let e = process.env, tz = e.TZ; e.TZ = 'Europe/Vienna'; let r = strftime('%j', 1680307200); e.TZ = tz; return r;})(); + expect(result).to.deep.equal(expected) + done() + }) })