Check List
Please check the following before submitting a new issue.
The issue has been reported in
For example, I have a post setup as following:
# _config.yml
timezone: Asia/Shanghai
title: Hello World
date: 2020-09-29 23:00:00
Also, my machine is under the Asia/Shanghai timezone, which will also affect Node.js' timezone.
After the front-matter being processed by js-yaml, the "Date-like string" will be converted into Date object:
const jsYaml = require("js-yaml");
jsYaml.load('date: 2020-09-29 23:00:00');
// > "Tue, 29 Sep 2020 23:00:00 GMT"
Notice that the input was converted into the UTC? Users will only fill in the front-matter with their local time, not the UTC. Thus it is not the desired behavior.
So during the processing of front-matter, Date#getTimezoneOffset has been used:
// https://github.com/hexojs/hexo-front-matter/blob/ccbdff36d151a56932418cdc6d0329d866032a1b/lib/front_matter.js#L55-L62
// Convert timezone
Object.keys(data).forEach(key => {
const item = data[key];
if (item instanceof Date) {
data[key] = new Date(item.getTime() + (item.getTimezoneOffset() * 60 * 1000));
}
});
It will result in:
"Tue, 29 Sep 2020 15:00:00 GMT"
Which is the desired behavior.
Then, during the processing pf posts, moment.timezone was used:
|
if (data.date) { |
|
if (timezoneCfg) data.date = timezone(data.date, timezoneCfg); |
|
} else { |
|
exports.timezone = (date, timezone) => { |
|
if (moment.isMoment(date)) date = date.toDate(); |
|
|
|
const offset = date.getTimezoneOffset(); |
|
const ms = date.getTime(); |
|
const target = moment.tz.zone(timezone).utcOffset(ms); |
|
const diff = (offset - target) * DURATION_MINUTE; |
|
|
|
return new Date(ms - diff); |
|
}; |
If the config.timezone is configured correctly, there will be no differences between before and after timezone():
"Tue, 29 Sep 2020 15:00:00 GMT"
// There's no differences
A demo can be found here: https://runkit.com/sukkaw/5f732261a7aac8001a42bcc4
Date#getTimezoneOffset: -480
Date parsed by js-yaml: Tue, 29 Sep 2020 23:00:00 GMT
Date after calculating the timezone offset: Tue, 29 Sep 2020 15:00:00 GMT
Date after moment-timezone: Tue, 29 Sep 2020 15:00:00 GMT
Date after moment-timezone (without pre offset): Tue, 29 Sep 2020 15:00:00 GMT // Will be discussed later
So, what about a different timezone environment? For example, the CI environment. Its timezone will not be Asia/Shanghai.
So here is another demo: https://repl.it/repls/LividBewitchedControlflowgraph#index.js
Date#getTimezoneOffset: 0 // See? It is not -480 anymore, it is now 0
Date parsed by js-yaml: Tue, 29 Sep 2020 23:00:00 GMT
Date after calculating the timezone offset: Tue, 29 Sep 2020 23:00:00 GMT // It is now wrong
Date after moment-timezone: Tue, 29 Sep 2020 15:00:00 GMT // But it is still correct
Date after moment-timezone (without pre offset): Tue, 29 Sep 2020 15:00:00 GMT // Will be discussed later
As you can see, Date after calculating the timezone offset is now wrong, while Date after moment-timezone is still correct. That's because timezone() takes getTimezoneOffset into consideration.
So, what about removing "getTimezoneOffset" completely?
Here goes Date after moment-timezone (without pre offset). It is generated without using Date#getTimezoneOffset, and the result is still correct. It also means it is not affected by the environment (no `Date#getTimezoneOffset being used).
By eliminating the Node.js timezone affection (only dependents on users' config.timezone configuration) the timezone issue should be solved.
Check List
Please check the following before submitting a new issue.
hexo versionto check)The issue has been reported in
For example, I have a post setup as following:
Also, my machine is under the
Asia/Shanghaitimezone, which will also affect Node.js' timezone.After the front-matter being processed by
js-yaml, the "Date-like string" will be converted intoDateobject:Notice that the input was converted into the UTC? Users will only fill in the front-matter with their local time, not the UTC. Thus it is not the desired behavior.
So during the processing of front-matter,
Date#getTimezoneOffsethas been used:It will result in:
Which is the desired behavior.
Then, during the processing pf posts,
moment.timezonewas used:hexo/lib/plugins/processor/post.js
Lines 80 to 82 in 557487a
hexo/lib/plugins/processor/common.js
Lines 51 to 60 in 557487a
If the
config.timezoneis configured correctly, there will be no differences between before and aftertimezone():A demo can be found here: https://runkit.com/sukkaw/5f732261a7aac8001a42bcc4
So, what about a different timezone environment? For example, the CI environment. Its timezone will not be
Asia/Shanghai.So here is another demo: https://repl.it/repls/LividBewitchedControlflowgraph#index.js
As you can see,
Date after calculating the timezone offsetis now wrong, whileDate after moment-timezoneis still correct. That's becausetimezone()takesgetTimezoneOffsetinto consideration.So, what about removing "getTimezoneOffset" completely?
Here goes
Date after moment-timezone (without pre offset). It is generated without usingDate#getTimezoneOffset, and the result is still correct. It also means it is not affected by the environment (no `Date#getTimezoneOffset being used).By eliminating the Node.js timezone affection (only dependents on users'
config.timezoneconfiguration) the timezone issue should be solved.