这个 js bug 应该大家都碰到过吧? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
millx
V2EX    程序员

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

  •  
  •   millx 2018-06-15 11:06:13 +08:00 7619 次点击
    这是一个创建于 2682 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    其他的都有兼容问题
    millx
        18
    millx  
    OP
       2018-06-15 11:52:36 +08:00
    @zenxds 统一用这几种就够了
    Cbdy
        19
    Cbdy  
       2018-06-15 11:55:43 +08:00 via Android
    不要用时间戳数字,不要用奇奇怪怪的格式,数据传输统一用字符串,用 ISO8601 格式!
    kslr
        20
    kslr  
       2018-06-15 11:57:35 +08:00
    用时间戳处理只有展示格式化可以避免很多奇怪的问题
    millx
        21
    millx  
    OP
       2018-06-15 11:59:57 +08:00
    @Cbdy 时间戳除了可读性不好,其他应该还是没问题的
    Cbdy
        22
    Cbdy  
       2018-06-15 12:06:48 +08:00 via Android
    @millx 可读性是最严重的问题了,然后他是数字,“类型对不上”,还有诸如 2038 问题
    millx
        23
    millx  
    OP
       2018-06-15 12:10:02 +08:00
    @Cbdy 也是,养成统一格式习惯可以省好多事儿
    doubleflower
        24
    doubleflower  
       2018-06-15 12:32:12 +08:00
    没碰到过,从来不用这种感觉不牢靠的方式
    millx
        25
    millx  
    OP
       2018-06-15 12:34:56 +08:00
    @doubleflower 你用哪种?
    royzxq
        26
    royzxq  
       2018-06-15 12:34:58 +08:00   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
       2018-06-15 12:38:10 +08:00
    @royzxq 不错
    doubleflower
        28
    doubleflower  
       2018-06-15 12:40:55 +08:00
    @millx 我没用过中间有空格的,感觉不符标准
    kefengong
        29
    kefengong  
       2018-06-15 12:59:02 +08:00 via Android   1
    把 - 换成 / 就可以了
    learnshare
        30
    learnshare  
       2018-06-15 13:06:12 +08:00
    这不叫 Bug,是 Chrome 容错更强而已

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

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

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

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

    当然,欢迎体验 dayjs , 2kb 类似 moment.js 的时间库,欢迎提出各种改进意见。
    feder
        47
    feder  
       2018-06-15 17:31:47 +08:00
    LS dayjs 作者
    wenzhoou
        48
    wenzhoou  
       2018-06-15 18:22:16 +08:00 via Android
    恩。那我下次项目也用 dayjs
    millx
        49
    millx  
    OP
       2018-06-15 20:07:13 +08:00
    @iamkun (*@ο@*) 哇~ dayjs 作者
    scplay
        50
    scplay  
       2018-06-16 09:38:03 +08:00
    第一次用 dayjs 发现 dayjs 没有解决 iso8601 在 safari 上的问题,果断换回 moment,
    iamkun
        51
    iamkun  
       2018-06-16 15:59:09 +08:00
    @scplay 请问在 safari 上是什么问题呢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2539 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 10:33 PVG 18:33 LAX 03:33 JFK 06:33
    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