This is mostly to satisfy my own curiosity because to me, it doesn’t make sense at first glance. I run this code on client and server side at the same time (as close as possible using one button push):
On the server side, datetime.now() and datetime.utcnow() are identical, which is expected. My timezone is UTC - 6:00 at the moment, which is the exact difference between the two client timestamps, also as expected. But then why is the timestamp for datetime.now() on the client side closer to to the server’s timestamp than the client’s datetime.utcnow()? Is this coming from skulpt, the time package, Anvil, or is this exactly how it should be and I’m just not getting it?
I know I shouldn’t be using times from the client side, so this isn’t super significant, but now that I’ve found it, my brain won’t leave it alone lol.
This is because you used time.mktime(), which interprets its input as a local time (and then adjusts to produce an output in “seconds since the epoch”, which is defined as midnight UTC on Jan 1st 1970).
Generally speaking, the time.* functions in Python are full of timezone-related bear traps. You should avoid them and use datetime everywhere.
(Fun fact: Anvil handles datetimes intelligently! If you pass a time-zone-unaware datetime to or from a server function, it gets stamped with the timezone of wherever it came from. So when you collect a datetime in a DatePicker on the client, pass it to the server and store it in a data table, it (correctly) ends up in the client’s time zone.)
On the subject, what do you think is the optimal way of storing a time-related object in a JSON field? I know it could be the timestamp like I’m currently trying to use, but I know I could also do something like an ISO formatted string. Do you have any opinions on the subject?
ISO format is nice, and easy to generate with datetime.toisoformat(), but parsing it back out is a pain. (You need to do it by hand with strptime – astonishingly, the datetime.fromisoformat() method didn’t turn up until Python 3.7!)
If you want your JSON to be human-friendly, use ISO format; if you’re feeling lazy use epoch timestamps.