gpt4 book ai didi

javascript - moment.js 模拟 local() 所以单元测试运行一致

转载 作者:行者123 更新时间:2023-12-01 15:34:28 25 4
gpt4 key购买 nike

我想测试以下代码。我想知道是否有办法模拟 moment.js或强制它认为我当前的位置是America/New_York这样我的单元测试不会在可能位于不同地理位置的 gitlab.ci 运行器中失败?

  const centralTimeStartOfDay = moment.tz('America/Chicago').startOf('day');
const startHour = centralTimeStartOfDay
.hour(7)
.local()
.hour();

基本上我想将我的时区硬编码为 America/New_York并希望此函数的行为一致。
编辑 :
我试过了:
  • Date.now = () => new Date("2020-06-21T12:21:27-04:00")
  • moment.tz.setDefault('America/New_York')

  • 而且,我得到了同样的结果。我想模拟当前时间所以 startHour返回一致的值。

    最佳答案

    问题
    所以这个问题没有一个单一的答案。这个问题是 javascript 的一个基本问题,您可以通过以下两种方式之一查看日期:

  • UTC(getUTCHours()getUTCMinutes() 等)
  • 本地(即系统、getHours()getMinutes() 等)

  • 没有指定的方法来设置有效的系统时区 ,甚至是 UTC 偏移量。
    (扫描 mdn Date reference 或查看 the spec 以了解这一切是多么无益。)
    “可是等等!”我们哭了,“这不就是 moment-timezone存在的原因吗??”
    不完全是。 momentmoment-timezone更好/更轻松地控制 javascript 中的时间管理,但即使他们也无法知道本地时区 Date正在使用,并使用其他机制来学习。这是一个如下问题。
    一旦你了解了代码,你就会看到 .local()瞬间的方法( prototype declarationsetOffsetToLocal 的实现)有效地执行以下操作:
  • 将时刻的 UTC 偏移设置为 0
  • 通过设置 _isUTC 禁用“UTC 模式”为假。

  • 禁用“UTC 模式”的效果是意味着大多数访问器方法被转发到底层 Date目的。例如。 .hours() 最终调用 moment/get-set.js get() 看起来像这样:
    export function get(mom, unit) {
    return mom.isValid()
    ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
    : NaN;
    }
    _dDate时刻 ( mom ) 正在包装的对象。对于非 UTC 模式时刻如此有效, moment.hours()是到 Date.prototype.getHours() 的直通.用 moment.tz.setDefault() 设置什么都没关系,或者如果您已覆盖 Date.now() .这些东西都没有使用。
    另一件事...
    你说:

    Basically I want to hard code my time to be America/New_York and want this function behaves consistently


    但实际上,这通常是不可能的。您正在使用芝加哥,我想它与纽约同步偏移,但是例如英国在与美国不同的时间转移,因此如果您从美国时区转换为英国时区,一年中有几周您的测试会失败。
    解决方案。
    但这仍然令人沮丧,因为我不希望我在波兰和美国西海岸的开发人员因为我的 CI 服务器在 UTC 中运行而进行破坏性本地测试。那么我们能做些什么呢?
    第一个解决方案不是解决方案:找到一种不同的方式来做你正在做的事情!通常使用 .local() 的用例非常有限,并且将向用户显示其当前偏移量中的时间。这甚至不是他们的时区,因为本地的 Date方法只会查看当前偏移量。所以大多数时候你只想在当前时间使用它,或者如果你不介意它是否对 Date 的一半有误。您使用它的对象(对于使用夏令时的时区)。最好通过其他方式了解用户想要的时区,而不是使用 .local()。一点也不。
    第二个解决方案也是一个非解决方案:不要太担心你的测试!显示本地时间的主要事情是它可以工作,你并不关心它到底是什么。手动验证它是否显示正确的时间,并在您的测试中验证它是否返回一个看起来合理的东西,而不检查具体时间。
    如果您仍然想继续,最后一个解决方案至少可以使您的案例和其他一些解决方案有效,并且如果您发现需要扩展它,您需要做什么是显而易见的。然而,这是一个复杂的领域,我不保证这不会产生一些意想不到的副作用!
    在您的测试设置文件中:
    [
    'Date',
    'Day',
    'FullYear',
    'Hours',
    'Minutes',
    'Month',
    'Seconds',
    ].forEach(
    (prop) => {
    Date.prototype[`get${prop}`] = function () {
    return new Date(
    this.getTime()
    + moment(this.getTime()).utcOffset() * 60000
    )[`getUTC${prop}`]();
    };
    }
    );
    您现在应该可以使用 moment.tz.setDefault()并使用 .local()应该允许您访问日期时间的属性,就好像它认为本地时区与 moment-timezone 中配置的一样.

    I thought about trying to patch moment instead, but it is a much more complicated beast than Date, and patching Date should be robust since it is the primitive.

    关于javascript - moment.js 模拟 local() 所以单元测试运行一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62476903/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com