#4548·hexo

Date & Timezone issue related with Front-Matter

Author: SukkaWCreated Sep 29, 2020Updated Apr 10, 2026
Labelsdiscussiondates

Check List

Please check the following before submitting a new issue.

The issue has been reported in

  • #4239
  • #3397
  • #3282
  • #2063

For example, I have a post setup as following:

yaml
# _config.yml
timezone: Asia/Shanghai
yaml
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:

javascript
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:

javascript
// 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:

https://github.com/hexojs/hexo/blob/557487a2f8ab0065bf94d5a9466c54034f1db17f/lib/plugins/processor/post.js#L80-L82 https://github.com/hexojs/hexo/blob/557487a2f8ab0065bf94d5a9466c54034f1db17f/lib/plugins/processor/common.js#L51-L60

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.