postgresqldatetimehaskellesqueleto

Dealing with different time precision between Data.Time and Postgresql


I have some database functions which I'm testing (to make sure my queries etc. work) -- in them, I'm de/serialising records (via Database.Esqueleto.Experimental) and these contain values of type UTCTime (and Maybe UTCTime, etc.).

The problem is that I get these sorts of errors in my tests:

1) Vulture.Database.EventRepository.addEvents correctly sets the event properties
       expected: 2023-05-06 21:52:13.441270819 UTC
        but got: 2023-05-06 21:52:13.441271 UTC

This is sort of annoying, but I don't know how to either manipulate UTCTime values to change the precision, or to change the way the equality works here.


Solution

  • As you've noticed, UTCTime by itself has a pretty sparse api. Just about everything interesting involves going via NominalDiffTime. For this case, I think you're best served by getting the difference between the two times and then making sure it's below some epsilon. For this, the relevant time function is diffUTCTime, and the rest takes advantage of the extensive set of instances available for NominalDiffTime. Thanks to the Num instance, we have abs available. Thanks to the Num and Fractional instances, we can use literals to create NominalDiffTime values. And of course there's Ord for comparisons...

    let eps = 1e-5 in abs (diffUTCTime t1 t2) < eps
    

    Feel free to adjust eps as desired. And of course, you might need to adjust the structure of the whole thing to get good diagnostics out of the test framework.

    Remember this as the basic framework for working with UTCTime - those values are just points in time. The really interesting stuff involves working with NominalDiffTime values which represent intervals between UTCTime values. Those intervals have a much richer API for manipulating them then the points have.