I’m using the Users service, and I noticed that the signed_up and last_login columns in the Users table are set to the time in the UK where Anvil (and its servers) are based. So although I’m the USA (EST), the time is always 5 hours ahead of me. I confirmed that in my app, Python’s date/time functions return different values 5 hours apart based on whether they’re called from a form (i.e. the user’s browser) or in a server module. Is there a way for all date/times to be consistent, or will I simply have to make sure that all date/times I’m computing are done in a form?
We noticed the same thing. Sooner or later, you may need to use timestamps to determine the order or sequence in which events occurred. (E.g., to settle a dispute.) To that end, you are right to standardize on a single time zone. But it’s also important to eliminate Daylight Saving effects.
Not so long ago, thanks to DST, we had a morning with two separate times named “01:30”. Which came first? Will your database entries tell you? Reliably?
To avoid this problem, we are standardizing on UTC. It is unaffected by DST. I suspect that Server Modules use UTC.
Docs say
Any naive datetime.datetime objects that are transferred between client and server (or vice versa) will have a timezone explicitly set before being sent. When leaving the server, they will be set to UTC, and when leaving the client they will be set to the timezone of the user’s browser.
class datetime.datetime
A combination of a date and a time. Attributes: year, month, day, hour, minute, second, microsecond, and tzinfo.
So you should be able to convert all of them to UTC – or to whatever standard you choose.
Hi folks,
Anvil actually takes extreme care with Python datetime
objects, because dealing with timezones is such a minefield. Here’s how it works:
- Any timezone-aware
datetime
object retains its timezone when transferred in any direction between client, server and Data Tables. - Any naïve
datetime
object that is transferred between client and server gets automatically ‘stamped’ with the timezone of the place where it was created before it is transferred. This means thatdatetime
objects generated on the client get the timezone of the browser, while those generated on the server are stamped with the timezone of the server, which is always guaranteed to be UTC (not UK time, which is different in the summer).
These deceptively simple rules mean that you can always compare datetime
objects, no matter where they were created and no matter how much you’ve moved them around or stored them in the DB.
You can explictly create timezone-aware datetime
objects if you wish, using helper classes from the anvil.tz
module:
import anvil.tz
naive_local = datetime.now()
aware_local = datetime.now(anvil.tz.tzlocal())
naive_utc = datetime.utcnow()
aware_utc = datetime.now(anvil.tz.tzutc()) # note: NOT datetime.utcnow()
aware_custom = datetime(2017,11,16,23,45,15,0, anvil.tz.tzoffset(hours=3))
print "Naive local: %s" % naive_local
print "Aware local: %s" % aware_local
print "Naive UTC: %s" % naive_utc
print "Aware UTC: %s" % aware_utc
print "Aware custom: %s" % aware_custom
I hope that helps!
Thanks for the explanation Ian!
anvil.tz
?
What is it?
Is it documented?
For some reason tz thinks I am in UTC.
print(“You local time zone is”)
print(anvil.tz.tzlocal())
output:
You local time zone is
tzlocal(0.0 hour offset)
I’m in California. Thoughts?
Are you running it in Server Modules or in the browser? Server Modules always run in UTC!
Hi @meredydd! It’s a client function but we were tryin’ to do some clever refactoring and imported it to the server library. D’oh!
#toocleverformyowngood
Having just spent the last few hours dealing with the pains of trying to get all my datetimes consistent. I found this particularly helpful:
Many of the time zone functions (such as pyzt and timezone) do not seem to be very available for a free Anvil account, which made it difficult for me to print EST to the UI when UTC or naive was stored in the data tables. My recommendation for others is to make everything time zone aware by only pulling datetimes from the client (for example: do not run datetime.now(anvil.tz.tzlocal()) on the server and especially do not run datetime.now()). Then, when you want to store the datetime in a data table, transfer this to the server and add it. It is automatically stamped with the local time zone info. This seems to be the only way everything works consistently for me without a huge headache.