JamesNK / Newtonsoft.Json.Schema

Json.NET Schema is a powerful, complete and easy to use JSON Schema framework for .NET
http://www.newtonsoft.com/jsonschema
Other
241 stars 106 forks source link

Json schema with datetime format ISO8601 #287

Open minhquang opened 2 years ago

minhquang commented 2 years ago

Hi, I was testing the jsonschema validator with date Time format and I find out that the validation is ok with datetime without the Z characters

2021-11-15T18 :34 :13Z => ok 2021-11-15T18 :34 :13 => ok

With the following property in the schema : { « type » : « string », « format » : « date-time » }

I am expecting that it is validating a datetime defined by ISO8601.

As workaround I had to add a pattern { « type » : « string », « format » : « date-time », « pattern » : »^( ?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|-0[1-9]|-1\d|-2[0-3]|-00:?(?:0[1-9]|[1-5]\d)|\+[01]\d|\+2[0-3])(?:|:?[0-5]\d)$ » }

Is it normal ? Do I miss something ?

JamesNK commented 2 years ago

There are both valid:

2021-11-15T18 :34 :13Z => ok

Date & time at UTC

2021-11-15T18 :34 :13 => ok

Date & time at local time

minhquang commented 2 years ago

Yes but if I want in the json exclusively a date time conformed to RFC 3339, section 5.6 with the Z character to specify an UTC date time.

date-time = full-date "T" full-time

  NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this
  syntax may alternatively be lower case "t" or "z" respectively.

  This date/time format may be used in some environments or contexts
  that distinguish between the upper- and lower-case letters 'A'-'Z'
  and 'a'-'z' (e.g. XML).  Specifications that use this format in
  such environments MAY further limit the date/time syntax so that
  the letters 'T' and 'Z' used in the date/time syntax must always
  be upper case.  Applications that generate this format SHOULD use
  upper case letters.

  NOTE: ISO 8601 defines date and time separated by "T".
  Applications using this syntax may choose, for the sake of
  readability, to specify a full-date and full-time separated by
  (say) a space character.

Am In wrong or do I have to specify a regex pattern in the schema ?

minhquang commented 2 years ago

Yes but if I want in the json exclusively a date time conformed to RFC 3339, section 5.6 with the Z character to specify an UTC date time.

date-time = full-date "T" full-time

  NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this
  syntax may alternatively be lower case "t" or "z" respectively.

  This date/time format may be used in some environments or contexts
  that distinguish between the upper- and lower-case letters 'A'-'Z'
  and 'a'-'z' (e.g. XML).  Specifications that use this format in
  such environments MAY further limit the date/time syntax so that
  the letters 'T' and 'Z' used in the date/time syntax must always
  be upper case.  Applications that generate this format SHOULD use
  upper case letters.

  NOTE: ISO 8601 defines date and time separated by "T".
  Applications using this syntax may choose, for the sake of
  readability, to specify a full-date and full-time separated by
  (say) a space character.

Am In wrong or do I have to specify a regex pattern in the schema ?

elgonzo commented 2 years ago

@JamesNK

There are both valid:

This is not unconditionally true. This only applies to older draft versions up to draft 6, where the definition of the "date-time" attribute was either ambiguous or a "SHOULD" clause.

However, with respect to draft 2019-09 this statement is not correct. Draft 2019-09 has the following to say about the "date-time" attribute (https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-02#section-7.3.1):

Date and time format names are derived from RFC 3339, section 5.6 [RFC3339]. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.

date-time: A string instance is valid against this attribute if it is a valid representation according to the "date-time" production.

If you look at the "date-time" production in RFC 3339, you'll notice that a time offset in the form of either Z or the "time-numoffset" production is mandatory for the "date-time" production.

Doing a quick check in the jsonschemavalidator (direct link: https://www.jsonschemavalidator.net/s/V7quKaFt), it seems that Newtonsoft.Json.Schema does not fully adhere to the 2019-09 spec with respect to "date-time", as it succeeds validation even though a "date-time" value is missing the time offset.

nulltoken commented 2 years ago

In a different schema validation library (ajv), a similar issue (timeoffset not being considered as mandatory by the validation engine) was eventually considered as too permissive => https://github.com/ajv-validator/ajv-formats/pull/33#issuecomment-881636023

elgonzo commented 2 years ago

Well, as a side note, the whole "format" shenanigans have reached peak epic status in draft 2019-09, where "format" should either be treated as an annotation (that may or may not be treated as a "best effort assertion") or an assertion based on a set of criteria that in its inscrutability is only bested by tax law in my humble opinion. Draft 2020-12 attempts to rectify this insanity somewhat by introducing two separate "format-annotation" and "format-assertion" vocabularies with each providing a definition for the "format" keyword. But i have to admit that i haven't dived deeper into those vocabularies and how the spec governs (attempted) simultaneous use of both these vocabularies.

minhquang commented 2 years ago

Hi is there any chance that the json validator fully adhere to the 2019-09 spec for datetime offset ?

Amachua commented 2 years ago

I also encounter a this issue with the tool and I would greatly appreciate that the next version properly validate the date-time as defined on the RFC 3339 as I'm unsure how to handle date-time that neither contains an offset nor a Z. :)

druud commented 1 year ago

So let's be explicit, and add 'date-time-tzopt' and 'date-time-tzman', or such.

Is 1e9 an integer? ;) And 3.000?

elgonzo commented 1 year ago

@druud, you mean throwing Json schema over board, and replace it with a Json-schema-lookalike that's not actually Json schema? Also, are Roman numerals integers? ;-P