hapijs / hapijs/joi

`Joi.date().default('now')` does not produce current time

Open
#3,112 3 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
21.2k
Forks
1.5k
Avg merge
4h 57m
Merged PRs (30d)
14

Description

### Runtime

node.js

### Runtime version

24.x

### Module version

18.2.0

### Last module version without issue

_No response_

### Used with

standalone

### Any other relevant information

Found while working on JSON Schema output for date schemas (re #3108).

Happy to submit a (reasonable size 😄 ) PR for this one if you're open to it.

### What are you trying to achieve or the steps to reproduce?

`Joi.date().default('now')` does not resolve to the current time. The literal string `'now'` is returned as the default value:

```js
const schema = Joi.date().default('now');
const result = schema.validate(undefined);

result.value; // 'now'
```

This is surprising because `'now'` is a documented dynamic token in the date comparison APIs:

```js
Joi.date().min('now');
Joi.date().max('now');
Joi.date().greater('now');
Joi.date().less('now');
```

Those rules special-case `'now'` and compare against `Date.now()` at validation time. So there is an inconsistency in how the same token is interpreted across the date API surface:

- `min/max/greater/less('now')` treat `'now'` as a dynamic date token.
- `default('now')` treats `'now'` as an ordinary string literal.

Defaults are applied after validation/coercion, and literal defaults are returned as-is, so there is no date-specific interpretation for `'now'` in the default path. Workaround:

```js
Joi.date().default(() => new Date()); // returns an actual Date
```

### What was the result you got?

`'now'` as a literal.

### What result did you expect?

Current date value.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.