头图

Have you considered the time zone?

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:

Snipaste_2021-11-17_20-32-01.png

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 or HH:mm:ss.sss format
  • T connect between date and time
  • The time zone part is in Z or ±HH:mm format, where Z means no time difference, that is, UTC time. For example, the following two times are at the same point in time

    2021-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?


边城客栈
全栈技术专栏,公众号「边城客栈」,[链接]

一路从后端走来,终于走在了前端!

58.1k 声望
28.5k 粉丝
0 条评论
推荐阅读
羡慕 C# 的 switch 表达式不,JS 也可以有
对于 C/Java 语系的语言,都有 switch 语法。switch 语法用于多分支是一个标准的用法,但这个分支语法的各分支之间存在穿透性,所以需要 break 来切断逻辑,这也成为 switch 语法中最重要的一个替在缺陷来源。此...

边城2阅读 1.3k

封面图
安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城31阅读 7.2k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco21阅读 2.1k评论 3

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 2k

封面图
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!

SegmentFault思否20阅读 5.6k评论 10

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.7k评论 3

封面图
Vue2 导出excel
2020-07-15更新 excel导出安装 {代码...} src文件夹下新建一个libs文件夹,新建一个excel.js {代码...} vue页面中使用 {代码...} ===========================以下为早期的文章今天在开发的过程中需要做一个Vue的...

原谅我一生不羁放歌搞文艺14阅读 20k评论 9

一路从后端走来,终于走在了前端!

58.1k 声望
28.5k 粉丝
宣传栏