python - дата и время с часовым поясом
В приведенном ниже коде я вычисляю эпоху начала и начала текущей дневной эпохи.
import time
import pytz
from datetime import datetime
tz1 = pytz.timezone('CST6CDT')
utc = pytz.timezone('UTC')
now = pytz.UTC.localize(datetime.utcnow())
now_tz = now.astimezone(tz1)
print now_tz
print now_tz.strftime('%s')
begin_day = now_tz.replace(hour=0, minute=0, second=0)
print begin_day
print begin_day.strftime('%s')
печатать заявления:
2012-08-28 13:52:21.595718-05:00
1346187141
2012-08-28 00:00:00.595718-05:00
1346137200
Преобразование эпох в метку времени с часовым поясом CDT: 1346187141 - 28 августа 2012 г. 15:52:21, 1346137200 - 28 августа 2012 г. 02:00:00
Я бы хотел, чтобы вторая эпоха была началом дня, но сейчас уже 2 часа ночи. Похоже, что он по-прежнему использует местный часовой пояс PST при преобразовании в эпоху.
Что я делаю неправильно? или это можно сделать по другому?
Спасибо!
3 ответа
ПРИМЕЧАНИЕ: мой ответ совершенно неверный. (Я хотел бы удалить его, но не могу сделать это, пока флаг принятия не будет удален.)
Пожалуйста, смотрите ответ JFSebastian.
Вот код, демонстрирующий значение now_tz
для которых наши два метода дают разные результаты.
import calendar
import pytz
import datetime as dt
tz1 = pytz.timezone('US/Eastern')
utc = pytz.timezone('UTC')
now = utc.localize(dt.datetime(2002, 10, 28), is_dst=None)
now_tz = now.astimezone(tz1)
now_epoch = calendar.timegm(now_tz.utctimetuple())
begin_day = tz1.normalize(now_tz.replace(hour=0, minute=0, second=0))
midnight = tz1.localize(dt.datetime.combine(now_tz, dt.time(0, 0)), is_dst=None)
if begin_day != midnight:
print(begin_day)
# 2002-10-27 01:00:00-04:00 # my result -- is not midnight
print(midnight)
# 2002-10-27 00:00:00-04:00 # J.F.Sebastian's result is correct
(Оригинальный ответ отредактирован)
Чтобы преобразовать дату и время с часовым поясом в эпоху (POSIX timestamp):
from datetime import datetime
import pytz
tz = pytz.timezone('CST6CDT')
# a datetime with timezone
dt_with_tz = tz.localize(datetime(2012, 8, 28, 19, 33, 50), is_dst=None)
# get timestamp
ts = (dt_with_tz - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1346200430.0
Это как datetime.timestamp
метод реализован для часовых поясов datetime
объекты в Python 3.
Чтобы получить "сейчас эпоху":
from datetime import datetime
now_epoch = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
Или (при условии time
использует эпоху POSIX):
import time
now_epoch = time.time()
Получение "начала текущей дневной эпохи" является более сложным, потому что текущий день может отличаться в разных часовых поясах:
from datetime import datetime, time
import pytz
tz = pytz.timezone('CST6CDT')
# get current date in given timezone
today = datetime.now(tz).date()
# -> datetime.date(2013, 6, 22)
# get beginning of current day in given timezone as a datetime with timezone
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
# -> datetime.datetime(2013, 6, 22, 0, 0, tzinfo=<DstTzInfo 'CST6CDT'...>)
# get timestamp
ts = (midnight - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1371877200.0
См. Как я могу получить время UTC "полуночи" для данного часового пояса?,
Чтобы получить "начало текущей дневной эпохи", исходя из даты UTC:
from datetime import datetime, date
# get current date in UTC
utc_date = datetime.utcnow().date()
# -> datetime.date(2013, 6, 23)
# get timestamp
ts = (utc_date - date(1970, 1, 1)).days * 86400
# -> 1371945600
См. Преобразование datetime.date/datetime.datetime в метку времени UTC в Python.
Последняя версия simple-date (версия 0.2 на pypi) будет управлять деталями для вас:
>>> from simpledate import *
>>> now_utc = SimpleDate(tz='UTC')
>>> now_tz = now_utc.convert(tz='CST6CDT')
>>> begin_day = now_tz.replace(hour=0, minute=0, second=0, microsecond=0)
>>> now_utc.timestamp
1371950295.777453
>>> now_tz.timestamp
1371950295.777453
>>> begin_day.timestamp
1371877200.0
мы можем вернуться назад, чтобы проверить временные метки (хотя выше ясно, что переключение часового пояса не изменило эпоху, а переход на начало дня -):
>>> SimpleDate(1371877200.0, tz='CST6CDT')
SimpleDate('2013-06-22 00:00:00.000000 CDT', tz='CST6CDT')
>>> SimpleDate(1371877200.0, tz='UTC')
SimpleDate('2013-06-22 05:00:00.000000 UTC')