src: make process.env.TZ setter clear tz cache
Since the presence of the libc and V8 timezone caches seem to be a perennial source of confusion to users ("why doesn't it work?!"), let's try to support that pattern by intercepting assignments to the `TZ` environment variable and reset the caches as a side effect. PR-URL: https://github.com/nodejs/node/pull/20026 Fixes: https://github.com/nodejs/node/issues/19974 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
5af28c26cf
commit
1d1ab76e17
10
src/node.cc
10
src/node.cc
@ -80,6 +80,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h> // tzset(), _tzset()
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -135,6 +136,7 @@ using v8::Array;
|
||||
using v8::ArrayBuffer;
|
||||
using v8::Boolean;
|
||||
using v8::Context;
|
||||
using v8::Date;
|
||||
using v8::EscapableHandleScope;
|
||||
using v8::Exception;
|
||||
using v8::Float64Array;
|
||||
@ -2679,6 +2681,10 @@ static void EnvSetter(Local<Name> property,
|
||||
node::Utf8Value key(info.GetIsolate(), property);
|
||||
node::Utf8Value val(info.GetIsolate(), value);
|
||||
setenv(*key, *val, 1);
|
||||
if (key.length() == 2 && key[0] == 'T' && key[1] == 'Z') {
|
||||
tzset();
|
||||
Date::DateTimeConfigurationChangeNotification(info.GetIsolate());
|
||||
}
|
||||
#else // _WIN32
|
||||
node::TwoByteValue key(info.GetIsolate(), property);
|
||||
node::TwoByteValue val(info.GetIsolate(), value);
|
||||
@ -2687,6 +2693,10 @@ static void EnvSetter(Local<Name> property,
|
||||
if (key_ptr[0] != L'=') {
|
||||
SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
|
||||
}
|
||||
if (key.length() == 2 && key[0] == L'T' && key[1] == L'Z') {
|
||||
_tzset();
|
||||
Date::DateTimeConfigurationChangeNotification(info.GetIsolate());
|
||||
}
|
||||
#endif
|
||||
// Whether it worked or not, always return value.
|
||||
info.GetReturnValue().Set(value);
|
||||
|
23
test/parallel/test-process-env-tz.js
Normal file
23
test/parallel/test-process-env-tz.js
Normal file
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
if (common.isWindows) // Using a different TZ format.
|
||||
common.skip('todo: test on Windows');
|
||||
|
||||
if (common.isAIX || common.isSunOS) // Reports 2018 CEST as CET.
|
||||
common.skip('tzdata too old');
|
||||
|
||||
const date = new Date('2018-04-14T12:34:56.789Z');
|
||||
|
||||
process.env.TZ = 'Europe/Amsterdam';
|
||||
if (/\(Europe\)/.test(date.toString()))
|
||||
common.skip('not using bundled ICU'); // Shared library or --with-intl=none.
|
||||
assert.strictEqual(date.toString(), 'Sat Apr 14 2018 14:34:56 GMT+0200 (CEST)');
|
||||
|
||||
process.env.TZ = 'Europe/London';
|
||||
assert.strictEqual(date.toString(), 'Sat Apr 14 2018 13:34:56 GMT+0100 (BST)');
|
||||
|
||||
process.env.TZ = 'Etc/UTC';
|
||||
assert.strictEqual(date.toString(), 'Sat Apr 14 2018 12:34:56 GMT+0000 (UTC)');
|
Loading…
x
Reference in New Issue
Block a user