class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

flag for @IsDateString() to validate date without time

Open RomanSolianik opened this issue 6 years ago • 16 comments

It`s more feature request. I think it would be nice to have ability validate date string without time using @IsDateString() decorator. For example, '2000-07-26', not '2000-07-26T00:00:01.967Z'. Cannot find how to do that not using @Matches() decorator.

RomanSolianik avatar Jul 26 '19 13:07 RomanSolianik

Feel free to contribute :)

vlapo avatar Jul 31 '19 12:07 vlapo

I agree. There should be two different functions one for checking isostring and another for plain date string

rubiin avatar Aug 19 '19 08:08 rubiin

@vlapo i am taking this one

rubiin avatar Oct 02 '19 17:10 rubiin

I create custom one.

import { registerDecorator, ValidationOptions } from 'class-validator';

export function IsOnlyDate(validationOptions?: ValidationOptions) {
  return function(object: Object, propertyName: string) {
    registerDecorator({
      name: 'IsOnlyDate',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [],
      options: {
        message: 'Please provide only date like 2020-12-08',
        ...validationOptions,
      },
      validator: {
        validate(value: any) {
          const regex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/;
          return typeof value === 'string' && regex.test(value);
        },
      },
    });
  };
}

ghost avatar Oct 02 '20 04:10 ghost

@jerryfreshworks as a little note - the provided validator passes 2020-02-31 as a correct date so it's rather a format validator than actually validating if the date exists.

dtmzr avatar Dec 21 '20 02:12 dtmzr

anything ?

kaisskander avatar Jan 04 '21 15:01 kaisskander

for date format only you can use Matches validator

@Matches(/^\d{4}(-)(((0)[0-9])|((1)[0-2]))(-)([0-2][0-9]|(3)[0-1])$/i, {
    message: "$property must be formatted as yyyy-mm-dd"
})

talski avatar Feb 11 '21 23:02 talski

@talski of course we can use regular expressions.. basically we can use them for all validations, but I think the point of the creation of this library was to simplify this process

RomanSolianik avatar Feb 12 '21 11:02 RomanSolianik

2000-07-26

so correct me if i am wrong but it should also validate the date string as valid / invalid date after validating the format?

rubiin avatar Feb 12 '21 16:02 rubiin

@talski of course we can use regular expressions.. basically we can use them for all validations, but I think the point of the creation of this library was to simplify this process

yes, we can use regex for almost all the validations provided by library but people are looking for out of the box solutions like you said

rubiin avatar Feb 12 '21 16:02 rubiin

import { ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
import moment = require('moment');

@ValidatorConstraint()
export class isDate implements ValidatorConstraintInterface {
  validate(value: any) {
    if (typeof value === 'string') {
      return /^[1-9]\d*-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/.test(value) && moment(value, 'YYYY-MM-DD').isValid();
    }
    return false;
  }

  defaultMessage({ property }) {
    return `${property} must be a valid date (Required format: YYYY-MM-DD)`;
  }
}

Hope this helps!

anhpt97 avatar Feb 20 '21 07:02 anhpt97

@IsISO8601 does the job!

pasan9 avatar Feb 03 '22 11:02 pasan9

@pasan9, thanks my friend, you saved my day.

rongyadong avatar Apr 20 '22 07:04 rongyadong

@IsISO8601 does the job!

Yes, but how to ensure we only receive a date (without time)? Currently, I do this:

@IsISO8601({ strict: true })
@Length(10, 10)

but I am wondering if there is something cleaner to do. Is there any option to the @IsISO8601() decorator I can use to specify I only accept a date?

pepsi92 avatar May 05 '22 14:05 pepsi92

The best answer I found for this issue on stack overflow: https://stackoverflow.com/a/62517465/3342886

yehyaumar avatar Sep 01 '22 05:09 yehyaumar

There is an ongoing PR in validator.js where ISO8601 is being discussed in terms of what subsets of ISO 8601 should be most prominent (conigurable via options flags). ISO 8601 is notoriously all inclusive, allowing things that may not seem correct at first glance such as ordinal dates without a separator: 1933329

If you have an opinion about which date/date time formats are most important/relevant, feel free to chime in.

braaar avatar Sep 01 '22 05:09 braaar

This is currently possible. The @IsDateString can validate only YYYY-MM-DD pattern, and with a @MaxLenght decorator you can enforce that no time part is specified.

import { IsDateString, MaxLength, validate } from 'class-validator';

class MyPayload {
  @MaxLength(10)
  @IsDateString()
  date: string;

  constructor(date?: string) {
    this.date = date;
  }
}

// Will pass
validate(new MyPayload('2022-12-24')).then(console.log);
// Will fail
validate(new MyPayload('2022-12-24:12:00:00Z')).then(console.log);
validate(new MyPayload('invalid')).then(console.log);

It's always a good idea to think of decorators as pieces of Lego. Some things can only be achieved with multiple decorators. The solution is not always to extend the decorator we first thought of using to match my exact use-case.

NoNameProvided avatar Dec 09 '22 20:12 NoNameProvided

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Jan 09 '23 00:01 github-actions[bot]