I have an object which contains one or more properties of type date. I would like to validate the object using the ajv json schema validator package. I could convert the properties of type date to a string by using the toISOString(). But the object can be quiet big and thus I dont want to convert all the date-properties of the whole object. Is there a solution other than converting the date to a string? Could I somehow create a custom ajv schema validator?
 // My example schema
const schema = {
  "properties": {
    "createdAt": { 
       "type": "string",
       "format": "date-time"
    },
       "lastName": { "type": "string" },
       "firstName": { "type": "string" }
  }
};
// My example testobject
const testObj = {
   createdAt: new Date(),
   lastName: "Doe",
   firstName: "John"
}
// The validation
const validate = ajv.compile(schema);
const valid = validate(testObj);
if(!valid) console.log('Invalid: ' + ajv.errorsText(validate.errors));
This will do a console log, because the testObj.createdAt is a date and not a string.
The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JsonSchema) method with the JSON Schema. To get validation error messages, use the IsValid(JToken, JsonSchema, IList<String> ) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.
For example, because JSON doesn't have a “DateTime” type, dates need to be encoded as strings. format allows the schema author to indicate that the string value should be interpreted as a date. By default, format is just an annotation and does not effect validation.
This is the recommended form of date/ timestamp. date : This SHOULD be a date in the format of YYYY-MM-DD. It is recommended that you use the "date-time" format instead of "date" unless you need to transfer only the date part. time : This SHOULD be a time in the format of hh:mm:ss.
JSON Schema is a JSON-based format for defining the structure of JSON data. It provides a contract for what JSON data is required for a given application and how to interact with it. It can be used for validation, documentation, hyperlink navigation, and interaction control of JSON data.
Simply change your ajv schema from "type": "string" to "type": "object" and the built-in ajv date-time format will work.  Here's a working fiddle.
You can also define a custom ajv format to validate a Date object (or string) like this:
ajv = new Ajv();
ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }
  return !isNaN(Date.parse(dateTimeString));  // any test that returns true/false 
});
... and invoke your custom format in the ajv schema like this:
const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"
Putting it all together here's the code and a working fiddle for creating a custom date format:
// My example schema
const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"
    },
    "lastName": {
      "type": "string"
    },
    "firstName": {
      "type": "string"
    },
    "required": [ 'createdAt', 'lastName', 'firstName' ],
    "additionalProperties": false,
  }
};
// My example testobject
const testObj = {
  createdAt: new Date(),
  lastName: "Doe",
  firstName: "John"
}
// The validation
ajv = new Ajv();
ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }
  return !isNaN(Date.parse(dateTimeString));  // return true/false 
});
const validate = ajv.compile(schema);
const valid = validate(testObj);
if (valid)
  alert('valid');
else
  alert('Invalid: ' + ajv.errorsText(validate.errors));
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With