Setting a timezone in vitest
Asked Answered
P

3

8

I would like to set (actually mock) a timezone in my Vitest tests to get deterministic results in all time zones they will run in. I run my tests on a local machine and also in CI/CD environments that have different timezones.

I've searched for some answers on Stackoverflow but haven't found a good cleare way to do it in vitest.

Prosecutor answered 16/8, 2023 at 8:43 Comment(0)
A
17

Create a file vitest.global-setup.ts

export const setup = () => {
  process.env.TZ = 'UTC'
}

Then add it to globalSetup in vitest.config.ts

export default defineConfig({
  test: {
    globalSetup: './vitest.global-setup.ts',
    // ...
  },

(Solution found in this GitHub comment)

Arjuna answered 24/8, 2023 at 16:12 Comment(1)
Tried it. Didn't work on windows. works on the debian dockerProsecutor
J
1

You can't "mock" the timezone directly. The closest you can get is to set the TZ environment variable when you run vitest.

For example: TZ=UTC vitest

I save this in my package.json as a script and then execute that script like this:

{
  scripts: {
    test: "TZ=UTC vitest"
  }
}

And just run yarn test so I don't have to think about it. This gives me deterministic timezones. This plus a vi.setSystemTime should hopefully cover your needs.

If you need to test different timezones I don't think it is possible to do that within a test itself. You would have to run vitest multiple times with different environment variables.

See this issue for more information: https://github.com/vitest-dev/vitest/issues/1575

vi.setSystemTime: https://vitest.dev/api/vi.html#vi-setsystemtime

Jinny answered 23/8, 2023 at 15:35 Comment(0)
O
1

Yes you can mock the timezone, here's how to do it:

    vi.spyOn(globalThis.Intl, 'DateTimeFormat').mockImplementation(() => ({
      resolvedOptions: () => ({
        timeZone: 'America/New_York', // Your timezone, rest is irrelevant
        calendar: 'gregory',
        locale: 'en-US',
        numberingSystem: 'latin',
      }),
      format: () => '1/1/2022',
      formatRange: () => '1/1/2022 – 1/1/2023',
      formatRangeToParts: () => [],
      formatToParts: () => [],
    }))
Orfurd answered 22/2 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.