建议阅读本文时,先阅读前置知识,有助于更好的理解本文

计算机常见时间术语解释

一、有效类型

  • datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
  • datetime.date(year, month, day)
  • datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
  • datetime.timedelta((days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)):时间之间的差值
  • datetime.tzinfo:处理时区、夏令时,它是一个抽象基类,不可以被实例化
  • datetime.timezone(offset, name=None):是tzinfo的子类,表示相对于世界标准时间(UTC)的偏移量

二、取值范围

  • datetime.MINYEAR <= year <= datetime.MAXYEAR
  • 1 <= month <= 12
  • 1 <= day <= 指定年月的天数
  • 1 <= hour < 24
  • 1 <= minute < 60
  • 1 <= second < 60
  • 1 <= microsecond < 1000000
1秒=1000毫秒;1毫秒=1000微秒

三、导入模块

from datetime import datetime
from datetime import date
from datetime import time
from datetime import timedelta
from datetime import tzinfo
from datetime import timezone

为了区分datetime.datetime()对象和datetime模块本身,不在代码写法上混淆,以下代码中的datetime指的均为datetime.datetime()

下文中,<datetime><date><time>指的是实例化的对象,即具体的日期和时间。

文中的tzinfo/timezone看不懂可以先忽略,或者参考末尾的两章关于tzinfo/timezonetimedelta的专述

四、简单型和感知型对象

  • 简单型:不包含时区信息tzinfo
  • 感知型:包含时区信息tzinfo

五、获取当前日期时间

  • datetime.today():本地日期和时间(其中tzinfo为None)
  • date.today():只包含日期
  • datetime.now(tz=None):日期和时间,tz是tzinfo的一个实例,返回的日期和时间会被转换到tz时区
  • datetime.utcnow():返回UTC日期和时间,相当于datetime.now(timezone.utc),但是前者返回的是简单型对象,后者返回的是感知型对象

例子:

>>> datetime.today()
datetime.datetime(2024, 10, 10, 16, 5, 10, 876866)
>>> datetime.utcnow()
datetime.datetime(2024, 10, 10, 8, 5, 54, 101824)
>>> datetime.now(timezone.utc)
datetime.datetime(2024, 10, 10, 8, 12, 9, 406672, tzinfo=datetime.timezone.utc)

六、获取日期时间实例属性

返回一个日期时间的具体某项:

  • <datetime>.year/month/day/hour/minute/second/microsecond/tzinfo
  • <date>.year/month/day
  • <time>.hour/minute/second/microsecond/tzinfo
  • <datetime>.date()/time():返回日期/时间部分,tzinfo为None
  • <datetime>.timetz():返回带tzinfo的时间
  • <datetime>.utcoffset():返回时区差值
  • <datetime>.tzname():返回时区名称

同时,<date><time>还能结合:

  • datetime.combine(date, time, tzinfo=time.tzinfo)

返回星期:

  • <datetime>/<date>.weekday():从0开始
  • <datetime>/<date>.isoweekday():从1开始

返回Unix时间戳:

  • <datetime>.timestamp()

七、Unix时间戳转日期时间对象

  • datetime.fromtimestamp(timestamp, tzinfo=None)
  • date.fromtimestamp(timestamp)
  • datetime.utcfromtimestamp(timestamp):转UTC日期和时间

最后一个相当于datetime(1970,1,1,tzinfo=timezone.utc)+timedelta(seconds=timestamp)

例子:

>>> datetime.fromtimestamp(1728465673)
datetime.datetime(2024, 10, 9, 17, 21, 13)
>>> datetime.utcfromtimestamp(1728465673)
datetime.datetime(2024, 10, 9, 9, 21, 13)

八、字符串转日期时间对象

1.ISO 8601格式字符串

  • datetime.fromisoformat(date_string)
  • date.fromisoformat(date_string)
  • time.fromisoformat(time_string)

注意这里字符串内的时间格式必须是ISO8601格式,如:

  • YYYY-MM-DDThh:mm:ss(.SSS/.ffffff)(X/±hh:mm)、YYYYMMDDThhmmss (3.11之后)
  • YYYY-MM-DD、YYYYMMDD (3.11之后)
  • hh:mm:ss(.SSS/.ffffff)(X/±hh:mm)、hhmmss (3.11之后)
.SSS表示毫秒,.ffffff表示微秒
X表示时区,这种表示法在3.11后才可用;日期时间格式的组合比较灵活,T可以用空格代替,前部分日期的格式可以和后部分时间的格式产生多种组合。

例子:(Python 3.11及以上版本生效)

>>> datetime.fromisoformat('2024-10-24 09:52:10.562Z')
datetime.datetime(2024, 10, 24, 9, 52, 10, 562000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('20241024 095210')
datetime.datetime(2024, 10, 24, 9, 52, 10)

2.格式化字符串

  • datetime.strptime(date_string, format)
datetime模块的date和time没有strptime方法,但是time模块有time.strptime()方法(后期会出time模块教程)

format格式表:

指示符含义示例
\%Y、\%y4位年、2位年2024、24
\%m、\%B、\%b2位月、月完整名称、月缩写10、October、Oct
\%d2位日10
\%H、\%I2位时(24小时制、12小时制)16、04
\%M2位分21
\%S2位秒43
\%f6位微秒781564
\%zUTC偏移量(±HHMM[SS[.ffffff]])(空), +0000,-0400
\%:zUTC偏移量(±HH:MM[:SS[.ffffff]])(空), +00:00,-04:00
\%Z时区名称UTC
\%A、\%a星期完整名称、星期缩写Thursday、Thu
\%w、\%u星期数(从0开始、从1开始)2、3
\%p输出AM或PMPM
\%j3位日序号001
\%X只输出时间16:23:00

例子:

>>> date_string='10/24 09:52:10'
>>> datetime.strptime(f'2024/{date_string}','%Y/%m/%d %H:%M:%S')
datetime.datetime(2024, 10, 24, 9, 52, 10)

九、日期时间对象转格式化字符串

1.格式化输出

  • <datetime>.strftime(format):等价于<datetime>.__format__(format)
  • <date>.strftime(format):等价于<date>.__format__(format)
  • <time>.strftime(format):等价于<time>.__foramt__(format)
format格式表同上

另外,还有一种用法:<str>.format(),例子:

d = datetime.date.today()
# 2024-10-10
text = 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
# 'The day is 11, the month is March.'

2.ISO 8601格式化

  • <datetime>.isoformat(sep='T', timespec='auto'):返回YYYY-MM-DDThh:mm:ss.ffffff
  • <date>.isoformat():返回YYYY-MM-DD
  • <time>.isoformat(timespec='auto'):返回hh:mm:ss.ffffff
sep表示日期和时间之间的分隔符

timespec取值:

  • auto:如果microsecond不为0,则返回(YYYY-MM-DDT)hh:mm:ss.ffffff,否则返回(YYYY-MM-DDT)hh:mm:ss
  • hours:返回(YYYY-MM-DDT)hh
  • minutes:返回(YYYY-MM-DDT)hh:mm
  • seconds:返回(YYYY-MM-DDT)hh:mm:ss
  • milliseconds:返回(YYYY-MM-DDT)hh:mm:ss.SSS(被截断至毫秒,而不是舍入)
  • microseconds:返回(YYYY-MM-DDT)hh:mm:ss.ffffff
如果带有时区信息,还会返回时区信息±hh:mm(:ss(.ffffff))

3.字符串化

  • <datetime>.__str__():等价于str(<datetime>)<datetime>.isoformat(' '),返回YYYY-MM-DD hh:mm:ss.ffffff
  • <date>.__str__():等价于str(<date>)<date>.isoformat(),返回YYYY-MM-DD
  • <time>.__str__():等价于str(<time>)<time>.isoformat(),返回hh:mm:ss

十、参数替换

  • <datetime>.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo)
  • <date>.replace(year=self.year, month=self.month, day=self.day)
  • <time>.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo)

例子:

d = date(2024, 9, 25)
d = d.replace(day=26)
print(d)
# datetime.date(2024, 9, 26)

十一、运算

1.timedelta

  • <timedelta> = <timedelta> ± <timedelta>
  • <timedelta> = <timedelta> * <int>
  • <float> = <timedelta> / <timedelta>
  • -<timedelta>:timedelta内所有单位符号取反
  • abs(<timedelta>)

2.datetime

  • <datetime> = <datetime> ± <timedelta>
  • <timedelta> = <datetime> ± <datetime>
  • <datetime> == <datetime>
  • <datetime> != <datetime>
  • <datetime> < <datetime>
  • <datetime> > <datetime>
  • <datetime> <= <datetime>
  • <datetime> >= <datetime>
两个能进行比较的前提是均为简单型或者感知型;如果两个的tzinfo不同,则两个会首先被转换为UTC再进行比较;先发生的是小值

3.date

  • <date> = <date> ± <timedelta>
  • <timedelta> = <date> - <date>
  • <date> == <date>
  • <date> != <date>
  • <date> < <date>
  • <date> > <date>
  • <date> <= <date>
  • <date> >= <date>

4.time

  • <time>不支持算术运算
  • <time> == <time>
  • <time> != <time>
  • <time> < <time>
  • <time> > <time>
  • <time> <= <time>
  • <time> >= <time>

十二、timedelta

datetime.timedelta((days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0))

timedelta是两个datetimetime之间的差值

只有dayssecondsmicroseconds存储在内部,其他单位则自动向这三个单位转换

>>> delta = timedelta(
...    days=50,
...    seconds=27,
...    microseconds=10,
...    milliseconds=29000,
...    minutes=5,
...    hours=8,
...    weeks=2
...)
>>> delta
# 只保留日期、秒和微秒
# datetime.timedelta(days=64, seconds=29156, microseconds=10)

实例属性

  • <timedelta>.days/seconds/microseconds:返回<timedelta>的天数、秒数、微秒数
  • <timedelta>.total_seconds():返回的总秒数

十三、tzinfo和timezone

  • 这两个类都是用来处理时区问题的
  • tzinfo是一个抽象基类,也就是不能直接实例化
  • timezonetzinfo的子类,是tzinfo的具体实现
  • 代表UTC的timezone常量:datetime.UTC/timezone.utc,即timezone(timedelta(0))
datetime.UTC中的datetime指的是datetime模块本身

timezone实例

datetime.timezone(offset, name=None)
offset表示本地时间与UTC的差值;name将被作为<datetime>.tzname()的返回值

构造timezone

>>> tz = timezone(timedelta(hours=8), "Beijing")
>>> tz
datetime.timezone(datetime.timedelta(seconds=28800), 'Beijing')

构造带时区的datetime

>>> dt = datetime(2024, 10, 25, tzinfo=tz)
>>> dt
datetime.datetime(2024, 10, 25, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), 'Beijing'))
>>> dt.tzname()
'Beijing'
>>> dt.utcoffset()
datetime.timedelta(seconds=28800)

发表评论

本站总访问量