hapijs / joi-date

Joi extensions for dates
Other
83 stars 25 forks source link

Allow coercion of numeric date formats to Date #41

Open gregbrowndev opened 2 years ago

gregbrowndev commented 2 years ago

Context

What problem are you trying to solve?

I wish to validate and convert a numerical value into a proper Date object. The raw value is a number of the format YYYYMMDD. The data is received from an API which I don't control.

Additionally, I want to be able to specify the correct expected output type in my schema, i.e. using Joi.date(). I am using joi-to-typescript to generate the Typescript interface for this value (which I want to be a Date, not a number or anything else).

The problem is the number is cast into a UNIX/millisecond epoch timestamp and the format option is ignored.

Joi.date().validate(20211029)
// {value: Thu Jan 01 1970 06:36:51 GMT+0100 (Greenwich Mean Time)}

Joi.date().format("YYYYMMDD").validate(20211029)
// {value: Thu Jan 01 1970 06:36:51 GMT+0100 (Greenwich Mean Time)}

Ideally, if I could coerce the value into a Joi.string() first and then into Joi.date() that would solve my problem.

I have found a workaround using custom:

const dateNumberValidator: CustomValidator = (_: any, helpers: CustomHelpers) => {
  const dateStr = String(helpers.original);
  if (!dateStr) {
    return dateStr;
  }
  const {value, error} = Joi.date().format("YYYYMMDD").validate(dateStr)
  if (error) {
    return helpers.error(error);
  }
  return value
}

Joi.date().custom(dateNumberValidator).validate(20211029)
// {value: "2021-10-28T23:00:00.000Z"}

Do you have a new or modified API suggestion to solve the problem?

It would be great if an option was added to provide more control over how the raw value is coerced. It should allow a numeric value to be cast into a string before parsing as a Date rather than treating all numbers as epoch timestamps.

Thanks!

hueniverse commented 2 years ago

What would it look like? Care to suggest a syntax?