一、python对时间的定义
1.1 aware和naive
python doc里面有段这样的描述,将日期时间分为两种类型“aware”和“naive”。navie不携带timezone时区信息,所以navie的时间格式在理解上会有歧义。
Aware and Naive ObjectsDate and time objects may be categorized as “aware” or “naive” depending on whether or not they include timezone information. A naive object does not contain enough information to unambiguously locate itself relative to other date/time objects.
Python在这两个类型定义了3种日期时间格式
- struct_time (naive)
- POSIX (aware)
- daattime (naive or aware)
因为naive无法感知时区信息,所以naive时间格式,按照使用习惯,我们会有naive local时区和naive UTC标准时区的分类。
进一步会分为这6种datetime:
- struct_time (local)
- struct_time (UTC)
- POSIX (aware)
- Aware datetime (进一步可分为Python2和Python3写法)
- Navie datetime (local)
- Navie datetime (UTC)
类型 | 写法 |
struct_time (local) | time.localtime() |
struct_time (UTC) | time.gmtime() |
POSIX | time.time() |
Aware datetime (Python2) | datetime.datetime.now(pytz.timezone('UTC')) |
Aware datetime (Python3) | datetime.datetime.now(datetime.timezone.utc) |
Naive datetime (local) | datetime.datetime.now() |
Naive datetime (UTC) | datetime.datetime.utcnow() |
注意到Aware datetime (Python2) 的写法,因为Python2的datetime缺少timezone,所以需要安装第三方库来支持。
python2 -m pip install pytz tzlocal
1.2 struct_time和POXIS时间戳
struct_time和POSIX时间戳的表达如下:
import os,time
os.environ['TZ'] = 'Asia/Shanghai'
time.tzset()
print(time.localtime()) # struct time(local)
print(time.gmtime()) # struct time(UTC)
print(time.time()) # POSIX
1.3 datetime
接下来看下datetime库是怎么表达时间的。
import os,time
os.environ['TZ'] = 'Asia/Shanghai'
time.tzset()
import datetime
print(datetime.datetime.now(datetime.timezone.utc)) # Aware datetime(Python3)
print(datetime.datetime.now()) # Naive datetime(local)
print(datetime.datetime.utcnow()) # Naive datetime(UTC)
二、使用datetime库
datetime提供的常用操作包括:
2.1 datetime对象的序列化和反序列化
datetime有两个函数:strptime用来将日期字符串反序列化成datetime对象;strftime用来按照一定的格式序列化生成日期字符串。
举例来说:
from datetime import datetime
data = datetime.strptime("2024-1-21_22:01:02", "%Y-%m-%d_%H:%M:%S")
print(data.strftime("%Y%m%d %H:%M:%S"))
print(datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))
2.2 获取当前时间
from datetime import datetime
print(datetime.now())
print(datetime.now().isoformat())
print(datetime.now().isocalendar())
print(datetime.today())
print(datetime(2024, 1, 21, 22, 1, 2, 100999))
print(datetime.date(*map(int, "2024-1-21".split('-'))))
2.3 时间运算
from datetime import datetime,timedelta
print(datetime.today())
print(datetime.today() + timedelta(days=1))
2.4 时区
from datetime import datetime,timedelta,timezone
print(datetime.today())
print(datetime.today().replace(tzinfo=timezone.utc))
print(datetime.today().replace(tzinfo=timezone(timedelta(hours=8))))
三、各种time类型的互相转换
Row -> Col | POSIX | struct_time(local) | struct_time(UTC) | Naive datetime(local) | Naive datetime(UTC) | Aware datetime(Py2) | Aware datetime(Py3) |
POSIX | - | time.localtime(x) | time.gmtime(x) | datetime.datetime.fromtimestamp(x) | datetime.datetime.fromtimestamp(x) | datetime.datetime.fromtimestamp(x,pytz.timezone('UTC')) | datetime.datetime.fromtimestamp(x,datetime.timezone.utc) |
struct_time(local) | time.mktime(x) | - | - | datetime.datetime(*x[:6]) | - | - | - |
struct_time(UTC) | calendar.timegm(x) | - | - | - | datetime.datetime(*x[:6]) | datetime.datetime(*x[:6], tzinfo=pytz.timezone('UTC')) | datetime.datetime(*x[:6], tzinfo=datetime.timezone.utc) |
Naive datetime(local) | - | - | - | - | - | x.replace(tzinfo=tzlocal.get_local_zone()) | x.astimezone() |
Naive datetime(UTC) | calendar.timegm(x.utctimetupe()) | - | x.utctimetupe() | - | - | x.replace(tzinfo=pytz.timezone('UTC')) | x.replace(tzinfo=pytz.timezone.utc) |
Aware datetime(Py2) | calendar.timegm(x.utctimetupe()) | - | x.utctimetupe() | x.astimezone(tzlocal.get_localzone()).replace(tzinfo=None) | x.astimezone(pytz.timezone('UTC')).replace(tzinfo=None) | - | - |
Aware datetime(Py3) | calendar.timegm(x.utctimetupe()) | - | x.utctimetupe() | x.astimezone().replace(tzinfo=None) | x.astimezone(pytz.timezone.utc).replace(tzinfo=None) | - | - |