这个 js bug 应该大家都碰到过吧? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
millx

这个 js bug 应该大家都碰到过吧?

  •  
  •   millx Jun 15, 2018 8011 views
    This topic created in 2883 days ago, the information mentioned may be changed or developed.

    开发 bufpay.com 个人收款接口 的时候,前端需要计算账号过期时间。直接用了:

    var t = new Date('2018-06-15 00:00:00'); 

    这样来初始化,在 Chrome 里面是没问题的,但是 Safari 里面就不行了,发现 Safari 支持 :

    var t = new Date('2018-06-15'); 

    和这样

    var t = new Date('2018-06-15T00:00:00'); 

    Chrome 里面是上面三种格式初始化都支持的。

    这个 bug (应该也不能算 Safari 的 bug )应该是 Chrome 做了兼容,Safari 是符合 ECMAScript IOS 8601 关于时间的格式定义的。

    51 replies    2018-06-16 15:59:09 +08:00
    wenzhoou
        1
    wenzhoou  
       Jun 15, 2018 via Android
    改用 moment.js 怎么样
    hanpei
        2
    hanpei  
       Jun 15, 2018
    t = new Date('2018/06/15 00:00:00')
    safari 这样可以
    以前也遇到过
    替换-为 /
    millx
        3
    millx  
    OP
       Jun 15, 2018
    @wenzhoou 需求比较简单,注意到这个问题手动处理一下就好啦,不太喜欢引入太多 lib
    cccRaim
        4
    cccRaim  
       Jun 15, 2018
    我好像是 split(' ')分成日期和时间,然后再对日期 split('-')区分出年月日
    millx
        5
    millx  
    OP
       Jun 15, 2018
    @hanpei 嗯,这样也可以,或者是把空格替换为 T
    opengps
        6
    opengps  
       Jun 15, 2018
    遇到过-有问题,但是没深入研究,于是一直后台返回 2018/06/15 00:00:00 格式给前台 new Date('')。
    目前没发现问题
    Mutoo
        7
    Mutoo  
       Jun 15, 2018
    这种必须前端后统一使用 IOS 8601,或者使用 UTC Timestamp 整数,不然遇到不同时区的时候,就蛋疼了。
    IOS 8601 的 T 部分是负责时区
    millx
        8
    millx  
    OP
       Jun 15, 2018
    @opengps 后台 PHP 么? Python 里面 str(datetime.now()) 直接就是 '2018-06-15 11:23:06.674947' 这种格式
    grewer
        9
    grewer  
       Jun 15, 2018   1
    以前碰到过,反正只要以'/'作为分割,那就没什么问题了
    Mutoo
        10
    Mutoo  
       Jun 15, 2018   1
    @Mutoo 更正一下,Z 部分负责时区(可选)
    zjsxwc
        11
    zjsxwc  
       Jun 15, 2018
    moment.js +1
    millx
        12
    millx  
    OP
       Jun 15, 2018
    @Mutoo timestamp 可读性不太好 /(ㄒoㄒ)/~~
    agagega
        13
    agagega  
       Jun 15, 2018
    同样的坑也出现在 iOS 平台的微信小程序里
    millx
        14
    millx  
    OP
       Jun 15, 2018
    @agagega 就是不同 js 编译器有差异,容易被忽略
    jin5354
        15
    jin5354  
       Jun 15, 2018   1
    原生 Date 兼容性问题多了,非 IOS 8601 标准格式,有的端直接报错,移动端某些版本还会出现 8 小时误差(不标 Z 的话有的按东八区算,有的按零时区算),如果跨端多非标准格式还是建议用个库
    zhouyg
        16
    zhouyg  
    &bsp;  Jun 15, 2018
    建议覆盖掉原生 Date 类型,改为自己实现或模块
    zenxds
        17
    zenxds  
       Jun 15, 2018   2
    new Date(时间戳)
    new Date('2014/07/12 12:34:35')
    new Date(year, month, day[, hour[, minute[, second[, millisecond]]]])

    其他的都有兼容问题
    millx
        18
    millx  
    OP
       Jun 15, 2018
    @zenxds 统一用这几种就够了
    Cbdy
        19
    Cbdy  
       Jun 15, 2018 via Android
    不要用时间戳数字,不要用奇奇怪怪的格式,数据传输统一用字符串,用 ISO8601 格式!
    kslr
        20
    kslr  
       Jun 15, 2018
    用时间戳处理只有展示格式化可以避免很多奇怪的问题
    millx
        21
    millx  
    OP
       Jun 15, 2018
    @Cbdy 时间戳除了可读性不好,其他应该还是没问题的
    Cbdy
        22
    Cbdy  
       Jun 15, 2018 via Android
    @millx 可读性是最严重的问题了,然后他是数字,“类型对不上”,还有诸如 2038 问题
    millx
        23
    millx  
    OP
       Jun 15, 2018
    @Cbdy 也是,养成统一格式习惯可以省好多事儿
    doubleflower
        24
    doubleflower  
       Jun 15, 2018
    没碰到过,从来不用这种感觉不牢靠的方式
    millx
        25
    millx  
    OP
       Jun 15, 2018
    @doubleflower 你用哪种?
    royzxq
        26
    royzxq  
       Jun 15, 2018   1
    ```js
    function parseDate(date) {
    if (!date) return new Date()
    if (date instanceof Date) return date
    if (!/[^\d]+/g.test(date)) {
    date = date.toString().concat('000').substr(0, 13) * 1

    return new Date(date)
    }

    return new Date(date.toString().replace(/-/g, '/').replace(/T|(?:\.\d+)?Z/g, ' '))
    }
    ```
    millx
        27
    millx  
    OP
       Jun 15, 2018
    @royzxq 不错
    doubleflower
        28
    doubleflower  
       Jun 15, 2018
    @millx 我没用过中间有空格的,感觉不符标准
    zenio
        29
    zenio  
       Jun 15, 2018 via Android   1
    把 - 换成 / 就可以了
    learnshare
        30
    learnshare  
       Jun 15, 2018
    这不叫 Bug,是 Chrome 容错更强而已

    2018-06-15 00:00:00 这不是标准格式
    参考 https://zh.wikipedia.org/wiki/ISO_8601
    weixiangzhe
        31
    weixiangzhe  
       Jun 15, 2018   1
    不是 bug 这个是兼容问题,推荐 dayjs 吧,api 兼容 momentjs,大小只有 2kb,https://github.com/iamkun/dayjs
    millx
        32
    millx  
    OP
       Jun 15, 2018
    @learnshare 是的
    millx
        33
    millx  
    OP
       Jun 15, 2018
    @weixiangzhe 这个赞,可以 locale 收藏了
    wwt2017
        34
    wwt2017  
       Jun 15, 2018
    Safari 用 - 转化为毫秒时也会出问题
    auroraccc
        35
    auroraccc  
       Jun 15, 2018
    平常用个 dayjs 就行了 , momentjs 好大
    zpf124
        36
    zpf124  
       Jun 15, 2018
    ie 也有这个问题

    '2018-06-15' 正确
    '2018/06/15 00:00:00' 正确

    '2018-06-15 00:00:00' 报错。
    millx
        37
    millx  
    OP
       Jun 15, 2018
    @auroraccc @royzxq 他的这个 parseDate 也不错
    millx
        38
    millx  
    OP
       Jun 15, 2018
    @zpf124 应该都是老老实实按标准来实现的 哈哈哈
    mooo
        39
    mooo  
       Jun 15, 2018
    第一种不规范啊, 规范只支持 RFC2822 和 ISO 8601 标准的
    metrxqin
        40
    metrxqin  
       Jun 15, 2018
    **前端需要计算账号过期时间**

    你确定这种设计足够安全?
    millx
        41
    millx  
    OP
       Jun 15, 2018
    @metrxqin 前端后端都需要啊,为什么不安全?
    millx
        42
    millx  
    OP
       Jun 15, 2018
    @metrxqin 前端只是用来计算显示的啦,后端肯定需要自己重新计算的,不要太紧张
    Cynic222
        43
    Cynic222  
       Jun 15, 2018 via iPhone
    @wenzhoou #1 moment 太大,现在有个 dayjs,一样的 api
    ernest
        44
    ernest  
       Jun 15, 2018
    ISO 8601 date string 格式了解下:2018-06-15T00:00:00 是 js Core 支持的。https://en.wikipedia.org/wiki/ISO_8601
    Building
        45
    Building  
       Jun 15, 2018 via iPhone   1
    js 没有 bug,如果有的话,那是 feature。
    iamkun
        46
    iamkun  
       Jun 15, 2018   1
    @millx 其实这几个时间字符串都不是标准时间,所以呢不同浏览器的支持情况是不一样的。 推荐前后统一用 ISO 时间或者时间戳,省心省力

    当然,欢迎体验 dayjs , 2kb 类似 moment.js 的时间库,欢迎提出各种改进意见。
    feder
        47
    feder  
       Jun 15, 2018
    LS dayjs 作者
    wenzhoou
        48
    wenzhoou  
       Jun 15, 2018 via Android
    恩。那我下次项目也用 dayjs
    millx
        49
    millx  
    OP
       Jun 15, 2018
    @iamkun (*@ο@*) 哇~ dayjs 作者
    scplay
        50
    scplay  
       Jun 16, 2018
    第一次用 dayjs 发现 dayjs 没有解决 iso8601 在 safari 上的问题,果断换回 moment,
    iamkun
        51
    iamkun  
       Jun 16, 2018
    @scplay 请问在 safari 上是什么问题呢
    About     Help     Advertise     Blog     API     FAQ     Solana     939 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 111ms UTC 20:25 PVG 04:25 LAX 13:25 JFK 16:25
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86