const dt = new Date('2017-12-12');
console.log(format(dt, 'YYYY-MM-DD'));
以上代码记录2017-12-11在美国,但2017-12-12在印度。
我跟着这个github线程here并尝试了一些事情,但没有得到预期的结果。
我的期望是打印相同的日期而不考虑时区
为什么我需要这个: 考虑涉及生日的情景。如果我提供一些输入日期,则必须在所有地区显示为相同日期,而不管其时区如何。
答案 0 :(得分:1)
您需要先从Date
实例中减去本地时区的时区偏移量,然后再将其从format
传递到date-fns
。例如:
const dt = new Date('2017-12-12');
const dtDateOnly = new Date(dt.valueOf() + dt.getTimezoneOffset() * 60 * 1000);
console.log(format(dtDateOnly, 'YYYY-MM-DD')); // Always "2017-12-12"
您只想处理Date
实例的日期部分,因为时间部分对生日没有意义。但是,Date
对象不提供任何“仅日期”模式。您可以在本地时区或UTC中访问其日期和时间部分。问题是format
中的date-fns
总是在当地时区打印输出。
仅在日期部分执行构造函数时:
const dt = new Date('2017-12-12');
JavaScript引擎实际上假定了不完整的ISO 8601格式的字符串,并且对此进行了填充:
const dt = new Date('2017-12-12T00:00:00.000Z');
对您来说,它似乎仍然“无害”,但是date
实例不仅在UTC中而且还在本地时区公开该值。如果在美国东海岸构造Date
实例,您将看到以下输出:
> const dt = new Date('2017-12-12');
> dt.toISOString()
'2017-12-12T00:00:00.000Z'
> dt.toString()
'Tue Dec 11 2017 19:00:00 GMT-0500 (EST)'
> d.toLocaleString()
'12/11/2017 7:00:00 PM'
如果您知道format
中的date-fns
从本地时区的date
实例中读取日期和时间部分,则需要使日期看起来像“传递给Date
构造函数的本地时区而不是UTC的午夜。然后,您将看到保留的年,月和日期数字。这意味着,您需要减去指定日期的本地时区的时区偏移量。 Date.prototype.getTimezoneOffset
返回偏移量,但以分钟为单位的符号相反。
const dt = new Date('2017-12-12');
// Tue Dec 11 2017 19:00:00 GMT-0500 (EST)
const dtDateOnly = new Date(dt.valueOf() + dt.getTimezoneOffset() * 60 * 1000);
// Tue Dec 12 2017 00:00:00 GMT-0500 (EST)
console.log(format(dtDateOnly, 'YYYY-MM-DD'));
// Prints always "2017-12-12", regardless the time zone it executed in
但是,这样的Date
实例只能用于格式化仅日期值。例如,您不能将其用于计算日期差,这可能需要原始且正确的UTC值。
如果始终需要仅包含日期的dame格式,而不需要当前语言环境专用的格式,则不需要date-fns
。您可以通过填充数字的串联来格式化字符串:
const dt = new Date('2017-12-12');
const year = dt.getUTCFullYear()
const month = dt.getUTCMonth() + 1 // Date provides month index; not month number
const day = dt.getUTCDate()
// Print always "2017-12-12", regardless the time zone it executed in
console.log(year + '-' + padToTwo(month) + '-', padToTwo(day));
// Or use a template literal
console.log(`${year}-${padToTwo(month)}-${padToTwo(day)}`);
function padToTwo (number) {
return number > 9 ? number : '0' + number
}