本来自己打算用 UTC 存,结果手欠百度了一下,结果发现用什么存储的都有。 现在乱了,不知道怎么存了,求大佬帮忙打醒
1
ss098 2021-07-13 14:13:34 +08:00 5
UTC,客户端自行根据本地时间格式化。
|
2
richangfan 2021-07-13 14:15:43 +08:00
当然是服务器本地时间了,转换多麻烦,又没有国外用户
|
3
Jirajine 2021-07-13 14:20:49 +08:00 via Android 2
当然是 UTC,要不然服务器时区一变(更换机房、新安装的系统没有修改等),全都乱套。
|
4
dqzcwxb 2021-07-13 14:21:11 +08:00 2
偷懒的结果就是付出更多
|
5
zjyl1994 2021-07-13 14:22:09 +08:00
时间戳最没有歧义了,而且到处都可以格式化
|
6
tabris17 2021-07-13 14:24:32 +08:00
如果取值范围不大的话,时间戳最好了
|
7
dynastysea 2021-07-13 14:25:10 +08:00
如果没有国外用户的话直接时间戳啊,搞 UTC 这些干啥。。时间戳有什么问题?
|
8
ytmsdy 2021-07-13 14:30:41 +08:00
后台存储 UTC,API 输出时输出时间戳。这样前端可以用用户的时区来显示具体时间
|
9
CEBBCAT 2021-07-13 14:47:10 +08:00
时间戳,UNSIGNED BIGINT
|
10
labulaka521 2021-07-13 14:52:16 +08:00
存时间戳 然后再把用户的时区存储起来
|
11
wunonglin 2021-07-13 14:58:08 +08:00
干吗不用时间戳
|
12
snail00 2021-07-13 15:01:16 +08:00
从数据库到后台服务全部统一 UTC+8
|
13
hackersli 2021-07-13 15:33:58 +08:00
时间戳吧,怎么转换都可以哇
|
14
clf 2021-07-13 15:57:33 +08:00
时间戳是最方便的。无论从数据库的查询效率来说,还是不同代码的通用性来说,时间戳都很好用。
|
15
weizhen199 2021-07-13 16:29:26 +08:00
@dqzcwxb 付出更多可以弄更多的改造项目 /doge
|
17
clf 2021-07-13 17:40:39 +08:00
@bthulu #17 bigint 类型,对应 Java 的 Long 类型。就是一串数字,从 UTC 1970 年 1 月 1 日 0 时 0 分 0 秒开始到现在的毫秒数。
datetime 的查询效率是低于 bigint 的。 |
19
lfzyx 2021-07-13 17:44:57 +08:00
时间戳是 Epoch time
|
20
rrfeng 2021-07-13 17:47:30 +08:00
当然存 timestamp
每次遇到人时间 /时区搞不清楚的时候就很恼火。 |
21
Cy1 2021-07-13 18:05:47 +08:00
直接时间戳,各端根据时区自己格式化显示。
|
22
cmdOptionKana 2021-07-13 18:29:40 +08:00 10
看来关心时区问题的人不多呀,一大堆说时间戳……
时间戳也分 “UTC” 时间戳和 “本地时间” 时间戳的好吗。 |
23
BenX 2021-07-13 18:36:19 +08:00
UTC 秒数存下来,至于使用端的逻辑,看那一层处理了。 时间戳,跨时区不是自找麻烦
|
24
libook 2021-07-13 18:43:55 +08:00
看需求。
如果你有个强大的数据库,那么可能怎么存时间无所谓。 如果数据库不够强的话: 如果你的服务只在一个时区开展的话,用本地时间记录可以方便数据的统计分析; 如果希望跨时区的话就最好用 UTC ; 用 ISODate 格式的话方便于根据日期查询; 用时间戳格式便于进行数学计算; …… 没有银弹。 |
26
Yut 2021-07-13 18:58:12 +08:00 via Android
那肯定是 Unix 时间啊,存其他的都有可能要转两道
|
28
gtexpanse 2021-07-13 19:06:04 +08:00 1
@cmdOptionKana #23 时间戳本身是没有时区概念的,只是他要基于 UTC1970 年这个基准而产生。
使用时间戳来交互的方便之处在于,给出一个时间戳,不论你处于哪个时区,这个时间戳表示的时间点基准点的秒数都是相同的,也就是说时间的长度是固定的,但你拿时间戳想转换为“时间”的时候是必须要带入时区概念的——可以想象成尺子的长度是固定的,但是想看最终的读数必须要带入时区。 |
29
qiayue 2021-07-13 19:10:58 +08:00 7
@cmdOptionKana 时间戳是唯一的,不存在 UTC 时间戳还是本地时间时间戳。
时间戳的定义式从 1970 年 1 月 1 日零点到现在经过的秒数。 时间戳可以格式化为各地时间,如时间戳 0 值,你格式化为 UTC 时间,就是 1970 年 1 月 1 日 0 点,你格式化为北京时间,就是 1970 年 1 月 1 日 8 点。 |
30
mxT52CRuqR6o5 2021-07-13 19:13:46 +08:00
@cmdOptionKana 时间戳没有时区的,时间戳转为年月日是需要考虑时区
|
31
SuperMild 2021-07-13 19:17:53 +08:00 1
@gtexpanse 我没说清楚,我本来想说就算用时间戳,也有 “直接用本地时间转时间戳” 与 “先转 UTC±00:00 再转时间戳” 两种做法。
因为,如果每个客户端都先转 UTC±00:00, 按这个统一转时间戳,就能兼顾时区了。 按我理解,楼主主要想问的是要不要处理时区,而回答 “用时间戳” 是回答不了 “要不要处理时区” 这个问题的,因为用时间戳既可以处理时区(方法是统一转 UTC±00:00 ),也可以不处理时区。 |
32
crclz 2021-07-13 19:20:37 +08:00 1
首先,存到数据库里面的东西都要标准化,所以统一使用 UTC 时间。
建议统一使用 int64 UTC milliseconds. 当然 int64 UTC seconds 也行,只不过都是 int64,不会省空间的。 还有就是要注意,避免在 ORM 的实体上面使用语言自带的日期类型,例如 C#的 DateTime 、DateTimeOffset,例如 Java 的 Datetime 。虽然看起来方便,但是最终会付出额外的成本。 keep it simple and stupid. 这虽然笨了点,但是却能够避免很多问题,并且别人也更加容易看懂你的代码。 |
33
cmdOptionKana 2021-07-13 19:22:30 +08:00
|
34
tokyo2021 2021-07-13 19:56:56 +08:00 5
1 看了前面很多,感觉有的也没理解啥是时间戳的概念呀, 我一直做海外游戏后端,稍微了解一点。
时间戳 故名思义 表示戳记, 记录 1 个事件发生时的时间戳记 举个例子: 当抵达上海的入境海关,给你护照上盖个时间戳,这是中国 cst 时间,时间格式是 ISO 那个 8644(好像是)格式, 抵达东京的海关入境时护照上面当然也会盖一个时间戳,这是东京时间,时间格式又是 1 种,他们的时间格式。 你手机拍的照片, 同时也会存储拍照时的时间戳记, 那计算机通常采用 unix timestamp 存储时间戳记。 一般是从 1970 年 1 月 1 日 0 时至今的秒数。 为啥 1970 年呢, 应该是 unix 系统就是 1970 年正式发布诞生,选择就从 1970 年开始记吧。UTC 世界协调时,啥原子能机构授时的机构发布,严谨的来说不要在 UTC 上面表示+- 时区,UTC 就是世界协调时。 一般+- 是 GMT +1, GMT -2,本地时间和 GMT 的偏差,PST,PDT,和 GMT 时间做转换,还有海洋时间等等 2 觉得如果是 mysql 数据库,最好使用 datetime 格式, 做时区存储 (公元 0000 到 9999 年时间),SQL 查询(自带丰富的时间函数), 转换(天数加减)非常的方便。mysql 8.0.19 版本以来,支持插入的时间可以带上偏移的参数,支持多个时区的数据插入到同 1 个数据库,这样始终存储的是同 1 个时区的时间。 3 觉得时间特别容易引起 bug, 当年 iPhone 就因为时间存储问题,变成砖了~ |
35
lix7 2021-07-13 20:15:17 +08:00
永远都存毫秒级时间戳
|
36
SingeeKing 2021-07-13 20:40:19 +08:00 via iPhone
@SuperMild 先转 UTC0 的唯一「好处」是浪费了点时间…
|
37
oooooooooooo 2021-07-13 20:55:41 +08:00 via Android
|
38
ngn999 2021-07-13 22:08:22 +08:00
我理解是应该存下时刻, 展示时, 把时刻转到相应的时区就好了.
|
39
akira 2021-07-13 22:13:30 +08:00
看你的用户群体
|
40
cmdOptionKana 2021-07-13 22:20:04 +08:00
|
41
paulw54jrn 2021-07-13 23:04:35 +08:00 via Android
Epoch 或者 UTC iso8601
|
42
realradiolover 2021-07-13 23:37:10 +08:00 8
UNIX 时间戳是绝对的。其度量基准为:从伦敦时间 1970 年 1 月 1 日 0 时开始,到此刻的秒数。
在某一时刻,全球不同地区时区不同,因此钟表时间也不相同(“时差”的来源),但 UNIX 时间戳是一致的。e.g.: 此刻,是北京时间 23:08:00,伦敦时间 15:08:00,美国东部时间 11:08:00,但此刻三个地方的 UNIX 时间戳都是 1626188880 。 同样道理,你获得此刻的 UNIX 时间戳,在全球不同时区,翻译得到的时间也是不同的;几乎所有的操作系统都有“区域,语言”之类的配置项,就是为了根据你的设备所在的时区,来翻译出“合适”的时间。e.g.:手机的“时钟”APP 通过 ntp 授时服务获得此刻的 UNIX 时间戳 1626188880,然后检查手机系统配置的“区域”,如果此刻你在上海,那么时钟显示“23:08:00”;此刻,你在夏威夷的同学,他的手机时钟 APP 也得到了同样的 1626188880,但他的系统区域设置是夏威夷,那么时钟将显示太平洋时间“05:08:00” 由此可见,各国日常生活所使用的时间是不过是表象,是相对的。这是为了照顾人们的生活习惯,午夜一定是 0 点,正午一定是 12 点。因此全球需要一个绝对的基准,一般用 UTC 来度量,计算机科学则使用 unix timestamp. PS:基于北京时间的时间戳,本身就是一个伪命题。时间戳只有一个全球的绝对的。早期照片文件 EXIF 信息就忽略了这一点,只存了文本而没有时区。造成时间转换的混乱 |
43
smallthing 2021-07-13 23:41:17 +08:00
@cmdOptionKana 所谓本地世界的时间戳 就是一个错误的时间戳罢了。
|
44
cszchen 2021-07-13 23:49:48 +08:00 via iPhone 3
mysql 用 timestamp pgsql 用 timestamptz,都带有时区,根据客户端时区转换
|
45
acmore 2021-07-14 00:32:54 +08:00
把时区带进数据库中给人的感觉就像把前端样式存在数据库了一样。
很多时候没啥不行,说不定还很好用,但是让人浑身不自在。 |
46
jupiter157 2021-07-14 03:30:15 +08:00 via iPhone
时间戳是强制换算到 utc0 的,和楼主存 utc0 时间有差别吗?前者是毫秒,对机器友好,后者所见即所得,对人类友好。反正别存本地时间,如果实在必须,可以存成字符串后面永远带着时区的尾巴。
|
47
jupiter157 2021-07-14 03:44:35 +08:00 2
楼主存 6 个,是下下策,原因有三。1 ) 5 个信息冗余,换来的优点是可以节省转换时间,调用可以没有格式要求; 2 )时间转换效率是会随着硬件和软件提升不断改善的,节省的时间会越来越少; 3 )冗余的数据会越来越多,如果有天想删了,发现不同的程序调用的格式都不一样。
|
48
qfdk 2021-07-14 04:21:45 +08:00 via iPhone
ISO8601 然后前端用 dayjs 这样的库来显示
|
49
ericls 2021-07-14 04:25:46 +08:00 via iPhone
存未来的时间只能用 string
|
50
sutra 2021-07-14 08:36:49 +08:00
当你使用本地时间存储时,需要考虑时区、夏令时。
|
51
bxb100 2021-07-14 08:44:23 +08:00
只要存储的信息里面包含(隐式 /显式)时区信息, 那么最终的展示应该根据 local zone 来计算, 不要预先考虑 DST/WT/ST, 最终转换使用工具类即可
|
52
Mithril 2021-07-14 08:49:02 +08:00
只要你不想知道这数据是从哪个时区生成的,那你可以直接存 UTC 或者时间戳。
否则直接 ISO |
53
liuidetmks 2021-07-14 08:52:33 +08:00
@cmdOptionKana 时间戳就是格林威治时间,各个时区都是一样的吧?
|
54
cmdOptionKana 2021-07-14 08:58:31 +08:00
@liuidetmks 是一样的,我理解错了。幸好参与了讨论,不然我都没发现自己错误(因为我的做法也不会导致结果出错,所以靠自己很难发现)。
|
55
Cbdy 2021-07-14 09:01:37 +08:00 via Android
timestamptz 不好吗?
|
56
p1gd0g 2021-07-14 09:06:06 +08:00
看到有人说时间戳加时区的,忍不住说两句。
我们做海外手游的,客户端曾经因为时间戳加了时区导致时间戳结果为负数,直接闪退。 |
57
SilentDepth 2021-07-14 09:06:38 +08:00 1
完全没想到楼主最终选择的方案是全都存,而且存 6 种……
存 UTC 就得了,或者存带时区的 ISO8601 (取决于是否需要保留初始时区信息)。想不到有什么问题是解决不了的。 |
58
egfegdfr 2021-07-14 09:11:31 +08:00
存时间戳的 不考虑可读性吗? 每次查问题,或者是直接在数据库里面查数据的时候 都需要 format 一下,不累吗
直接时间格式不香吗, 能后时区问题的话,可以存 utc 时间,能后根据时区转换 |
59
falcon05 2021-07-14 09:13:45 +08:00 via iPhone 1
WordPress 的 posts 表还真的是把 gmt 和本地时间都存了一份。
|
60
Ariver 2021-07-14 09:21:04 +08:00
建议对这个概念不太清楚的把楼上回复仔细看完。
时区这个概念对于稍微有点经验的开发都是必须掌握的。 |
61
ikas 2021-07-14 09:22:13 +08:00
用 utc..用 db 原生时间类型..db 默认时区也配置为 utc 时区...
现在比如 elasticsearch 都是默认如此,并且完全不提供给你修改默认时区的机会.. |
62
mcluyu 2021-07-14 09:30:03 +08:00
哈哈哈。。想不到啊想不到,V 站这么多人连时间戳都搞不清。。
|
63
Torpedo 2021-07-14 10:12:10 +08:00
说到时间,想起和 php 后端对的时候,都是时间戳。和 java 后端就是各种时间格式化后的字符串。。。
|
64
imnpc 2021-07-14 10:19:25 +08:00
1.针对单一地区的 ,例如只有 国内 直接时间戳就可以 然后程序处理好 GMT +8 输出
2.针对多个国家 /地区 /时区的 一律 UTC 存入 然后根据用户所在地区输出准确时间 |
67
Dragonphy 2021-07-14 10:37:07 +08:00 1
存 UTC 还是 UTC+8 根本不是问题,问题是部署的容器时间都是 UTC 时间,每次看日志都要自动+8😂
|
68
Lemeng 2021-07-14 10:44:28 +08:00
需求是什么
|
70
winglight2016 2021-07-14 11:42:46 +08:00
有跨时区的需求那么必须两个都存,utc 统一核算,本地时间客户端使用,毕竟一个用户也许会有不同时区的账单呢?
|
71
waterb 2021-07-14 11:51:23 +08:00
真希望时间戳能成为标准
首先 UI 不会把所有用到时间的地方都统一格式 其次我遇到的绝大部分后台也不会根据当前 UI 的格式给我字符串 导致经常会有后台给我字符串 我要转成时间戳 再转成 UI 格式 是真的操蛋 |
72
evilStart 2021-07-14 12:03:06 +08:00 via Android 3
不是,这玩意儿从盘古开天开始就是存 UTC 时间的吧?
楼上这么多说不存 UTC 时间而存时间戳的让我感觉进了北大青鸟培训班。你们说的时间戳是指 UNIX 时间戳吧?这本质上就是 UTC 时间的秒数。而且获得正确的时间戳的前提是代码里的 Date 对象时区要正确。所以为什么不直接存 UTC 时间?可读性还更高。 |
74
GuuJiang 2021-07-14 12:12:23 +08:00 via iPhone
@cmdOptionKana 居然还有另外 7 个人点赞,太可怕了,时间戳和时区没有任何关系!只有当把时间戳转换为人可读的时间时才涉及时区
|
75
evilStart 2021-07-14 12:21:14 +08:00 via Android 2
@evilStart UTC 时间不仅可读性更高,能够替代一切使用时间戳的场景,而且许多数据库都对 Date 类型有特殊的查询优化。比如你需要找到某年某月的所有记录,要是存时间戳你要怎么查?把月头月末的时间戳都算出来然后再查询?存 UTC 时间的话查询语句就很直观。
数据库都提供给你日期类型不用,非要存时间戳那真是自找麻烦。 |
76
muzuiget 2021-07-14 12:52:00 +08:00
我以为“时间”默认就是“Unix 时间戳”那个 32/64 的整数,想不到那么多人会带入时区的概念。
程序内部各种储存通信计算一律“Unix 时间戳”,只有给用户交互那一层再转换成可读字符串格式。 |
77
zxbutton 2021-07-14 13:35:48 +08:00
楼上很多太秀了,当然是存 UTC,根据客户端所在时区展示
|
78
masterclock 2021-07-14 13:39:07 +08:00
1 、时间戳,即 timestamp,只是个时间标签的概念,不涉及任何定义、实现、格式。
2 、楼上一些人说的 “时间戳” 是 unix epoch ?这是个整数的秒数,扩展一下毫秒也行,也不涉及存储,也许有人要存成 36 进制数文本呢? 3 、UTC 时间 是个时间的标准,不涉及表示、格式、存储。 4 、有些数据库有 timestamp 、timestamptz 等格式,可以极度方便地存储、查询时间。 5 、一般用 timestamptz,除非不是表示时间点。 6 、pg 提供一堆函数来处理时间,比如 date_trunc 到日、周等。 7 、有些数据库用 int64 、uint64 来存储时间,因为要精确到纳秒. |
79
egfegdfr 2021-07-14 13:48:45 +08:00 1
@7v9TEc53 在查数据问题的时候,都是 习惯 select * from 的,如果是时间戳,需要手动 format, 还有,如果是客户端能直接连的话,都是直接打开的,sql 都不写
|
80
szq8014 2021-07-14 13:51:00 +08:00
直接 MySQL 存 timestamp 。
什么,2038 年限制? 那不还剩下 16+年呢? 但愿我做的项目能运行到那个时候。。 |
81
TomatoYuyuko 2021-07-14 14:24:42 +08:00
数据这东西最终用途不就是用来展示的吗,对于前端来说当然是愿意拿时间戳了,最怕后端给一堆乱七八糟时间格式前端你还得转换一遍
|
82
smallthing 2021-07-14 17:27:18 +08:00
@egfegdfr 一看你就是那种自己爽的后端。应该是写 java 的
|
83
ppphp 2021-07-14 18:10:36 +08:00
打日志用本地时间,存数据库最好当然是用时间戳,正常人类存时间戳都是 unix epoch 的,没有任何歧义,数据库服务,服务数据库客户端(orm),宿主系统,客户端有一个地方处理时区处理不好,就很麻烦
|
84
Digitalzz 2021-07-14 18:36:12 +08:00
直接所有的服务器的时间都设置成 UTC 时间,存储自然是 UTC,然后根据需求在代码里加时区。
|
85
jimmyismagic 2021-07-14 20:57:13 +08:00
@szq8014 2038,那是有符号整数
|
86
egfegdfr 2021-07-15 09:13:11 +08:00
@smallthing 前端 python java 都写过。刚开始工作的时候,团队中经常辩论用时间戳还是 Y M D 好,到现在公司各团队几乎是没人在讨论这个了 都是用的 年月日 时分秒 格式。
|
87
julyclyde 2021-07-15 12:00:20 +08:00
即使“仅在”中国,也不是单一时区
新中国成立的时候还继承了民国的五大时区制,90 年代还有过夏令时 |
88
xuanbg 2021-07-15 13:33:33 +08:00
时间到底存什么?只要统一标准,存什么都行。
|
89
smallthing 2021-07-22 13:01:14 +08:00
@egfegdfr 那说明你们的 CTO 喜欢这个
|