Подтвердить что ты не робот

Json-схема дата-время не проверяется правильно

У меня есть JSON и JSON-схема

JSON:

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

JSON-схема:

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

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


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

JSON получает подтверждение по схеме JSON. Однако, если я изменяю поле aaa на "bla", схема не замечает, что это не дата-время больше.

Я пропустил что-нибудь в схеме?

4b9b3361

Ответ 1

Для Python jsonschema укажите проверку формата при вызове validate:

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

Для проверки формата даты и времени должен быть установлен пакет strict-rfc3339.

См. Проверка форматов.

Ответ 2

Валидация с помощью "format" является необязательной. Отчасти это связано с тем, что авторам схем разрешено полностью создавать новые форматы, поэтому ожидание проверки всех форматов не является разумным.

Ваша библиотека должна (если она приличная) иметь способ зарегистрировать специальные валидаторы для определенных форматов. Например, библиотека проверки tv4 (в JavaScript) имеет метод tv4.addFormat():

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

Как только вы это сделали, тогда "format": "date-time" в схеме должно правильно подтвердить даты.

Ответ 3

Весьма вероятно, что для реализации проверки JSON-схемы, которую вы используете, требуется разделитель T между компонентами даты и времени. Это основной элемент RFC3339 spec и ISO8601 на которой он основан. Хотя у обоих есть положения о том, чтобы исключить T, они оба делают это чем-то, что можно сделать по соглашению, а не обязательно для поддержки. (Идите цифру.)

Кроме того, RFC3339 требует, чтобы вы указывали либо смещение часового пояса, либо Z для указания UTC. Это блокирует его до определенного момента времени, а не человеческого представления одного в каком-то неизвестном часовом поясе. Поскольку вы не нуждаетесь ни в одном, это вероятно, пока он не прошел проверку.

Из Спецификация JSON Schema:

7.3.1.2. Проверка

Строковый экземпляр действителен в отношении этого атрибута, если он является допустимым представлением даты, как определено RFC 3339, раздел 5.6 [RFC3339].

Ответ 4

Я нашел обходное решение, используя эту библиотеку. Он проверяет содержимое поля в 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;
}

Ответ 5

Вы можете изменить исходный код модуля jsonschema python.

Найдите код, связанный с дат-временем, в jsonschema/_format.py func 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)

Прокомментируйте это выше и вставьте это или замените функцию _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