···11591159function setSystemTime(date: string | number | Date): Vitest
11601160```
1161116111621162-If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers. If fake timers are not enabled, this method will only mock `Date.*` calls.
11621162+If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers. If fake timers are not enabled, this method will only mock `Date.*` and `Temporal.Now.*` calls.
1163116311641164Useful if you need to test anything that depends on the current date - for example [Luxon](https://github.com/moment/luxon/) calls inside your code.
11651165
+9
docs/guide/migration.md
···201201vi.useFakeTimers({ toNotFake: ['Temporal'] })
202202```
203203204204+### `setSystemTime` Now Mocks Temporal
205205+206206+Previously `vi.setSystemTime` mocked only `Date` without fake timers, but now it also mocks methods of `Temporal.Now`.
207207+208208+```ts
209209+vi.setSystemTime(0)
210210+Temporal.Now.instant().epochMilliseconds // 0 (was the real time in v4)
211211+```
212212+204213### `toThrow("")` Matches Any Error Message
205214206215[`toThrow`](/api/expect#tothrow) (and its alias `toThrowError`) treats a string argument as a substring of the error message. In Vitest 4 an empty string was special-cased to the `/^$/` pattern, so it matched only an error whose message was empty. It now behaves like any other substring, and an empty string is contained in every message:
+3-1
docs/guide/mocking.md
···171171172172### Mock the current date
173173174174-To mock `Date`'s time, you can use `vi.setSystemTime` helper function. This value will **not** automatically reset between different tests.
174174+To mock `Date` and `Temporal`'s time, you can use `vi.setSystemTime` helper function. This value will **not** automatically reset between different tests.
175175176176Beware that using `vi.useFakeTimers` also changes the `Date`'s time.
177177···180180vi.setSystemTime(mockDate)
181181const now = new Date()
182182expect(now.valueOf()).toBe(mockDate.valueOf())
183183+const nowInstant = Temporal.Now.instant()
184184+expect(nowInstant.epochMilliseconds).toBe(mockDate.valueOf())
183185// reset mocked time
184186vi.useRealTimers()
185187```
···44import { Writable } from 'node:stream'
55import { getSafeTimers } from '@vitest/utils/timers'
66import c from 'tinyrainbow'
77-import { RealDate } from '../integrations/mock/date'
87import { getWorkerState } from './utils'
88+99+const RealDate = globalThis.Date
9101011export const UNKNOWN_TEST_ID = '__vitest__unknown_test__'
1112
-110
packages/vitest/src/integrations/mock/date.ts
···11-/* Ported from https://github.com/boblauer/MockDate/blob/master/src/mockdate.ts */
22-/*
33-The MIT License (MIT)
44-55-Copyright (c) 2014 Bob Lauer
66-77-Permission is hereby granted, free of charge, to any person obtaining a copy
88-of this software and associated documentation files (the "Software"), to deal
99-in the Software without restriction, including without limitation the rights
1010-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111-copies of the Software, and to permit persons to whom the Software is
1212-furnished to do so, subject to the following conditions:
1313-1414-The above copyright notice and this permission notice shall be included in all
1515-copies or substantial portions of the Software.
1616-1717-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323-SOFTWARE.
2424-*/
2525-2626-export const RealDate: DateConstructor = Date
2727-2828-let now: null | number = null
2929-3030-class MockDate extends RealDate {
3131- constructor()
3232- constructor(value: number | string)
3333- constructor(
3434- year: number,
3535- month: number,
3636- date?: number,
3737- hours?: number,
3838- minutes?: number,
3939- seconds?: number,
4040- ms?: number
4141- )
4242- constructor(
4343- y?: number | string,
4444- m?: number,
4545- d?: number,
4646- h?: number,
4747- M?: number,
4848- s?: number,
4949- ms?: number,
5050- ) {
5151- super()
5252-5353- let date: any
5454- switch (arguments.length) {
5555- case 0:
5656- if (now !== null) {
5757- date = new RealDate(now.valueOf())
5858- }
5959- else {
6060- date = new RealDate()
6161- }
6262- break
6363- case 1:
6464- date = new RealDate(y!)
6565- break
6666- default:
6767- d = typeof d === 'undefined' ? 1 : d
6868- h = h || 0
6969- M = M || 0
7070- s = s || 0
7171- ms = ms || 0
7272- date = new RealDate(y as number, m!, d, h, M, s, ms)
7373- break
7474- }
7575-7676- Object.setPrototypeOf(date, MockDate.prototype)
7777-7878- return date
7979- }
8080-}
8181-8282-MockDate.UTC = RealDate.UTC
8383-8484-MockDate.now = function () {
8585- return new MockDate().valueOf()
8686-}
8787-8888-MockDate.parse = function (dateString) {
8989- return RealDate.parse(dateString)
9090-}
9191-9292-MockDate.toString = function () {
9393- return RealDate.toString()
9494-}
9595-9696-export function mockDate(date: string | number | Date): void {
9797- const dateObj = new RealDate(date.valueOf())
9898- if (Number.isNaN(dateObj.getTime())) {
9999- throw new TypeError(`mockdate: The time set is an invalid date: ${date}`)
100100- }
101101-102102- // @ts-expect-error global
103103- globalThis.Date = MockDate
104104-105105- now = dateObj.valueOf()
106106-}
107107-108108-export function resetDate(): void {
109109- globalThis.Date = RealDate
110110-}