做外贸系统遇到订单日期的问题, sql 不知道该怎么写

2021-07-15 09:33:57 +08:00
 woshipanghu

前提概要: 订单分布在各个国家 有美国、加拿大、日本、欧洲国家,一个国家统一使用一个时区,有一张表是国家对应的时区差。

想实现: 查询同一天的订单

目前我做的: 每个订单统一都保存成 T0 时区的时间戳(t0),而且会对应保存对应国家时间的时间戳( t_country )

举个例子: 美国订单, t0: 1625627408 t_country: 1625602208

查询的时候直接用 t_country 这个字段

遇到的问题: 虽然实现了我想要的功能,但是灵活性比较差,下单的时候就要把对应的订单转成当地的时间保存一个字段

如果时区发生变化 时间就会有错误 特别是美国夏时令和冬时令

如果直接使用 t0 字段 sql 该怎么写呢?还是有其他办法?

2882 次点击
所在节点   SQL Server
13 条回复
moreant
2021-07-15 09:49:35 +08:00
时间戳是 unix 时间戳,没有时区,所有国家的时间戳都是从 1970 年 1 月 1 日开始所经过的秒数。要查同一天的话就将当地时间的日期转成时间戳来查
woshipanghu
2021-07-15 10:04:27 +08:00
@moreant 所以订单是保存了一个 0 时区的时间,查询的时间想要查 当前订单国家时间同一天的订单 每个国家的时差都不一样遇到的是这个问题
woshipanghu
2021-07-15 10:05:18 +08:00
@moreant 想根据 0 时区的时间 结合 时差的表去查询订单
Mithril
2021-07-15 10:16:08 +08:00
这都快成日经贴了,没想到这么多人搞不懂个时间表示法。

举个例子,你在看欧洲杯,前锋起脚射门,球飞到门框的时候信号中断画面卡了。这一瞬间这个球到底在空间哪个位置是有准确值的,这个值就是时间戳。
同时球场上有多个摄像机,每个机位都不一样,这些摄像机都能拍到这个球,但是画面里看起来位置不太一样。不过根据每个摄像机的位置和角度(时区)你总能算出来在其它摄像机里看起来这球在什么地方。
UTC 你可以认为是在球里装了个摄像机,它总是对准了球拍摄的,没有角度差。但它和代表实际位置的时间戳含义是不同的。

搞到这里你应该能明白了。
如果你想要表示某个确定的时间点,那么就用时间戳。
如果你不仅想表示确定的时间点,还想保存生成这次信息的时区,那么就用 DateTimeOffset,或者 ISO8601
如果你并不关心其它机位,那么本地时间就可以了。

所以按照你的需求来说,需要关心多个不同机位的信号时,最好是存时间戳,然后查询的时候根据当地时区转换成时间戳来查。不然你需要转换两次。
CEBBCAT
2021-07-15 10:30:26 +08:00
新建或使用现有的时间转换表,表需要有两列,国家及相较于 GMT 偏移的秒数。

查询的时候,按照 t0+偏移来过滤。最好再加上对 t0 的过滤,因为加法的时候我想是用不上索引的。这样顶多扫三天的表
anzu
2021-07-15 10:40:54 +08:00
时间戳是统一的,没有「 XX 国家的时间戳」 的说法,t_country 是错误的用法
c6h6benzene
2021-07-15 10:43:52 +08:00
你这样除了标准时间之外,最好还有一个 localTime,不然就要精确到城市或者州省邦县之类的级别。

像美国一个国家就有若干个时区,不同州份是否应用夏令时规定都不一致,你光有一个国际字段是没法知道准确区时的。
matrix67
2021-07-15 10:50:06 +08:00
数据库里面只落 utc 读的时候再用程序转换出来

Instant.parse( "2021-07-15T16:15:17.309Z" )
.atZone( ZoneId.of( "Europe/London" ) )
.toString();
ipwx
2021-07-15 11:18:49 +08:00
时间戳就是 1970-01-01 00:00:00 UTC+0 之后开始的秒数。

那是个历史时刻,时间点是确定的,和时区无关。楼主你再想想。
----

存 timestamp 然后找库按照 timezone 格式化出来就行。
bsg1992
2021-07-15 11:34:47 +08:00
时间戳啊 时间戳肯定没有时差的问题。
bnm965321
2021-07-15 11:35:08 +08:00
t_country 直接换成时区吧,有对应的 ISO 标准的,而且应该有专门的库可以应付
gam2046
2021-07-15 12:06:43 +08:00
数据库全部用时间戳,所有的业务系统也用时间戳,只有到前端渲染的时候,时间戳才被转换成本地时间,当前端发起带时间的参数,也一律转换成 UTC+0,进入业务系统。业务系统内不保留时区信息。

需要留意的是,依据数据库不同对于时间的类型不太一致,以我常用的 postgresql 为例,建表时,选择 timestamp without timezone,当查询时需要带时区信息,可以简单的 select ts at time zone 'utc+8' 来显示本地时间,但不建议在数据库查询出来的时候就带时区,最好业务系统内,都不带时区
mingl0280
2021-07-15 13:47:51 +08:00
数据库里面用时间戳,UTC 那个,记录下订单的时区在显示的时候转换一下就行了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/789614

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX