最近遇到不同时区时间转换成时间戳的问题,总结datetime模块常用的方法:
一、常见用法:
1. datetime表示的时间需要时区信息才能确定指定时间;
2. 一般利用时间戳存储时间,timestamp的值和时区无关。
3. 不同时区转换:获取正确的时区->时区信息tzinfo为None:强制设置时区(基准时间)-> astimezone()方法转换任意时区
from datetime import datetime, timedelta, timezone
print(datetime.now()) // 获取当前的日期+时间: 2021-11-11 15:58:35.846131
print(datetime(2021, 11, 11, 14, 58, 59)) // 获取指定日期时间: 2021-11-11 14:58:59
# epoch time:1970年1月1日 00:00:00 UTC+00:00时区的时刻,当前时间相对于epoch time的秒数,为timestamp
print(datetime.now().timestamp()) // 当前时间的时间戳
# timestamp 的值与时区没有关系, 北京是东8区:UTC+8:00
t = datetime.now().timestamp()
print("本地时间:{0}".format(datetime.fromtimestamp(t))) // 本地时间(本地设置时区对应时间):2021-11-11 15:58:35.846131
print("UTC时间:{0}".format(datetime.utcfromtimestamp(t))) // UTC+0:00时间:2021-11-11 07:58:35.846131
# str - datetime格式转换,时间格式: %Y-%m-%d %H:%M:%S
print("str转datetime: {0}".format(datetime.strptime('2021-11-11 15:41:59', '%Y-%m-%d %H:%M:%S'))) // str转datetime: 2021-11-11 15:41:59
print("datetime转str: {0}".format(datetime.now().strftime('%Y%m%d %H:%M:%S'))) // datetime转str: 20211111 15:58:35
# datetime加减:timedelta
print("datetime加1D1H: {0}".format(datetime.now() + timedelta(days=1, hours=1))) // datetime加1D1H: 2021-11-12 16:58:35.850656
print("datetime减1D: {0}".format(datetime.now() - timedelta(days=1))) // datetime减1D: 2021-11-10 15:58:35.850656
# 获取utc时间
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc) // utc时间:2021-11-11 07:58:35.850656+00:00
# utc时间(str格式)转北京时区时间
# 不同时区转换关键:获取正确的时区->强制设置时区(基准时间)-> astimezone()方法转换任意时区
# 为什么强制设置时区:一个datetime类型有一个时区属性tzinfo,默认为None, str格式转成datetime tzinfo=None
a = utc_dt.strftime('%a, %d %b %Y %H:%M:%S GMT') // str类型: Thu, 11 Nov 2021 07:58:35 GMT
gmt_time = datetime.strptime(a, '%a, %d %b %Y %H:%M:%S GMT') // str转datetime类型
# 强制设置时区为UTC+0:00
utc_time = gmt_time.replace(tzinfo=timezone.utc) // 时区属性tzinfo=None, 需要强制datetime设置一个时区,否则无法区分是哪个时区
# 转成北京时区
print(utc_time.astimezone(timezone(timedelta(hours=8)))) // 北京时区:2021-11-11 15:58:35+08:00
二、datetime包含的属性:
datetime
"""datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
The year, month and day arguments are required. tzinfo may be None, or an
instance of a tzinfo subclass. The remaining arguments may be ints.
"""
__slots__ = date.__slots__ + time.__slots__
def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
microsecond=0, tzinfo=None, *, fold=0):
if (isinstance(year, (bytes, str)) and len(year) == 10 and
1 <= ord(year[2:3])&0x7F <= 12):
# Pickle support
if isinstance(year, str):
try:
year = bytes(year, 'latin1')
except UnicodeEncodeError:
# More informative error message.
raise ValueError(
"Failed to encode latin1 string when unpickling "
"a datetime object. "
"pickle.load(data, encoding='latin1') is assumed.")
self = object.__new__(cls)
self.__setstate(year, month)
self._hashcode = -1
return self
year, month, day = _check_date_fields(year, month, day)
hour, minute, second, microsecond, fold = _check_time_fields(
hour, minute, second, microsecond, fold)
_check_tzinfo_arg(tzinfo)
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
self._hour = hour
self._minute = minute
self._second = second
self._microsecond = microsecond
self._tzinfo = tzinfo
self._hashcode = -1
self._fold = fold
return self
参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017648783851616
https://docs.python.org/zh-cn/3/library/datetime.html#timezone-objects