V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
woshipanghu
V2EX  ›  SQL Server

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

  •  
  •   woshipanghu · 140 天前 · 1205 次点击
    这是一个创建于 140 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

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

    第 1 条附言  ·  140 天前
    不同时区的订单我统一用 0 时区来表示 并且转成时间戳
    然后保存对应国家时间的日期也转成了时间戳
    怎么上来就教人什么是 utc 什么是时间戳
    感谢下面认真不装逼的那些回复
    结贴!自己研究去了
    13 条回复    2021-07-15 13:47:51 +08:00
    moreant
        1
    moreant  
       140 天前
    时间戳是 unix 时间戳,没有时区,所有国家的时间戳都是从 1970 年 1 月 1 日开始所经过的秒数。要查同一天的话就将当地时间的日期转成时间戳来查
    woshipanghu
        2
    woshipanghu  
    OP
       140 天前
    @moreant 所以订单是保存了一个 0 时区的时间,查询的时间想要查 当前订单国家时间同一天的订单 每个国家的时差都不一样遇到的是这个问题
    woshipanghu
        3
    woshipanghu  
    OP
       140 天前
    @moreant 想根据 0 时区的时间 结合 时差的表去查询订单
    Mithril
        4
    Mithril  
       140 天前   ❤️ 1
    这都快成日经贴了,没想到这么多人搞不懂个时间表示法。

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

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

    所以按照你的需求来说,需要关心多个不同机位的信号时,最好是存时间戳,然后查询的时候根据当地时区转换成时间戳来查。不然你需要转换两次。
    CEBBCAT
        5
    CEBBCAT  
       140 天前 via Android
    新建或使用现有的时间转换表,表需要有两列,国家及相较于 GMT 偏移的秒数。

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

    像美国一个国家就有若干个时区,不同州份是否应用夏令时规定都不一致,你光有一个国际字段是没法知道准确区时的。
    matrix67
        8
    matrix67  
       140 天前   ❤️ 1
    数据库里面只落 utc 读的时候再用程序转换出来

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

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

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

    需要留意的是,依据数据库不同对于时间的类型不太一致,以我常用的 postgresql 为例,建表时,选择 timestamp without timezone,当查询时需要带时区信息,可以简单的 select ts at time zone 'utc+8' 来显示本地时间,但不建议在数据库查询出来的时候就带时区,最好业务系统内,都不带时区
    mingl0280
        13
    mingl0280  
       140 天前 via Android   ❤️ 1
    数据库里面用时间戳,UTC 那个,记录下订单的时区在显示的时候转换一下就行了。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1122 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:23 · PVG 05:23 · LAX 13:23 · JFK 16:23
    ♥ Do have faith in what you're doing.