Date & Timezone issue related with Front-Matter
- Dominant language
- TypeScript
- Stars
- 41.8k
- Forks
- 41
- PR merge metrics
- No merged PRs in 30d
Description
## Check List
Please check the following before submitting a new issue.
- [x] I have already read [Docs page](https://hexo.io/docs/) & [Troubleshooting page](https://hexo.io/docs/troubleshooting)
- [x] I have already searched existing issues and they are not helpful to me
- [x] I examined error or warning messages and it's difficult to solve
- [x] Using [the latest](https://github.com/hexojs/hexo/releases) version of Hexo (run `hexo version` to check)
- [x] Node.js is higher than [minimum required version](https://hexo.io/docs/#Minimum-required-Node-js-version)
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:
```js
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:
```js
// 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.
Contributor guide
Assessment
This issue has not been assessed yet.