hexo icon indicating copy to clipboard operation
hexo copied to clipboard

permalink date is incorrect if the time zone of _config.yml and the time zone setting of the machine are different

Open MatchaChoco010 opened this issue 6 years ago • 6 comments

Environment Info

Node version(node -v):v10.9.0

site to reproduce the ploblem:

https://github.com/MatchaChoco010/hexo-timezone-permalink

$ hexo version
hexo: 3.7.1
hexo-cli: 1.1.0
os: Linux 4.4.0-17134-Microsoft linux x64
http_parser: 2.8.0
node: 10.9.0
v8: 6.8.275.24-node.14
uv: 1.22.0
zlib: 1.2.11
ares: 1.14.0
modules: 64
nghttp2: 1.32.0
napi: 3
openssl: 1.1.0i
icu: 62.1
unicode: 11.0
cldr: 33.1
tz: 2018e

For BUG

_config.yml is this:

...
timezone: America/New_York
...
permalink: :year/:month/:day/:title/
...

and source/_posts/test.md is this:

---
title: test
date: 2018-10-11 23:00:00
tags:
---

The permalink of this article should be /2018/10/11/test/. But hexo generate in Japan, which +0900, /2018/10/12/test/index.html is generated.

screenshot0

The article date is correct (2018/10/11).

screenshot1

Change the machine timezone to -0500 and hexo generate, /2018/10/11/test.index.html is generated.

It seems that the permalink is not generated correctly if the time zone of _config.yml and the time zone setting of the machine are incorrect.

MatchaChoco010 avatar Oct 11 '18 12:10 MatchaChoco010

@MatchaChoco010 Thanks a report. I reproduced it. But, I can't judge fix this behavior or not. I think this problem impact is big.

I ask to other hexo maintainer this problem.

yoshinorin avatar Oct 14 '18 10:10 yoshinorin

@tommy351 @NoahDragon @JLHwung How do you think about this.

yoshinorin avatar Oct 14 '18 10:10 yoshinorin

I spent some time digging into this today and found out where the bug is. Unfortunately removing timezone from _config.yml is not a valid workaround me because I run the build on a cloud server just prior to deploy which is running in UTC timezone.

Why the timezone is off?

In plugins/filter/post_permalink.js we can see how the path is constructed. It reads from data.date which is prepared by the hexo database layer. If you print the value, you will see that while the timestamp is correct, its timezone is off -- It's just UTC.

Why is the timezone specified in _config.yml not applied?

Next, I dig into why the timezone specified in the config file was not applied. The timezone is being used in models/types/moment.js in the cast function: It reads options.timezone where it is defined in models/post.js by reading [ctx.config.timezone](https://github.com/hexojs/hexo/blob/master/lib/models/post.js#L25).

Why the config appeared as the default config?

Now if you print out ctx.config, you will see that it is NOT your personal config. Instead, it's the default config comes with hexo. Digging into how hexo initialize hexo/index.js, we see that [registerModels](https://github.com/hexojs/hexo/blob/master/lib/hexo/index.js#L100) happened before [load_config](https://github.com/hexojs/hexo/blob/master/lib/hexo/index.js#L169). That's why!

Now, how to fix this?

This is where I'm not sure what's the best way to proceed. I think the current logic is wrong. We obviously are using config before it is loaded. We have a few options here:

  1. Move the initialization until after we load the config (aka here): This makes the most sense to me, however, it breaks tests because some of them don't call hexo.init() before using hexo stuff. I'm not sure how big the assumptions were. hexo.init() is also, unfortunately, an async function so we can't just simply call it in those callsites too.
  2. Make load_config synchronous and load it before init: It's a safer way to fix this as it maintains the API interface. However, now we will be reading config file before init() is being called which might break some other cases as well. It also makes the init function useless.

I'm happy to code this up and send a PR, but I would like to discuss which approach would be more preferable?

Thanks!

itszero avatar Feb 09 '19 20:02 itszero

still have someone try to fix this?

tobyqin avatar May 16 '20 09:05 tobyqin

@tobyqin So far, it is still remain as a known issue.

SukkaW avatar May 18 '20 01:05 SukkaW

@SukkaW thanks, I workaround it by removing the timezone info in config file and build environment.

tobyqin avatar May 18 '20 13:05 tobyqin