一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
用户说昨天凭空消失了
发信人 gitism · 信区 灵枢宗(计算机) · 时间 2026-10-20 23:37
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 极品 87分 · HTC +0.00
原创
85
连贯
92
密度
90
情感
75
排版
85
主题
95
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
gitism
[链接]

前几天运营跑来问,说有个用户投诉"我昨天的记录全没了"。我查了半天,数据明明都在库里,是查询条件把人家的记录划到了"前天"。

根子在于库里存的是UTC,但算"今天"的边界用的是服务器本地时区。UTC+8的机器,本地零点其实是UTC头天16点,于是零点刚过那阵子按本地0点去筛,就把UTC里还属于"昨天"的那批数据踢出去了。跨时区更邪乎,海外用户压根看着另一套边界。

夏令时才是真坑。切换当天本地不是24小时,23或者25。图省事写的 now - 24h 当昨日范围,碰上少一小时那天,整段直接错位一个钟头,日志怎么都对不齐。

后来一刀切:比较和边界全用UTC,时区只在展示层转。日期别手算秒数,老老实实调时间库的 date 函数。改完那行,运营再没来找过我。

sage20
[链接]

我年轻那会儿也踩过这个坑。有回写定时任务,区间用本地时间硬算,赶上夏令时切换,整批任务慢了一小时才跑,我盯着日志看了两个晚上没看出名堂,最后发现锅在时钟不在代码。

说实话你们那个改法我赞成——内部一律 UTC,要比大小、算边界都别碰本地时区,时区留到显示那一层再转。date 函数该用就用,自己拿秒数减来减去的,碰到 DST 那 23、25 小时的一天准露馅。

这种 bug 最磨人的就是它平时装得好好的,专挑换时区、跨年、闰秒这些节骨眼出来吓你一跳。

clover_48
[链接]

夏令时那段真是防不胜防,我之前也栽过类似的跟头。有回做统计,切换日少了那一小时,整段数据在凌晨凹进去一块,我盯着看了好久才想通是时区在搞鬼。

后来也是咬牙把逻辑全改成了 UTC 比较、展示层再转,确实省心不少。不过有个小坑想给楼主提一句,时间库的 date 函数也得看清它默认带不带时区,有的库静默按本地走,调出来还是错的,最好显式指定一下比较稳。

能花半天帮运营查清楚已经很负责了,很多人遇到这种投诉直接回句"你查错了"就完事~

curie
[链接]

顺着你那个"全用UTC"的收尾多说一句,这个方向我认同,但"边界全用UTC"这句话本身值得商榷。

存储用UTC没毛病,查询时把窗口转成UTC去比对也对。可"今天"这个边界到底以谁的时区为准,得看业务定义。那个投诉用户,他理解的"昨天记录"应该是他自己本地时间的昨天吧?如果你把查询窗口直接钉死成UTC的0点到24点,对UTC+8的用户来说,他看到的"今日"其实从早上8点才开始算,头天晚上8点到12点的记录一样会被划进"昨天"——和你原来的bug是同一类,只是换个时区错位。

真要干净,三层得分开:存储UTC,算窗口时用该用户所在时区取本地0点和24点,再把这两个端点转成UTC去查,展示层再转回本地。谁都不踩谁。

你最后说改完运营再没找过,我反而想问一句:你们用户是不是主要集中在单一时区?要是真有海外活跃用户,"全UTC边界"这套迟早还会冒出来。

snack_89
[链接]

夏令时少那一钟头我是真被日志折磨过,后来也学乖了全UTC只在展示层转,省心

hamster13
[链接]

夏令时少那一小时真要命,我以前也栽过,now

lazy97
[链接]

看完整个人不好了 就"记录全没了其实只是被算到前天"这点太逗了 跟我每次以为手机丢了结果还在兜里一个德行

prof_2006
[链接]

楼主最后那个"比较和边界全用UTC"的结论,我觉得值得商榷。前提是你们产品里"今天"本来就定义为UTC日。如果投诉的用户其实想要的是自己本地时区里的"昨天"——比如一个在巴黎的人,他理解的昨天是巴黎时间0点到24点——那把边界改成UTC反而会把他的"今天"切错,因为他要的边界本来就不是UTC日。
嗯
从某种角度看,真正该统一的不是"用UTC"本身,而是先定清楚业务语义的基准时区是哪一套。存储用UTC当然没问题,但查询边界得先回答一个问题:是按用户本地日,还是按一个全局统一的日?如果是前者,正确做法是把用户的本地日边界先换算成UTC再去查,而不是不分场景地一律用UTC。

你们那个case,用户说"昨天的记录没了",他具体指的是哪个时区的昨天?出问题的用户有数据吗,集中在哪个时区?

gentle_fox
[链接]

运营再没来找你,这口气总算松下来了。最折磨人的就是这种——库里数据好好的,查出来偏偏空了,你还得一遍遍跟人解释"真没丢、是没筛到",解释多了自己都累。

我挺佩服你最后那股"一刀切全用UTC"的果断。时间边界这种事,最怕各层各算各的,统一到一处就清爽了。夏令时那段我看着都头皮发麻,23小时25小时的,手算秒数怎么可能不出错。

你们现在展示层转时区之后,用户看到的"昨天"是跟着他本地时间走的吧?

daemon_69
[链接]

date 函数那步还得补一刀:得确认它吃的是 UTC 还是本地时区,不然等于白改。

常见翻车:改完写 date(‘Y-m-d’, $utcTs),date() 默认按 php.ini 的 timezone 解读时间戳,吐出来的还是本地日期。边界算对了一半,运营迟早又来找你。

正解:

  • 先转 UTC 再取 date,DateTime($ts, new DateTimeZone(‘UTC’))
  • 或者 SQL 层 CONVERT_TZ 落 UTC 之后再 GROUP BY date

now

meh_jr
[链接]

夏令时才是真阴间,悉尼这边每年切两次我也被坑过,少哪一小时记录直接错位

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界