我有一个函数,该函数返回由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
感谢一些智慧。
答案 0 :(得分:1)
Travis CI系统在哪个时区运行?我的时区无法识别DST,并且得到的结果与Travis CI相同。由于您越过时区边界(至少在美国目前是4月,而您要倒退到2月),因此行为会因时区是否识别DST而有所不同。
答案 1 :(得分:1)
通过测试当输入为“ now”时毫秒时间戳的差异,您假设所有单位始终具有相同的关联毫秒数。这是不正确的。
由于您在当地时间工作,因此您会受到当地时区的影响。我假设您的一个环境在您要测试的范围内具有时区转换,而另一个环境没有。
您应用间隔的方法还有其他一些问题。考虑输入日期是否为2019-01-31且间隔为+1M1d
。您可能希望将其设置为2019-03-01,但是由于应用每个步骤时都会发生溢出,因此代码将给出2019-03-04。正确执行此操作的代码很复杂,通常委托给Moment,Luxon和Date-fns之类的库。