json 架构日期时间未正确检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20264146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 20:04:59  来源:igfitidea点击:

json schema date-time does not check correctly

jsondatetimejsonschema

提问by IHeartAndroid

I have a JSON and a JSON-schema

我有一个 JSON 和一个 JSON 模式

JSON:

JSON:

{
"aaa": "4000-02-01 00:00:00"
}

JSON-schema:

JSON 架构:

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "type": "object",
    "properties": {

        "aaa": {
            "type": "string",
            "format": "date-time"
        }


    }, "required": ["aaa"]
}

The JSON gets validated by the JSON-schema. However if I change the field aaato "bla" the schema does not notice that it is not a date-time any longer.

JSON 由 JSON 模式验证。但是,如果我将该字段更改aaa为“bla”,则架构不会注意到它不再是日期时间。

Did I miss anything in the schema?

我错过了架构中的任何内容吗?

回答by Beau Barker

For Python's jsonschemalibrary, specify the format checker when calling validate:

对于 Python 的jsonschema库,调用时指定格式检查器validate

jsonschema.validate(data, schema, format_checker=jsonschema.FormatChecker())

To validate a date-time format, the strict-rfc3339package should be installed.

要验证日期时间格式,应安装strict-rfc3339包。

See Validating Formats.

请参阅验证格式

回答by cloudfeet

Validation with "format"is optional. This is partly because schema authors are allowed to completely make up new formats, so expecting all formats to be validated is not reasonable.

验证"format"是可选的。这部分是因为模式作者被允许完全组成新格式,因此期望所有格式都经过验证是不合理的。

Your library should(if it is decent) have a way to register custom validators for particular formats. For example, the tv4validation library (in JavaScript) has the tv4.addFormat()method:

您的库应该(如果合适的话)有办法为特定格式注册自定义验证器。例如,tv4验证库(在 JavaScript 中)具有tv4.addFormat()方法

tv4.addFormat('date-time', function (data) {
    return isValidDate(data);
});

Once you've done this, then "format": "date-time"in the schema should validate dates correctly.

完成此操作后,"format": "date-time"架构中应正确验证日期。

回答by Matt Johnson-Pint

It is highly likely that the implementation of JSON schema validation that you're using is requiring the Tseparator between the date and time components. This is a staple of the RFC3339spec and ISO8601which it is based upon. While both have provisions for omitting the T, they both make it something that can be done by agreement, rather then a mandatory thing to support. (Go figure.)

您正在使用的 JSON 模式验证的实现很可能需要T日期和时间组件之间的分隔符。这是RFC3339规范和它所基于的ISO8601 的主要内容。虽然两者都有省略 的规定T,但它们都使其成为可以通过协议完成的事情,而不是必须支持的事情。(去搞清楚。)

Also, RFC3339 doesrequire that you include either a time zone offset or a Zto indicate UTC. This locks it down to a particular moment in time, rather than a human representation of one in some unknown time zone. Since you have required neither, that's likely while it has failed validation.

此外,RFC3339确实要求您包含时区偏移量或 aZ以指示 UTC。这会将其锁定到特定时刻,而不是某个未知时区中的人的代表。由于您两者都不需要,因此很可能在验证失败时。

From the JSON Schema spec:

来自JSON Schema 规范

7.3.1.2. Validation

A string instance is valid against this attribute if it is a valid date representation as defined by RFC 3339, section 5.6[RFC3339].

7.3.1.2. 验证

如果字符串实例是RFC 3339 第 5.6 节[RFC3339]定义的有效日期表示,则该字符串实例对该属性有效。

回答by IHeartAndroid

I found a workaround by using this library. It checks the content of the field in javascript code:

我通过使用这个库找到了一个解决方法。它检查 javascript 代码中字段的内容:

function isValidDate(datestring) {

    var format = d3.time.format("%Y-%m-%d %H:%M:%S");
    var date = format.parse(datestring);  
    if (date) {
        return true;
    }
    return false;
}

回答by R.Westbrook

You can change the source code for the python jsonschema module.

您可以更改 python jsonschema 模块的源代码。

Find the datetime-related code, at jsonschema/_format.pyfunc is_date_time(instance). Like this, about line 204 - 225, for version 2.6.0:

jsonschema/_format.pyfunc 处找到与日期时间相关的代码is_date_time(instance)。像这样,关于 204 - 225 行,对于 2.6.0 版:

try:
    import strict_rfc3339
except ImportError:
    try:
        import isodate
    except ImportError:
        pass
    else:
        @_checks_drafts("date-time", raises=(ValueError, isodate.ISO8601Error))
        def is_datetime(instance):
            if not isinstance(instance, str_types):
                return True
            return isodate.parse_datetime(instance)
else:
    @_checks_drafts("date-time")
    def is_datetime(instance):
        if not isinstance(instance, str_types):
            return True
        return strict_rfc3339.validate_rfc3339(instance)

Comment out the above and paste this, or replace the _check_draftsfunction above with this:

注释掉上面并粘贴它,或者_check_drafts用这个替换上面的函数:

@_checks_drafts("date-time")
def is_datetime(instance):
    if not isinstance(instance, str_types):
        return True
    try:
        datetime.datetime.strptime(instance, "%Y-%m-%d %H:%M:%S")
    except ValueError:
        return False
    return True