为什么在Travis CI测试中我的日期克隆会关闭1小时

时间:2019-04-17 16:28:16

标签: javascript typescript datetime

我有一个函数,该函数返回由delta修改的Date对象,如下所示:

    export function getDate(delta: string = "", start?: Date): Date {
        const date = start ? new Date(start.getTime()) : new Date();
        const rel = delta.split(" ").join("");
        const [, sign, years, months, days, hours, mins, secs] = toArray(/([+-])?(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/.exec(rel) as ArrayLike<string>);
        const plus = sign !== "-"; 
        if (years) date.setFullYear(date.getFullYear() + (plus ? +years : -years));
        if (months) date.setMonth(date.getMonth() + (plus ? +months : -months));
        if (days) date.setDate(date.getDate() + (plus ? +days : -days));
        if (hours) date.setHours(date.getHours() + (plus ? +hours: -hours));
        if (mins) date.setMinutes(date.getMinutes() + (plus ? +mins: -mins));
        if (secs) date.setSeconds(date.getSeconds() + (plus ? +secs : -secs));
        return date;
    }

它似乎在node和chrome上都可以正常工作,并且我的测试在本地通过。但是当我推送到npm时,测试在Travis CI中失败,如下所示: Travis CI

让我遗憾的是,为什么第一次测试通过而第二次测试恰好在1小时内失败。我缺少一些CET / UCT魔术吗?我是否错过了Date对象在各种节点版本中如何工作的一些特殊之处?

您可以在travis中看到测试代码(上面的链接),但是我也会在这里添加它:

    const now = new Date();
    let pos = Util.getDate("+1Y2M3d4h5m6s", now);
    expect(now.getTime() - pos.getTime()).toBe(-37166706000); // passes locally and in travis
    let neg = Util.getDate("-1Y2M3d4h5m6s", now);
    expect(now.getTime() - neg.getTime()).toBe(36903906000); // passes locally but fails in travis

感谢一些智慧。

2 个答案:

答案 0 :(得分:1)

Travis CI系统在哪个时区运行?我的时区无法识别DST,并且得到的结果与Travis CI相同。由于您越过时区边界(至少在美国目前是4月,而您要倒退到2月),因此行为会因时区是否识别DST而有所不同。

答案 1 :(得分:1)

通过测试当输入为“ now”时毫秒时间戳的差异,您假设所有单位始终具有相同的关联毫秒数。这是不正确的。

  • 并非每年都有相同的天数。普通年有365年。Le年有366年。
  • 并非每个月都有相同的天数。它们的范围从28到31。
  • 并非每个本地日都有24小时。时区偏移转换(例如,由于夏令时或标准时间的变化而引起的)可能导致给定的本地日长为23、23.5、24、24.5或25小时。

由于您在当地时间工作,因此您会受到当地时区的影响。我假设您的一个环境在您要测试的范围内具有时区转换,而另一个环境没有。

您应用间隔的方法还有其他一些问题。考虑输入日期是否为2019-01-31且间隔为+1M1d。您可能希望将其设置为2019-03-01,但是由于应用每个步骤时都会发生溢出,因此代码将给出2019-03-04。正确执行此操作的代码很复杂,通常委托给MomentLuxonDate-fns之类的库。