Timestamps

I’ve got a goal entity which consists of a description and whether the goal has been completed. I think I’d like to know how long it took between creating the goal and completing the goal.

Traditionally, I would have two fields for “created” and “completed” (or last updated, or whatever). Is there a way (without much difficulty) to figure that out WITHOUT adding those fields?

It seems like I should be able to query the entity for its history, and then get a real-world time from the T index. No idea how I’d go about that, though.

There are a few approaches here, but assuming you want to use transaction time as your time stamp for both of these, the following could work. If not, you could add some additional domain time stamp to the transaction and use a similar pattern.

In query you can bind the t place in any datom to get the transaction entity ref for when that fact was asserted. You can then bind the :db/txInstant from the transaction. Your description datom would be from when the goal was created and your completion flag would be asserted at the time of completion. For this to work you would have to never update the description or else it would mess up your start time. If that’s an issue, you could query the $history database which will contain past values of the completion flag; e.g. find the tx from when completed was false and then when completed was/is true. Be aware that when querying history there is an extra spot in datom tuples after t indicating asserted? in which case you would want to limit yourself to true

So:

:find ?start ?end
:where
 [?goal :goal/description _ ?startTx]
 [?goal :goal/completed true ?endTx]
 [?startTx :db/txInstant ?start]
 [?endTx :db/txInstant ?end]
:in $ ?goal

Although you can definitely use the built-in txInstant to answer this type of question, I generally recommend that if domain time is important for your data model, then you should explicitly include it in your schema.

In particular, you can imagine scenarios where “when the thing happened” and “when the system knew about it” differ. Datomic’s built-in transaction time is specifically oriented at modeling “when the system knew about it”. That may or may not always match “when it happened”. Additionally, it can often be very useful to be able to independently query/assess these two notions of time (for instance: what things were ‘known about’ more than X minutes after ‘they happened’).

Val has a nice blog post about this topic: https://vvvvalvalval.github.io/posts/2017-07-08-Datomic-this-is-not-the-history-youre-looking-for.html

1 Like

Thanks, guys. I’m absorbing both of those answers. :thinking: