Функция для получения сегодняшней даты?
Я создаю "выбор" внутри шаблона контракта, который требует проверки сегодняшней даты. Мой код DAML выглядит следующим образом:
controller dealer can
Add_Car : CarId
with
startCoverage: Date
do
-- Check for a legal start date
assert (
startCoverage > *today* --should check that its not before today
)
create this with date_vehicle_added = startCoverage
Как называется функция, которую я могу использовать для получения текущей даты? Нужно идти туда, где написано*today*
".
2 ответа
Tldr: использование getTime : Update Time
а также toDateUTC : Time -> Date
Но знайте о подводных камнях. Предпочтительно используйте шаблон Нотариально заверенная дата, если это возможно.
Моделирование даты / времени неявно
Моделирование даты и времени всегда является тонкой проблемой, вдвойне, когда речь идет о детерминированной распределенной системе, такой как цифровая бухгалтерская книга. DAML обеспечивает примитивную функцию getTime
который вернет "Эффективное время ГК"LET
), что, как гарантирует модель регистра, будет монотонно увеличивающимся значением времени (в миллисекундах), которое ограничено в пределах определенной регистром дельты времени UTC настенных часов. Это можно преобразовать в дату UTC, используя toDateUTC
функция вDA.Date
, Это прямой ответ на ваш вопрос, но есть несколько предостережений.
Время и дата указаны в UTC, вам нужно будет явно смоделировать, как это соответствует местному времени. Поскольку DAML является детерминированной распределенной системой, локального времени не существует, поскольку любая конкретная транзакция должна выполняться детерминистически в нескольких часовых поясах.
Неоправданное использование сравнений даты и времени может привести к тому, что контракты неявным образом останавливаются из-за истечения времени. Если выбор защищен проверкой времени по настенным часам, это может означать, что любая задержка в обработке вашего приложения может привести к тому, что выбор станет недействительным. Удостовериться, что вы правильно обрабатываете этот случай в коде приложения, - это тонкая проблема - и, поскольку это неявный параметр по вашему выбору, невозможно избежать оперативного вмешательства, чтобы избежать проблемы, даже если вы получили предварительное предупреждение.
Интеграционное тестирование вашей модели и приложения становится недетерминированным и неповторяемым при наличии явных временных сравнений. Хотя вы можете написать повторяемый
Scenario
тесты для вашей модели, так как у вас есть явный контроль надLET
там, это не будет осуществлять ваше приложение вне книги.
Моделирование даты / времени явно
Альтернативой является Нотариально заверенный Шаблон Даты. Здесь подписавшие договор договариваются о том, чтобы доверенная сторона заверяла текущую дату. Это нотариальное заверение принимает форму CurrentDate
договор на бухгалтерскую книгу. Этот договор имеет нотариуса в качестве подписавшего лица и, как правило, имеет единый выбор потребителя, контролируемый нотариусом, для продвижения даты.
Если вы используете этот подход, ваш Add_Car
выбор будет принимать дополнительный параметр currentDate : ContractId CurrentDate
, который вы можете рассматривать как контроллер, предоставляющий доказательства или доказательства того, что согласованный нотариус засвидетельствовал текущую дату для целей настоящего договора. Это решает проблемы с неявной временной моделью таким образом:
Поскольку Дата в явном виде указана в регистре, часовые пояса становятся явными в ходе выполнения
CurrentDate
контракт.Хотя договор все еще может быть приостановлен, если нотариус продвигает контракт на текущую дату, явный характер управления датами означает, что: а) любое упражнение, выполненное до обновления даты нотариуса, будет успешно обработано; что означает, б) Теперь есть возможность оперативного вмешательства, где вы заранее предупредили, что обработка для данного дня отстает от графика - при условии, что такое вмешательство предвидится и разрешено соглашением нотариуса.
Поскольку работа вашей системы опять-таки является чистой функцией содержимого регистра, поведение более крупного приложения становится детерминированным и повторяемым. Это значительно уменьшает усилия, необходимые для обслуживания, тестирования и отладки.
По этим причинам я бы рекомендовал использовать шаблон "Нотариально заверенная дата", где это возможно, оставляя за собой неявную обработку "Дата" для тех случаев, когда альтернативы действительно нет.
Перед вашим assert
, вы можете связать результат getTime
функция Тогда я предлагаю конвертировать startCoverage
к Time
с помощью toGregorian
а также datetime
функции в DA.Date.
У вас может не хватить информации, чтобы сделать это правильно с вашим примером кода; Date
это "местная дата", которая, как ожидается, будет интерпретирована относительно некоторого часового пояса, тогда как Time
абсолютное смещение эпохи UNIX. Именно по этой причине так много предостережений toDateUTC
перечислены в руководстве, и я рекомендую избегать этой функции.
Кроме того, имейте в виду, что доступно только "эффективное время бухгалтерской книги", что не совсем то же самое, что "текущее время". Конечно, для целей живых упражнений Add_Car
, getTime
результат будет соответствовать текущему времени. Тем не менее, транзакции обязательно воспроизводимы (для проверки или по другим причинам), и для этих исполнений getTime
будет производить то, что он первоначально сделал на упражнении. Вы не можете использовать getTime
определить количество времени настенных часов, которое DAML потребовалось для выполнения некоторого кода, и это означает, что даже во время живого упражнения регистр эффективного времени не точно соответствует настенным часам. Когда вы запускаете тестовые сценарии, время начинается в эпоху UNIX и может быть расширено вручную в вашем сценарии, как того требует ваш тест; на самом деле я могу рекомендовать использовать pass
или же passToDate
чтобы проверить тот самый контракт, который вы пишете.