Instead of injecting the current date and time into the regular “range” violation messages, let’s add separate messages for “now” range endpoints. This means we can cache the violation message for as long as it’s valid, and will probably also make for easier-to-understand violation messages.
(An alternative approach to solve the caching problem would be to store “current time” as a special value in ViolationMessage arguments, and resolve it in the renderer, but I think the other benefits of having separate messages are clear enough that it’s worth pursuing this path instead.)