日期区间的终点是用第二天的 00:00:00 还是当天的 23:59:59 比较好?
source link: https://www.v2ex.com/t/1006014
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
跟后端对接口,发现关于日期区间的定义有点模糊.
比如查询昨天的数据,我们一般是传起始时间点. 对接后端 A 的参数是:
{
startTime:2024-01-04 00:00:00,
endTime:2024-01-04 23:59:59
}
对接后端 B 的参数是:
{
startTime:2024-01-04 00:00:00,
endTime:2024-01-05 00:00:00
}
后端 A 说他用的是小于等于,后端 B 说他用的是小于,前端的时间工具类还得写两个方法...
想统一,但感觉两种方式都有自己的道理. 个人是倾向于 00:00:00 这种,可能是来源于数组截取时顾头不顾尾的概念. 另一位后端大佬则觉得 23:59:59 更便于理解.
不知道大家都是用哪种呢?
luomao 3 小时 10 分钟前 3 用 23:59:59 ,00:00:00 已经是第二天了
|
justlazydog 3 小时 9 分钟前 都可以,统一就行,常识上一般是 23:59:59 。
|
corcre 3 小时 5 分钟前 2 用 23:59:59, 因为永远不知道谁没事传个日期/加个字段只记日期, 用 datetime 类型还把时间给截了...
|
coderzhangsan 3 小时 1 分钟前 让后端统一口径,前端没有必要兼容 2 种方案。
|
tusj 3 小时 1 分钟前 2 前闭后开区间,用 00:00:00
|
belin520 3 小时 0 分钟前 moment 等时间库的 endOfDay 是 23:59:59
|
lscho 2 小时 59 分钟前 肯定是 23:59:59 ,0 点已经是第二天了
|
douxc 2 小时 58 分钟前 不懂就问:如果记录到了毫秒级,23:59:59 会少 1 秒的数据吗?
|
Curtion 2 小时 58 分钟前 2 A 更好, 左闭右开并不是一个常识, 大众常识应该左闭右闭, 选 00:00:00 会误以为包括第二天开始, 我们系统很多客户已经反馈过了
|
maocat 2 小时 58 分钟前 via iPhone 4 左开右闭原则 00.00.00 ,如果用 23.59.59 后面还有毫秒呢
|
gdfsjunjun 2 小时 54 分钟前 当然是 23:59:59 容易理解,0 点的话会被认为第二天也算
|
chronos 2 小时 54 分钟前 除非你数据库里面存的时间精度只到秒,否则还是用 00:00:00 的好。
|
lqhunter233 2 小时 52 分钟前 @douxc 2024-01-04 23:59:59.999(yyyy-MM-dd HH:mm:ss.SSS)精确到秒可以这样
|
leonshaw 2 小时 51 分钟前 via Android |
lqhunter233 2 小时 51 分钟前 打错了,毫秒
|
caiqichang 2 小时 49 分钟前 1 前端只穿日期
{ startTime:2024-01-04, endTime:2024-01-04 } 后端想怎么处理自己在 get 里面处理 |
zliea 2 小时 48 分钟前 左闭右开 +1
|
yinmin 2 小时 48 分钟前 via iPhone 如果某条记录的时间是 23:59:59.20 呢?
应该用 00:00:00 ,运算逻辑是:>=startTime and <endTime (即使数据库字段的时间秒不含小数,也不应该用 23:59:59 ,避免给自己留坑。谁也不知道几年之后,某个程序员写库的时候引入了秒的小数) |
darkengine 2 小时 48 分钟前 如果只是日期区间,我的建议是只传日期,不传时间。以后如果有改动,直接改后端的逻辑就行,前端都不用再发版。
|
likunyan 2 小时 42 分钟前 用 23:59:59 ,00:00:00 已经是第二天了
|
Kin9 2 小时 39 分钟前 24:00:00
|
milukun 2 小时 37 分钟前 那你可以制造一条 23:59:59.xx 的数据,然后暴露出这个 bug
他们后端就统一了 |
xuanbg 2 小时 37 分钟前 我在后端都是:start <= x < end 。所以,按日期的话,end 是前端传的日期/时间的下一天的 0 点
|
debuggerx 2 小时 33 分钟前 我的习惯是,如果是日期范围的参数,比如 1 月 1 号-1 月 3 号,那么前端就传 1 月 1 号和 1 月 3 号这两天任意的时间即可(比如 2024-01-01 08:12:35 和 2024-01-03 18:22:02 就满足,),后端只取日期部分。这样的好处是不会把歧义泄露到前端代码,并且前端使用 api 非常方便,比如前端想要近 5 天的数据,只要写:
const now = new Date(); const endTime = now.toISOString(); now.setDate(now.getDate() - 5); const startTime = now.toISOString(); apis.someApi(startTime, endTime); |
crz 2 小时 30 分钟前 toDate(timestamp) == date
|
libook 2 小时 29 分钟前 小于等于这个逻辑就是错的,因为并没有完全覆盖时间段,除非业务能接受没覆盖的那一部分被排除在外。
|
qzh993 2 小时 25 分钟前 很多兄弟都说了,左开右闭原则,前端只传日期,比如要查询 2024-01-04 这天的数据,后端这么处理,2024-01-04 00:00:00 <= create_time < 2024-01-05 00:00:00
|
nomytwins 2 小时 25 分钟前 正常都是当天的 23:59:59
|
RainCats 2 小时 22 分钟前 我倾向于后端 B 的做法,我也这样做
|
imldy 2 小时 20 分钟前 via Android 后端用左闭右开的 0.0.0 ,但给用户显示的业务规则是用 59.59.59
|
adoal 2 小时 12 分钟前 如果做比较的时候能保证传入的时间先 truncate 到确定的精度,可以用两端都闭合。否则只能左闭右开才能保证正确性。
|
douxc 2 小时 12 分钟前 @lqhunter233 #13 这其实可以无限拆下去,如果我想完整包含一天的数据,应该用其他老哥提到的 < endTime ,也就是第二天的 00:00:00
|
JimMoen 2 小时 11 分钟前 ```
{ startTime: "2024-01-04 00:00:00", endTimeBefore: "2024-01-05 00:00:00" } ``` |
Bromine0x23 2 小时 11 分钟前 前端来说右闭应该比较符合直觉;后端处理考虑到精度可能变化,用右开的应该比较好
|
zackzergzeng 2 小时 9 分钟前 得让后端对齐了,前端不能因为后台的不统一写两套代码啊
|
Belmode 2 小时 9 分钟前 23:59:59 包含 23:59:59.99.....9,前端没必要做特殊处理,左右都是闭区间
|
Huelse 2 小时 9 分钟前 传给后端查询一般用 00 这种,59 那种还要后端再处理下才能全覆盖
|
adoal 2 小时 5 分钟前 另外,除了小数部分之外,23:59:59 还有个问题是表示不了闰秒。
当然,实际应用中,如果业务不是全天候的,或者在那特定一两秒的业务量本来就少,也能承受少量错误的代价,就无所谓了。 |
dif 2 小时 0 分钟前 [2024:01:01 00:00:00, 2024:01:01 23:59:59]
|
abc0123xyz 2 小时 0 分钟前 用 000000 省事
|
tyrone2333 1 小时 47 分钟前 :default-time="['00:00:00', '23:59:59']"
|
ysc3839 1 小时 37 分钟前 via Android 一分钟 60 秒,取值范围是 0-59
|
54xavier 1 小时 34 分钟前 对啊,我想说你要算截止和开始,其实应该用
00:00:00.000 23:59:59.999 这样更佳 |
nextvay 1 小时 30 分钟前 开发了 8 年了,都是 start_time<= time < end_time ,我选 B
原因: 1 、万一数据库毫秒时间戳呢? 2 、开发、处理简单 |
JingXiao 1 小时 25 分钟前 日期区间不是只传日期就完事了么,如果非要加时分秒这种也是时间组件加上时分秒可选让用户选
|
snylonue 1 小时 18 分钟前 23:59:59
好几次因为 00:00:00 没赶上 ddl ( |
vagusss 1 小时 18 分钟前 左闭右开就完事儿了, 到 59 秒是什么鬼
|
Seulgi 1 小时 14 分钟前 我的建议是时间戳一把梭
|
focuxin 1 小时 11 分钟前 /**
* The maximum supported {@code LocalTime}, '23:59:59.999999999'. * This is the time just before midnight at the end of the day. */ public static final LocalTime MAX; |
wangtian2020 1 小时 6 分钟前 dayjs().endOf('d') 调用出来是啥就是啥,我不管
|
brader 1 小时 6 分钟前 单说程序、技术,看完大家说的,其实都有道理,讨论不出一个明确的对错的。我们不妨把视野再放大一点,从页面使用人员的惯性思维去反推理解:
比如使用人员查询 1 月份报表,正常应该是点开始 1 月 1 日,结束 1 月 31 日。使用人员潜意识里,其实会认为他点了 1 月 31 日,就应该包含 31 日的数据的,而不是让他去点 2 月 1 日。 所以引导出:就给 1 月 31 日最后一刻的时间戳没问题的。 |
label 1 小时 3 分钟前 前端正常只需要到日, 或者时分, 怎么说也不用精确到秒, 这应该由后端来做
|
yhnbgfd 48 分钟前 首先 23:59:59 是<错误>的时间区间判断条件, 我们需要先排除错误答案, 修复程序潜在 bug, 而不是给错误找理由.
|
liubaicai 48 分钟前 0:0:0 的时间戳-1 就行了
|
adoal 47 分钟前 @brader 也就是说,其实 Calendar 相关的东西是跟 time 不同逻辑的数据类型,它不是物理意义上的时间长度和时刻坐标,而是人为的、人文的编号。如果要处理日历上的日期,复杂度远比“存储用 UTC timestamp ,给人看的交给前端去做转换”复杂得多。以前在一个教务系统招生模块里就是因为大意用普通的时间类型保存生日而碰到了中国实行夏时制的年份里出生在夏时制边缘日子里的学生因为算出来的“年龄”不对而无法报名的问题。
|
lambdaq 47 分钟前 23:59:59.999 秒的时候客户下了一个订单呢?
|
mytharcher 46 分钟前 1 所有这些问题都是对日期和时间描述精度的问题。以下举例:
1. 用户要查 2023 年的数据,此时精度是“年”,那么界面上只需要选年,但后端要执行的查询应该是 >= 2023-01-01 00:00:00 && < 2024-01-01 00:00:00 。 2. 用户要查 2023 年 11 月的数据,此时精度是“月”,界面上需要选年-月,但后端要执行的查询应该是 >= 2023-11-01 00:00:00 && < 2023-12-01 00:00:00 。 3. 用户要查 2023 年 11 月 5 日的数据,此时精度是“日”,界面上只需要选年-月-日,但后端要执行的查询应该是是 >= 2023-11-05 00:00:00 && < 2023-11-06 00:00:00 。 4. ... 时、分、秒、毫秒、微秒等精度类似,不再继续举例。 以上举例我们可以得到的结论是,要查什么精度,那么后端需要执行的区间范围就是其精度所在时间的起始(闭区间)到其精度 +1 单位后的时间结束(开区间)。所以传开闭区间的条件比较合理。如果 HTTP 接口上不支持开闭条件的描述(>= 和 <),那么就只能后端拿到查询参数串后根据提供的精度解析,比如传了 2023 ,就认为精度是年,传了 2023-11-05 则认为精度是日,传 2023-11-05 12:41:32 则认为是秒,均按此精度统一规则处理,查询就不会有问题了。 尤其避免一些传 23:59:59 却不包含最后一秒内数据的误解。 所以区别两者,最核心的是你的 HTTP 接口上是否能表达“>=”/“<”这些非相等的运算符,如果可以,那么前端可以按精确时间传闭开区间的表达。如果不行,那么只能按精度字符串传,由后端根据精度信息进行理解。 |
quandou 39 分钟前 00:00:00 已经是 after day 了 23:59:59 合理
|
Philippa 24 分钟前 via iPhone 前后端判断用左闭右开,因为还有 1s 的间隙。显示用 23:59:59
|
Bingchunmoli 19 分钟前 via Android @douxc 会的..,不要问我是怎么知道的
|
kevin1452 17 分钟前 通常是左闭右开
|
Bingchunmoli 15 分钟前 via Android @brader 但是最后一刻时间戳你是精确到秒还是毫秒还是微秒,,实际上不如处理一下左闭又开,不然线上确实会丢这一段数据
|
lovelylain 14 分钟前 via Android 达成共识都可以,待讨论的话建议双闭区间,因为这个有效期可能涉及展示,开区间展示时需要减 1 秒处理
|
fionasit007 11 分钟前 00:00:00 算是第二天了,以后会是个大坑,比如抖音的巨量后台你用 00:00:00 会查出第二天这个点的数据,因为数据量太大 00:00:00 也会产生数据的
|
fionasit007 9 分钟前 @Seulgi 这个时候有问题又回到原地了 那到底是 59 的时间戳还是 00 的时间戳呢
|
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK