31

I have a string with this format 2018-02-26T23:10:00.780Z I would like to check if it's in ISO8601 and UTC format.

let date= '2011-10-05T14:48:00.000Z';
const error;
var dateParsed= Date.parse(date);
if(dateParsed.toISOString()==dateParsed && dateParsed.toUTCString()==dateParsed) {
  return  date;
}
else  {
  throw new BadRequestException('Validation failed');
}

The problems here are:

  • I don't catch to error message
  • Date.parse() change the format of string date to 1317826080000 so to could not compare it to ISO or UTC format.

I would avoid using libraries like moment.js

Hasan Sh
  • 1,018
  • 9
  • 16
infodev
  • 4,673
  • 17
  • 65
  • 138

3 Answers3

47

Try this - you need to actually create a date object rather than parsing the string

NOTE: This will test the string AS YOU POSTED IT.

YYYY-MM-DDTHH:MN:SS.MSSZ

It will fail on valid ISO8601 dates like

  • Date: 2018-10-18
  • Combined date and time in UTC: 2018-10-18T08:04:30+00:00 (without the Z and TZ in 00:00)
  • 2018-10-18T08:04:30Z
  • 20181018T080430Z
  • Week: 2018-W42
  • Date with week number: 2018-W42-4
  • Date without year: --10-18 (last in ISO8601:2000, in use by RFC 6350[2])
  • Ordinal date: 2018-291

It will no longer accept INVALID date strings

function isIsoDate(str) {
  if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(str)) return false;
  const d = new Date(str); 
  return d instanceof Date && !isNaN(d.getTime()) && d.toISOString()===str; // valid date 
}

console.log(isIsoDate('2011-10-05T14:48:00.000Z'))

console.log(isIsoDate('2018-11-10T11:22:33+00:00'));

console.log(isIsoDate('2011-10-05T14:99:00.000Z')); // invalid time part 
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 4
    `2018-11-10T11:22:33+00:00` would also be ISO8601 and UTC :D – Jaromanda X Oct 18 '18 at 08:23
  • @JaromandaX what do you mean? that `2018-11-10T11:22:33+00:00` should be allowed to pass? – mplungjan Oct 18 '18 at 08:25
  • well, yes, isn't it an ISO8601 UTC date? (I forgot the `.000` but the `+00:00` is UTC, isn't it? – Jaromanda X Oct 18 '18 at 08:25
  • Oh, sorry, I don't "say so" ... It was supposed to be a question :p – Jaromanda X Oct 18 '18 at 08:27
  • Javascript Dates make the inner child cry :p – Jaromanda X Oct 18 '18 at 08:32
  • I never had issues with JS dates :) I do have issues when you need a large array of regex to validate user entered dates, which is why I as much as possible force the user to use datepickers, dropdowns or sliders – mplungjan Oct 18 '18 at 08:33
  • Is there a javascript function that validates ISO + UTC format or should I use Regex ? Can you make the right regex to validate UTC+ ISO date format ? – infodev Oct 18 '18 at 08:58
  • 1
    My code uses a regex to validate `YYYY-MM-DDTHH:MN:SS.MSSZ` and then uses date to validate that it is an actual date. What dates/times are you looking for. You must have some idea of what your input could be – mplungjan Oct 18 '18 at 09:06
  • Here's the date format `2018-02-26T23:10:00.780Z`that should pass .Why you are checking if date is ISO format. the regex does not do it before ? – infodev Oct 18 '18 at 09:21
  • Ok I understand why. just to optimise code I suggest to add to `if` new `new Date(Date.parse(value)).toISOString() !==str` – infodev Oct 18 '18 at 09:32
  • 2
    There is no need to test the date for validity if it does not pass the string test of the regex first - at least that was my idea. It is faster than to create the date object – mplungjan Oct 18 '18 at 09:38
  • 1
    exception when run with `console.log(isIsoDate('2011-10-05T14:99:00.000Z'))` – yelliver Aug 10 '22 at 06:12
  • 1
    @yelliver see updated script that will catch your invalid date – mplungjan Aug 10 '22 at 06:23
  • 1
    If you're using typescript you need to do `!isNaN(d.getTime())` to avoid an error – Sam Hasler May 23 '23 at 08:30
  • 1
    Be aware that there are invalid dates that JavaScript will parse, such as February 31st `new Date('2023-02-31T01:23:45.678Z').toISOString() === '2023-03-03T01:23:45.678Z'`. The `isNan` check will not catch this. Internally, the parsing will fail as long as the day is `<= 31` and just rolls over into the next month on "overflow". Here is a pretty solid check: https://github.com/ajv-validator/ajv-formats/blob/4dd65447575b35d0187c6b125383366969e6267e/src/formats.ts#L160 – Eric Haynes Aug 14 '23 at 21:35
  • Oops, meant to say "parsing will not fail unless" – Eric Haynes Aug 14 '23 at 21:50
1
let date= '2011-10-05T14:48:00.000Z';
var dateParsed= new Date(Date.parse(date));
//dateParsed
//output: Wed Oct 05 2011 19:48:00 GMT+0500 (Pakistan Standard Time)
if(dateParsed.toISOString()==date) {
   //Date is in ISO
}else if(dateParsed.toUTCString()==date){
  //DATE os om UTC Format
}
Syed Faizan
  • 958
  • 9
  • 19
  • 1
    `dateParsed.toUTCString()` will **NEVER** be in ISO8601 format - so it seems an odd thing to check if a non-ISO8601 string is the same as the passed in date ... the whole point is, the passed in date, according to the question, must be ISO8601 format – Jaromanda X Oct 18 '18 at 08:29
0

I think what you want is:

let date= '2011-10-05T14:48:00.000Z';
const dateParsed = new Date(Date.parse(date))

if(dateParsed.toUTCString() === new Date(d).toUTCString()){
   return  date;
} else {
     throw new BadRequestException('Validation failed'); 
}

I hope that is clear!

Hasan Sh
  • 1,018
  • 9
  • 16