Front-end engineers, what do you do when you get a date/time data? Have you considered the issue of time zone?
Maybe you will say: Well, I didn't pay much attention to the time zone, but I tested it and it's no problem.
What can i say? Maybe you haven't met a foreign user yet!
Stolen day
If you get a date string "2021-11-17"
, in order to facilitate calculation and processing of data, you may first seal it into a Date
object:
const s = "2021-11-17";
const d = new Date(s);
What will I get when I use d.getDate()
17
, no problem!
Actually-how to put it-this is because you are in China. If this program runs in a browser and the browser happens to be located in Canada, will it still be 17
? Give it a try.
Enter the time setting under Windows, and change the time to "Pacific Time (US and Canada)" or other time zone of UTC-XX:00
Go to the browser again, you will find that d.getDate()
got 16
!
If it is under Linux, you can also reset the system time, and then use the Node console to view it, as shown in the figure below:
Why is one day missing?
Browser always uses local time
d
, you might as well take a look at what kind of data 061a01c81e295b is (remember to change the time zone back first!)
d.toString(); // Wed Nov 17 2021 08:00:00 GMT+0800 (中国标准时间)
d.toLocaleString(); // 2021/11/17 上午8:00:00
You see, when new Date("2021-11-17")
creates a date object, it uses 2021-11-17
as UTC 00:00:00
to create the object. And this time in China is 2021-11-17 08:00:00
. Similarly, if it is in -06:00
central Canada, it will be 2021-11-16 18:00:00
, this time .getDate()
, of course, will be 16
.
On the issue of processing time, the browser handles it simply and rudely, that is, according to the local time according to the system's time zone settings. If we give a precise time, the browser can handle it in this way. Date
world. At this point in time, it is morning in China and dusk in Canada. The problem is that the 061a01c81e29ca object can not only describe the date but also the time. After it automatically fills in the time data in UTC, we may get Unexpected results.
String with time part
So, what if the string representing the time is with time? Would it be more accurate... Try it:
// 为了方便查看,注释里的结果数据采用了简洁的描述
new Date("2021-11-17"); // 2021-11-17 08:00 +08:00
new Date("2021-11-17 00:00:00"); // 2021-11-17 00:00 +08:00
new Date("2021-11-17 09:00:00"); // 2021-11-17 09:00 +08:000
Note Article 2. In our common sense, 2021-11-17 00:00:00
and 2021-11-17
should be the same time, right? The latter does not have a time part, so by default it is the beginning of the day, which is 00:00:00
-the problem is here. The Date
object defaults to 0 o'clock in UTC instead of 0 o'clock in local time. But if you give the time, Date
will treat it as local time-there is a time difference somehow.
How to make no difference
Because new Date()
is parsed according to local time, in browsers in different regions, the same string representing the date and time will be parsed into different times-you see, 9 o'clock in the morning in China and morning in Canada 9 o'clock is definitely not the same time, right!
What if we want new Date()
to get the same time?
It's quite simple to say, as long as you get the string containing time zone information, for example, the time that conforms to the RFC3339 standard represents 2021-11-17T09:00:00+08:00
. RFC3339 is not detailed here, it just needs to be simply understood as
- The date part is in
yyyy-MM-dd
format - The time part is in
HH:mm:ss
orHH:mm:ss.sss
format T
connect between date and timeThe time zone part is in
Z
or±HH:mm
format, whereZ
means no time difference, that is, UTC time. For example, the following two times are at the same point in time2021-11-17T09:00:00+08:00
2021-11-17T01:00:00Z
Fortunately, Date
can recognize the time description that meets the RFC3339 standard, so the time created by the two strings in the above example is the same
const d1 = new Date("2021-11-17T09:00:00+08:00");
const d2 = new Date("2021-11-17T01:00:00Z");
console.log(d1.getTime() === d2.getTime());
What else to pay attention to
The reason has been explained, but some strange and weird problems will still appear in actual operation. The reason for these problems, in the final analysis, is still not paying attention to the "time zone." For example, let me ask a few questions to see if I can make it clear.
- Get a string that simply represents the date/time, which does not meet the RFC3339 standard, such as the aforementioned
"2021-11-17 09:00:00"
. Is it UTC time or local time? - If it is local time-is it the local time of the application server? Or the local time of the database server? Or is it the local time in the time zone of the user who entered the time...?
You see, a simple time zone problem is not just a front-end one-sided problem, it may be caused by ignoring the concept of time zone when the entire system is designed.
If the time zone issue is taken into account when the system is designed, and all storage and transmission use the same time zone description, the event will become much easier to handle. Of course, if you use UTC time directly, or a precise description such as Unix Time Stamp, it would be more ideal.
Some people may think that the browser does only support local time, but we can use Moment.js library, Day.js library, date-fns library... Yes, you can use various tools, but It is still necessary to understand that the time description obtained is accurate and unambiguous. Once again, the exact time description is:
- A string with time information, such as a string description in accordance with the RFC3339 standard;
- Based on a specific time in seconds, milliseconds or more subtle time offset values, such as Unix Time Stamp.
Our program was born in China, but it has to face the world-have you considered the time zone?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。