SQLAlchemy DateTime timezone
SQLAlchemy的
请注意datetime.datetime.utcnow如何不能很好地与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import sqlalchemy as sa from sqlalchemy.sql import select import datetime metadata = sa.MetaData('postgres://user:pass@machine/db') data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.utcnow) ) metadata.create_all() engine = metadata.bind conn = engine.connect() result = conn.execute(data_table.insert().values(id=1)) s = select([data_table]) result = conn.execute(s) row = result.fetchone() |
(1, datetime.datetime(2009, 1, 6, 0, 9, 36, 891887))
1 | row[1].utcoffset() |
datetime.timedelta(-1, 64800) # that's my localtime offset!!
1 | datetime.datetime.now(tz=pytz.timezone("US/Central")) |
datetime.timedelta(-1, 64800)
1 | datetime.datetime.now(tz=pytz.timezone("UTC")) |
datetime.timedelta(0) #UTC
即使我将其更改为显式使用UTC:
...
1 2 3 4 5 6 | data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset() |
...
datetime.timedelta(-1, 64800) # it did not use the timezone I explicitly added
或者,如果我放下
...
1 2 3 4 5 6 | data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset() is None |
...
True # it didn't even save a timezone to the db this time
http://www.postgresql.org/docs/8.3/interactive/datatype-datetime.html#DATATYPE-TIMEZONES
All timezone-aware dates and times are stored internally in UTC. They are converted to local time in the zone specified by the timezone configuration parameter before being displayed to the client.
用postgresql存储它的唯一方法是分别存储它。
这个问题的答案给出了一个解决方案:
您可以通过将所有(日期)时间对象存储在UTC中的数据库中,然后将所得的简单日期时间对象转换为可检索的已知日期时间对象,来规避这一问题。
唯一的缺点是您会丢失时区信息,但是无论如何,最好将日期时间对象存储在utc中。
如果您关心时区信息,我会将其分开存储,并且仅在最后一个可能的情况下(例如,在显示之前)将utc转换为本地时间
也许您根本不需要关心,可以使用运行程序的计算机或用户的浏览器(如果是网络应用程序)使用本地时区信息。