xsd date and dateTime types restriction
Жизненная ситуация
Повидав немало xsd-схем, я обнаружил, что мало кто использует ограничения на типы даты / времени. Бывает все в схеме по максимуму ограничат, даже больше, чем нужно, а дата и время в используется исходном базовом типе.
Проблематика
Какие в такой ситуации я вижу риски при интеграции систем посредством обмена данными через XML-фалйы:
- Пропуск при валидации по схеме "дефолтного" значения даты
Дело в том, что в некоторых базах данных в полях с типом даты и даты / времени вместо значения null (пустого значения используется какое-нибудь минимальное значение, типо 1900-01-01.
Что это значит.
А то что при передаче данных по xsd-схеме дата, например, является обязательной, а в интегрируемой системе не реализовано ее корректного заполнения, и система заполнит ее "пустым" значением, например, тем же 1900-01-01. Передаст совсем не бизнесовую дату, которая сломает далее по процессу всю логику - Использование неправильного значения времени и даже даты из-за часовых поясов
Мало кто заморачивается указанием часовых поясов в типах даты / времени xml-файлов, а это может привести к ошибкам, даже если при обмене оба сервера находятся в одном часовом поясе. Просто потому что при развертывании сервера забыли указать для него правильный часовой пояс, и он использует время Гринвича.
А при обмене между разными часовыми поясами, пож-та, не надо думать, что все сервера настроены на московское время всегда
Решение
У этих описанных выше двух рисков есть одно простое покрытие: использование паттерна ограничения значений.
Ниже приведены примеры такого ограничения. Диапазон значения дат можно менять по вкусу, но с учетом "дефолтного" значения даты в используемой интегрируемой системой базе данных
- Тип времени и даты
Данный паттерн обязывает для времени либо явно указать часовой пояс, либо передать приведенное к Гринвичу время
<xsd:simpleType name="typeTimeStamp">
<xsd:restriction base="xsd:dateTime">
<xsd:pattern value="2[0-9][0-9][0-9]-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](\+(0[2-9]|1[0-2]):00|Z)"/>
</xsd:restriction>
</xsd:simpleType> - Тип даты
<xsd:simpleType name="typeDate">
<xsd:restriction base="xsd:date">
<xsd:pattern value="2[0-9][0-9][0-9]-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])"/>
</xsd:restriction>
</xsd:simpleType>
Лирика
В примере выше диапазон дат ограничен третьим тысячелетием. Если вы считаете, что ваша схема будет использоваться и в четвертом тысячелетии, то пример выше можно легко поправить с учетом этого :)
Но вообще лучше подстраховаться и значения годов четвертого тысячелетия не обрубать валидацией, да :) чтобы российский, например, госчиновник следующей цивилизации четвертого тысячелетия, откопав такую схему, не рассердился на человека 21-го века и не отправил в прошлое андроида при исполнении показывать кто тут валидный :)