基于Python的datetime模块和time模块源码阅读分析
目录
1 前言
最近工作需求上对于datetime模块中的方法调用比较多,有时还要返回指定的格式,以及大小比较等情况。发现使用Python自带的datetime模块可以很好地实现相关需求,但是对于其中的具体实现原理以及相关方法的特性不是很了解,所以决定花点时间来看看datetime模块的源码以及time模块的源码,提高自己以后实现此类需求的工作效率。
一般情况下,我们引用datetime模块相关方式,引用有两种方式:
(1)
import datetime # 此种引用,即包含了datetime模块所有方法,但是引用具体方法时,需要这样写:datetime.date.today(),表示获取今天的日期,要多写一个datetime
(2)
from datetime import datetime, time, timedelta, tzinfo, date # 此种应用,可以看实际需求决定需要应用那个类方法,比如只应用date时,使用date.today()即可获取今天的日期
通过初步阅读datetime模块源码,datetime模块包含五个内部类,分别是:
tzinfo类(表示日期时间的时区)
date类(表示具体日期,精确到天,例如2018-7-22)
time类(表示具体时间,可精确到微秒,例如11:47:23.0001)
timedelta类(可表示具体的时间差,例如一小时时间差为timedelta(hours=1))
datetime类(表示具体日期时间,可理解为date类+time类所有属性和内部方法的结合体,例如:2018-7-22 11:49:30.0001)
注意在看datetime源码时,会发现源码包有一个datetime.pyi文件,通过查找资料得知:每一个模块源码都会有一个对于的.pyi文件,该文件只列出具体的实现方法头部代码和相关参数和返回值说明。例如,给出一篇论文的目录,具体内容可通过目录索引查看具体细节。(PS:资料种说明.pyi表示“存根文件”。)
使用time模块方式,引用方式:
import time
time模块内部只有相关调用方法,源码较少。
2 datetime.pyi源码分步解析
2.1 头部定义源码分析
import sys from time import struct_time # 关于struct_time的具体源码,可见下文详解 from typing import ( AnyStr, Optional, SupportsAbs, Tuple, Union, overload, ClassVar, ) # 请注意其中有多个类型,可能初次见面,不太明白,下面到具体应用会详细说明 if sys.version_info >= (3,): # 此处判断本地Python版本,是否大于3.0.0 _Text = str # 表示_Text代表类型str else: _Text = Union[str, unicode] # 表示_Text可选类型有str和unicode;Union功能是可以结合多个类型,但是如果类型之间有继承关系,只取优先级最高的,即辈份最高的父类 MINYEAR: int # 定义默认的最小年数,为1
MAXYEAR: int # 定义默认的最大年数,为9999
2.2 tzinfo类源码分析
tzinfo:time zone infomation,即时区信息,从该类类名即可知道其作用为限定给定时间的时区参数提供支持。该类的对象实例传递给datetime或者time对象的构造函数,从而输出相应时区的信息,如果不传递则默认输出本地时区的对应时间信息。
class tzinfo: # 下面使用的Optional类型,意思是该变量的具体实际类型或者为None,Optional[X]等同于Union[X, None] # 返回指定datetime对象的所在时区名称,返回值类型为字符串
def tzname(self, dt: Optional[datetime]) -> str: ... # 返回当地时间与UTC(世界统一时间)的偏移量,返回值类型是timedelta类型
def utcoffset(self, dt: Optional[datetime]) -> Optional[timedelta]: ... #dst(daylight saving time,阳光节约时或称夏至时),该方法用于获取夏至时调整量,一般不需要调用
def dst(self, dt: Optional[datetime]) -> Optional[timedelta]: ... # 调整日期(date)和时间(time)数据,在自己的本地时间返回一个等效的日期时间(datetime)。
def fromutc(self, dt: datetime) -> datetime: ... if sys.version_info >= (3, 2): # 当Python版本大于等于3.2.0时, 添加类tzinfo的timezone子类实现 class timezone(tzinfo): """以下用到了一个ClassVar变量,这是一个类变量类型,是Python3.6版本新添加的功能; 网上解析:已添加typing.ClassVar类型构造,来标识类变量。如 **PEP 526**中所述,封装在ClassVar中的一个变量注释暗示着一个给定的属性打算作为一个类变量使用,并且不应该在那个类的实例上设置它。 """
utc: ClassVar[timezone] # 定义的一个类变量,源码中具体实现:timezone.utc = timezone._create(timedelta(0)) min: ClassVar[timezone] # 定义的一个类变量,源码中具体实现:timezone.min = timezone._create(timezone._minoffset) max: ClassVar[timezone] # 定义的一个类变量,源码中具体实现:timezone.max = timezone._create(timezone._maxoffset) # 类timezone的构造函数,用于定义对象时的初始化函数
def __init__(self, offset: timedelta, name: str = ...) -> None: ... # 为该类定义的哈希函数,对象调用该方法,可以返回一个hash值,该对象可以用作字典中的key或集合中的一员
def __hash__(self) -> int: ... _tzinfo = tzinfo # 定义类tzinfo的一个别名,前面加一个下划线,表示该别名只能在当前类内部使用
2.3 date类源码分析
class date: min: ClassVar[date] # date类变量,具体实现:date.min = date(1, 1, 1),表示1年1月1日 max: ClassVar[date] # date类变量,具体实现:date.max = date(9999, 12, 31),表示9999年12月31日 resolution: ClassVar[timedelta] # timedelta类变量,具体实现:date.resolution = timedelta(days=1),表示时长为1天的timedelta类变量 # 构造函数,初始化参数分别为年(year)、月(month)、日(day),返回值类型为None
def __init__(self, year: int, month: int, day: int) -> None: ... """此处先简单说明一下@classmethod装饰器的作用:在类前面加该装饰器,特点就是可以通过类名去调用,但是也必须传递一个参数,一般用cls表示class,表示可以通过类直接调用”””
# 通过传入一个float类型的时间戳值,返回该时间戳对应的日期(date类型,年月日)
@classmethod
def fromtimestamp(cls, t: float) -> date: ... # 返回系统今天的日期,类似fromtimestamp(t=time.time())调用结果
@classmethod
def today(cls) -> date: ... # 参数n为天数,通过给定天数,返回具体的日期(date类型,年月日),从公元1年1月1日开始,即n=1,表示公元1年1月1日
@classmethod
def fromordinal(cls, n: int) -> date: ... """先说一下装饰器@property作用:负责把一个方法变成属性调用的。因此,类对象可以直接调用该方法作为属性使用,例如test_date.year直接返回对象test_date的年份数据””” # date对象对应的年份信息,可作为对象的属性直接调用
@property
def year(self) -> int: ... # date对象对应的月份信息,可作为对象的属性直接调用
@property
def month(self) -> int: ... # date对象对应的天信息,可作为对象的属性直接调用
@property
def day(self) -> int: ... # 返回当前date对象的ctime()样式字符串,例如今天是2018-07-21 星期六,则返回'Sat Jul 21 00:00:00 2018'
def ctime(self) -> str: ... # fmt(format缩写,代表格式)类型为_Text在头部文件代码有定义,该方法依据提供的格式返回对应date对应对象的字符串格式,例如:fmt="%Y-%m-%dT%H:%M:%SZ",返回示例:'2018-07-21T00:00:00Z'
def strftime(self, fmt: _Text) -> str: ... if sys.version_info >= (3,): # 当Python版本大于等于3.0.0
def __format__(self, fmt: str) -> str: ...
else:
def __format__(self, fmt: AnyStr) -> AnyStr: ... # 此处有一个新的类型AnyStr,看源码中具体实现为:AnyStr = TypeVar('AnyStr', bytes, str),表示该类型为str结构类型或者bytes结构类型,附源码中注释: """
Usage::
T = TypeVar('T') # Can be anything
A = TypeVar('A', str, bytes) # Must be str or bytes
"""
# 返回date对象的ISO格式的日期,具体为”yyyy-mm-dd",例如:'2018-07-21'
def isoformat(self) -> str: ... # 返回与time.localtime()兼容的本地时间元组。返回示例:time.struct_time(tm_year=2018, tm_mon=7, tm_mday=21, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=202, tm_isdst=-1)
def timetuple(self) -> struct_time: ... # 返回指定日期,从公元1年1月1日到现在的总天数,例如date(1,2,1).toordinal()=32
def toordinal(self) -> int: ... # 修改初始化date对象中year、month、int属性的值,例如date(2018,7,18).replace(year=2019),则该日期就变成2019年7月18日
def replace(self, year: int = ..., month: int = ..., day: int = ...) -> date: ... # date对象间的大小比较,le表示 <=
def __le__(self, other: date) -> bool: ... # date对象间的大小比较,lt表示 <
def __lt__(self, other: date) -> bool: ... # date对象间的大小比较,ge表示 >=
def __ge__(self, other: date) -> bool: ... # date对象间的大小比较,gt表示 >
def __gt__(self, other: date) -> bool: ... # date对象的加操作,但是添加的值只能是timedelta对象,而不能是date对象
def __add__(self, other: timedelta) -> date: ... # date对象的减操作,但是减去的值只能是timedelta对象,而不能是date对象
@overload # 重载功能装饰器,关于重载的概念可自行网上搜索
def __sub__(self, other: timedelta) -> date: ... #date对象的减操作,但是减去的值只能是date对象
@overload
def __sub__(self, other: date) -> timedelta: ... # date对象的哈希化方法,可以返回当前对象的哈希值
def __hash__(self) -> int: ... #返回当前date对象的星期几数目,例如2018年7月21日星期六,当天的date.today().weekday() = 5。注意:Monday == 0 ... Sunday == 6.所以5代表星期六
def weekday(self) -> int: ... # 返回当前date对象的星期几数目,注意:Monday == 1 ... Sunday == 7.则星期六,就返回6。
def isoweekday(self) -> int: ... # 返回当前date对象的年份、本年份的所在周数、星期几,例如:date(1,2,1).isocalendar()=(1,5,4)表示公元1年2月1日,年份是1,周数是4(公元1年的第4周),星期四
def isocalendar(self) -> Tuple[int, int, int]: ...
2.4 time类源码分析
下述方法有部分和上面date类实现或者意义类似,就大概简单说明,不作详细介绍啦。
class time: min: ClassVar[time] # time类变量,具体实现:time.min = time(0, 0, 0) max: ClassVar[time] # time类变量,具体实现:time.max = time(23, 59, 59, 999999) resolution: ClassVar[timedelta] # timedelta类变量,具体实现:time.resolution = timedelta(microseconds=1) # time类的构造函数,依据参数名即可知道具体参数的实际意义
def __init__(self, hour: int = ..., minute: int = ..., second: int = ..., microsecond: int = ...,
tzinfo: Optional[tzinfo] = ...) -> None: ... # time对象的具体hour属性函数
@property
def hour(self) -> int: ... #time对象的具体minute属性函数
@property
def minute(self) -> int: ... # time对象的具体second属性函数
@property
def second(self) -> int: ... #time对象的具体microsecond(微秒)属性函数
@property
def microsecond(self) -> int: ... #time对象所在时区信息,该属性方法表示该time对象的当前所在时区,默认为None
@property
def tzinfo(self) -> Optional[_tzinfo]: ... if sys.version_info >= (3, 6): # 当Python版本大于等于3.6.0时
#time类对象的 fold属性方法是3.6版本新添加的特性,主要用于区分本地相同两个时刻的分歧,当未出现此类情况时,fold值默认为0
@property
def fold(self) -> int: ... # time类对象间大小比较,le表示 <=
def __le__(self, other: time) -> bool: ... #time类对象间大小比较,lt表示 <
def __lt__(self, other: time) -> bool: ... #time类对象间大小比较,ge表示 >=
def __ge__(self, other: time) -> bool: ... #time类对象间大小比较,gt表示 >
def __gt__(self, other: time) -> bool: ... #可获取time类对象的hash值函数
def __hash__(self) -> int: ... #返回ISO格式化的时间,例如time(1,1,1,1).isoformat()返回:'01:01:01.000001'
def isoformat(self) -> str: ... #返回给定fmt格式的time对象字符串,例如time(1,1,1,1).strftime("%H:%M:%S")返回:'01:01:01'
def strftime(self, fmt: _Text) -> str: ...
if sys.version_info >= (3,): # 当Python版本大于等于3.0.0时
def __format__(self, fmt: str) -> str: ... # 检测fmt类型是否为str
else:
def __format__(self, fmt: AnyStr) -> AnyStr: ... #检测fmt类型是否为AnyStr #返回当前time类对象UTC以东的分钟时区偏移(西区为负),默认为空
def utcoffset(self) -> Optional[timedelta]: ... #返回当前time类对象的时区名称,time类对象初始化默认时区为空,所以此处返回值一般也为空
def tzname(self) -> Optional[str]: ... #返回当前time类对象的UTC偏移量,一般tzinfo为空时,此处返回值也为空,如果tzInfo不为空,没有偏移量则返回0
def dst(self) -> Optional[int]: ... if sys.version_info >= (3, 6): # 当前Python版本大于等于3.6.0时
# 该函数作用为修改time类对象具体属性值,其中有一个fold属性,是3.6版本新添加的属性
def replace(self, hour: int = ..., minute: int = ..., second: int = ...,
microsecond: int = ..., tzinfo: Optional[_tzinfo] = ...,
*, fold: int = ...) -> time: ...
else:
def replace(self, hour: int = ..., minute: int = ..., second: int = ...,
microsecond: int = ..., tzinfo: Optional[_tzinfo] = ...) -> time: ... _date = date # 类date定义的别名,只限本类中使用
_time = time # 类time定义的别名,只限本类中使用
2.5 timedelta类源码分析
timedelta实际意义表示两个日期时间对象之间的差异,例如可作为date对象的运算成员。
class timedelta(SupportsAbs[timedelta]):
min: ClassVar[timedelta] # timedelta类变量,具体实现:timedelta.min = timedelta(-999999999) max: ClassVar[timedelta] # timedelta类变量,具体实现:timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59,microseconds=999999) resolution: ClassVar[timedelta] # timedelta类变量,具体实现:timedelta.resolution = timedelta(microseconds=1) # timedelta的构造函数
def __init__(self, days: float = ..., seconds: float = ..., microseconds: float = ...,
milliseconds: float = ..., minutes: float = ..., hours: float = ...,
weeks: float = ...) -> None: ... # timedelta类对象days(天数)属性方法
@property
def days(self) -> int: ... # timedelta类对象seconds(秒数)属性方法
@property
def seconds(self) -> int: ... # timedelta类对象microseconds(微秒数)属性方法
@property
def microseconds(self) -> int: ... # 获取timedelta类对象总秒数,例如timedelta(hours=1).total_seconds()=3600.0
def total_seconds(self) -> float: ...
# timedelta类对象间相加操作函数
def __add__(self, other: timedelta) -> timedelta: ... # 源码中关于此方法实现:__radd__ = __add__,可看出功能作用和__add__一样
def __radd__(self, other: timedelta) -> timedelta: ... # 返回当前timedelta对象 - other对象值
def __sub__(self, other: timedelta) -> timedelta: ... # 返回other对象 - 当前timedelta对象值
def __rsub__(self, other: timedelta) -> timedelta: ... # 源码中返回:timedelta(-self._days,-self._seconds,-self._microseconds),具体作用不明
def __neg__(self) -> timedelta: ... # 返回当前timedelte对象,例如timedelta(microseconds=1).__pos__(),返回结果:datetime.timedelta(0, 0, 1)
def __pos__(self) -> timedelta: ... # 返回当前timedelte对象绝对值,和__neg__作用相反
def __abs__(self) -> timedelta: ... #返回两个timedelta对象self*other的值
def __mul__(self, other: float) -> timedelta: ... #返回两个timedelta对象乘积,源码实现:__rmul__ = __mul__,可知和__mul__功能一样
def __rmul__(self, other: float) -> timedelta: ... # 除数是timedelta类型的整除运算,向下取整
@overload
def __floordiv__(self, other: timedelta) -> int: ... # 除数是int类型的整除运算,向下取整
@overload
def __floordiv__(self, other: int) -> timedelta: ... if sys.version_info >= (3,): # 当python版本大于等于3.0.0时
# 除数是timedelta类型的除法运算,结果是浮点数
@overload
def __truediv__(self, other: timedelta) -> float: ... # 除数是float类型的除法运算,结果是timedelta类型
@overload
def __truediv__(self, other: float) -> timedelta: ... # 取余运算,返回余数
def __mod__(self, other: timedelta) -> timedelta: ...
# 取整运算和取余运算结合,返回int类型结果是取整结果,返回timedelta类型是取余结果
def __divmod__(self, other: timedelta) -> Tuple[int, timedelta]: ...
else:
# 除法运算,返回结果是float,此处源码未找到具体实现,此处释义是我自己猜的
@overload
def __div__(self, other: timedelta) -> float: ... # 除法运算,返回的结果是timedelta,此处源码中也未找到具体实现代码
@overload
def __div__(self, other: float) -> timedelta: ... # 比较运算,le表示<=
def __le__(self, other: timedelta) -> bool: ... # 比较运算,lt表示<
def __lt__(self, other: timedelta) -> bool: ... # 比较运算,ge表示>=
def __ge__(self, other: timedelta) -> bool: ... # 比较运算,gt表示>
def __gt__(self, other: timedelta) -> bool: ... # timedelta对象取哈希值函数
def __hash__(self) -> int: ...
2.6 datetime类源码分析
datetime类是date类的子类。
class datetime: # TODO: Is a subclass of date, but this would make some types incompatible. min: ClassVar[datetime] #datetime类变量,源码实现:datetime.min = datetime(1, 1, 1) max: ClassVar[datetime] #datetime类变量,源码实现:datetime(9999, 12, 31, 23, 59, 59, 999999) resolution: ClassVar[timedelta] #datetime类变量,源码实现:datetime.resolution = timedelta(microseconds=1) if sys.version_info >= (3, 6): # 此处依据Python版本是否大于等于3.6.0,来区分构造函数 # 注意,此处多了一个fold参数,这是3.6版本新添加的属性,用于区分时间分歧
def __init__(self, year: int, month: int, day: int, hour: int = ...,
minute: int = ..., second: int = ..., microsecond: int = ...,
tzinfo: Optional[tzinfo] = ..., *, fold: int = ...) -> None: ...
else:
def __init__(self, year: int, month: int, day: int, hour: int = ...,
minute: int = ..., second: int = ..., microsecond: int = ...,
tzinfo: Optional[tzinfo] = ...) -> None: ... # 以下包含@property装饰器的属性函数,可依据函数名知道其具体作用,不作详细说明
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def microsecond(self) -> int: ... # 该属性函数,表示datetime类对象的时区信息,默认为空
@property
def tzinfo(self) -> Optional[_tzinfo]: ... # 当python版本大于等于3.6时,添加一个fold属性函数
if sys.version_info >= (3, 6):
@property
def fold(self) -> int: ... # 将一个时间戳格式的数字,转换为datetime类型对象,例如 datetime.fromtimestamp(1582982934.11)=datetime.datetime(2020, 2, 29, 21, 28, 54, 110000)
@classmethod
def fromtimestamp(cls, t: float, tz: Optional[_tzinfo] = ...) -> datetime: ... # 一般情况下和fromtimestamp返回结果一样,如果有UTC时间偏差则会出现结果偏差
@classmethod
def utcfromtimestamp(cls, t: float) -> datetime: ...、 # 返回今天的具体日期时间,例如datetime.today()=datetime.datetime(2018, 7, 22, 9, 59, 6, 907570)
@classmethod
def today(cls) -> datetime: ... # 传入具体天数,返回当前天数的从公元1年1月1日开始计算后的日期时间
@classmethod
def fromordinal(cls, n: int) -> datetime: ... # 返回当前系统时间戳对应的日期时间,例如:datetime.now()=datetime.datetime(2018, 7, 22, 10, 3, 21, 38726)
@classmethod
def now(cls, tz: Optional[_tzinfo] = ...) -> datetime: ... #返回当前系统UTC时间戳对应的日期时间
@classmethod
def utcnow(cls) -> datetime: ...
if sys.version_info >= (3, 6): # 依据Python版本是否大于等于3.6,定义combine函数
@classmethod
def combine(cls, date: date, time: time, tzinfo: Optional[_tzinfo] = ...) -> datetime: ...
else:
@classmethod
def combine(cls, date: date, time: time) -> datetime: ... # 依据fmt格式,返回指定格式的datetime时间字符串
def strftime(self, fmt: _Text) -> str: ...
if sys.version_info >= (3,): # 此处依据Python版本是否大于等于3.0来初始化__format__函数
def __format__(self, fmt: str) -> str: ...
else:
def __format__(self, fmt: AnyStr) -> AnyStr: ... # 返回从公元1年1月1日到当前datetime对象所代表日期间的总天数,例如:datetime(2,1,1,1,1,1,1).toordinal() = 366
def toordinal(self) -> int: ... # 返回当前日期的time_struct格式的结果
def timetuple(self) -> struct_time: ... if sys.version_info >= (3, 3):
# 返回当前日期对象所对应的时间戳结果
def timestamp(self) -> float: ... # 返回当前日期UTC的time_struct格式的结果
def utctimetuple(self) -> struct_time: ... # 返回当前日期时间对象的具体日期,例如datetime.today().date()=datetime.date(2018, 7, 22)
def date(self) -> _date: ... # 返回当前日期时间对象的具体时间,例如datetime.today().time()=datetime.time(10, 15, 58, 933266)
def time(self) -> _time: ... # 返回当前日期时间对象的具体时间,其中包含了该时间的时区信息,一般为空
def timetz(self) -> _time: ... # 依据版本判断,定义不同的replace覆盖函数
if sys.version_info >= (3, 6):
def replace(self, year: int = ..., month: int = ..., day: int = ..., hour: int = ...,
minute: int = ..., second: int = ..., microsecond: int = ..., tzinfo:
Optional[_tzinfo] = ..., *, fold: int = ...) -> datetime: ...
else:
def replace(self, year: int = ..., month: int = ..., day: int = ..., hour: int = ...,
minute: int = ..., second: int = ..., microsecond: int = ..., tzinfo:
Optional[_tzinfo] = ...) -> datetime: ... # 依据版本判断,返回包含时区信息的datetime类型值,例如:datetime.today().astimezone()=datetime.datetime(2018, 7, 22, 10, 51, 1, 6604, tzinfo=datetime.timezone(datetime.timedelta(0, 28800), 'CST'))
if sys.version_info >= (3, 3):
def astimezone(self, tz: Optional[_tzinfo] = ...) -> datetime: ...
else:
def astimezone(self, tz: _tzinfo) -> datetime: ... # 返回ctime格式的datetime类型的字符串值,例如:datetime.today().ctime()='Sun Jul 22 10:53:43 2018'
def ctime(self) -> str: ... # 依据Python版本不同,返回isoformat格式的datetime类型的字符串值,例如:datetime.today().isoformat()='2018-07-22T10:55:11.618810'
if sys.version_info >= (3, 6):
def isoformat(self, sep: str = ..., timespec: str = ...) -> str: ...
else:
def isoformat(self, sep: str = ...) -> str: ... # 返回指定date_string日期时间的format格式的datetime类型,例如:datetime.strptime("2017-10-13 16:00:00", "%Y-%m-%d %H:%M:%S")=datetime.datetime(2017, 10, 13, 16, 0)
@classmethod
def strptime(cls, date_string: _Text, format: _Text) -> datetime: ... # 返回datetime对象的时区UTC偏差,一般情况下为空
def utcoffset(self) -> Optional[timedelta]: ... # 返回datetime对象的具体时区名称,一般情况下为空
def tzname(self) -> Optional[str]: ... # 返回当前datetime对象的DST偏差,一般情况下为空
def dst(self) -> Optional[int]: ... # 比较运算,le表示 <=
def __le__(self, other: datetime) -> bool: ... # 比较运算,lt表示 <
def __lt__(self, other: datetime) -> bool: ... # 比较运算,ge表示 >=
def __ge__(self, other: datetime) -> bool: ... # 比较运算,gt表示 >
def __gt__(self, other: datetime) -> bool: ... # 加运算
def __add__(self, other: timedelta) -> datetime: ... #减运算,参数类型为datetime,返回值类型为timedelta
@overload
def __sub__(self, other: datetime) -> timedelta: ... #减运算,参数类型为timedelta,返回值类型为datetime
@overload
def __sub__(self, other: timedelta) -> datetime: ... # 可返回datetime类对象的哈希值
def __hash__(self) -> int: ... # 返回当前datetime类对象的工作日(即为星期几),注意:Monday == 0 ... Sunday == 6.
def weekday(self) -> int: ... # 返回当前datetime类对象的工作日(即为星期几),注意:Monday == 1 ... Sunday == 7.
def isoweekday(self) -> int: ... # 返回当前datetime类对象的年份、本年份的所在周数、星期几
def isocalendar(self) -> Tuple[int, int, int]: ...
2.7 格式化字符串
datetime、date、time 都提供了 strftime() 方法,该方法接收一个格式字符串,输出日期时间的字符串表示。支持的转换格式如下:
字符 |
含义 |
例子 |
%a |
英文星期的简写 |
Sun, Mon, …, Sat |
%A |
英文星期的全拼 |
Sunday, Monday, …, Saturday |
%w |
星期几,星期天为0,星期六为6 |
0, 1, …, 6 |
%d |
这个月的第几天,以0填充的10进制 |
01, 02, …, 31 |
%b |
月份英文简写 |
Jan, Feb, …, Dec |
%B |
月份英文全拼 |
January, February, …, December |
%m |
月份数,以0填充的10进制 |
01, 02, …, 12 |
%y |
不带世纪的年份 |
00, 01, …, 99 |
%Y |
带有世纪的年份 |
1970, 1988, 2001, 2013 |
%H |
24小时制的小时数 |
00, 01, …, 23 |
%I |
12小时制的小时数 |
01, 02, …, 12 |
%p |
AM或者PM |
AM, PM |
%M |
分钟 |
00, 01, …, 59 |
%S |
秒数 |
00, 01, …, 59 |
%f |
微秒 |
000000, 000001, …, 999999 |
%z |
与utc时间的间隔 |
(), +0000, -0400, +1030 |
%Z |
时区 |
(), UTC, EST, CST |
%j |
当年的第几天 |
001, 002, …, 366 |
%U |
当年的第几周(星期天作为周的第一天) |
00, 01, …, 53 |
%W |
当年的第几周(星期一作为周的第一天) |
00, 01, …, 53 |
%c |
日期时间的字符串表示 |
Tue Aug 16 21:30:00 1988 |
%X |
时间字符串表示 |
21:30:00 |
%x |
日期字符串表示 |
08/16/88 |
%% |
相当于转意等于一个% |
% |
3 time模块time.pyi源码解析
先说一下struct_time结构的返回参数:
struct_time元组。这种结构具有如下属性:
序号 |
属性 |
值 |
0 |
tm_year |
2008 |
1 |
tm_mon |
1 到 12 |
2 |
tm_mday |
1 到 31 |
3 |
tm_hour |
0 到 23 |
4 |
tm_min |
0 到 59 |
5 |
tm_sec |
0 到 61 (60或61 是闰秒) |
6 |
tm_wday |
0到6 (0是周一) |
7 |
tm_yday |
1 到 366(儒略历) |
8 |
tm_isdst |
-1, 0, 1, -1是决定是否为夏令时的旗帜 |
# Stubs for time # Ron Murawski <ron@horizonchess.com> # based on: http://docs.python.org/3.3/library/time.html#module-time # see: http://nullege.com/codes/search?cq=time import sys
from typing import Any, NamedTuple, Tuple, Union
from types import SimpleNamespace TimeTuple = Tuple[int, int, int, int, int, int, int, int, int] # 定义一个时间元组返回类型,共9个返回值,其中每一个值均为int类型 # ----- variables and constants ----- accept2dyear = False altzone = 0 daylight = 0 timezone = 0 tzname = ... # type: Tuple[str, str] if sys.version_info >= (3, 3) and sys.platform != 'win32': CLOCK_HIGHRES = 0 # Solaris only CLOCK_MONOTONIC = 0 # Unix only CLOCK_MONOTONIC_RAW = 0 # Linux 2.6.28 or later CLOCK_PROCESS_CPUTIME_ID = 0 # Unix only CLOCK_REALTIME = 0 # Unix only CLOCK_THREAD_CPUTIME_ID = 0 # Unix only if sys.version_info >= (3, 3): class struct_time( # 注意这是struct_time类型的具体相关参数定义,通过参数名即可知道其具体含义 NamedTuple( '_struct_time', [('tm_year', int), ('tm_mon', int), ('tm_mday', int), ('tm_hour', int), ('tm_min', int), ('tm_sec', int), ('tm_wday', int), ('tm_yday', int), ('tm_isdst', int), ('tm_zone', str), ('tm_gmtoff', int)] ) ): def __init__( # 构造函数 self, o: Union[ Tuple[int, int, int, int, int, int, int, int, int], Tuple[int, int, int, int, int, int, int, int, int, str], Tuple[int, int, int, int, int, int, int, int, int, str, int] ], _arg: Any = ..., ) -> None: ... def __new__( # 调用构造函数之前,需要调用此函数 cls, o: Union[ Tuple[int, int, int, int, int, int, int, int, int], Tuple[int, int, int, int, int, int, int, int, int, str], Tuple[int, int, int, int, int, int, int, int, int, str, int] ], _arg: Any = ..., ) -> struct_time: ... else: class struct_time( # struct_time类型具体定义 NamedTuple( '_struct_time', [('tm_year', int), ('tm_mon', int), ('tm_mday', int), ('tm_hour', int), ('tm_min', int), ('tm_sec', int), ('tm_wday', int), ('tm_yday', int), ('tm_isdst', int)] ) ): def __init__(self, o: TimeTuple, _arg: Any = ...) -> None: ... def __new__(cls, o: TimeTuple, _arg: Any = ...) -> struct_time: ... # ----- functions ----- # 返回指定格式的系统当前时间,例如:time.asctime()='Sun Jul 22 12:59:50 2018'
def asctime(t: Union[TimeTuple, struct_time, None] = ...) -> str: ... # return current time # 返回自进程开始或之后的CPU时间
def clock() -> float: ... # 依据参数secs秒数,返回自1970开始后计算的日期,参数为空时返回当前日期时间
def ctime(secs: Union[float, None] = ...) -> str: ... # return current time # 和ctime()区别在于返回值的格式不同,返回值的格式为struct_time
def gmtime(secs: Union[float, None] = ...) -> struct_time: ... # return current time # 和gmtime()方法功能基本相同,但是gmtime()时转换为标准的UTC时间
def localtime(secs: Union[float, None] = ...) -> struct_time: ... # return current time # 将当地时间的时间元组转换为自纪元以来的秒数,也就是时间戳的值
def mktime(t: Union[TimeTuple, struct_time]) -> float: ... # 延迟指定的secs秒数时间,就是让代码在此处休眠指定的秒数时间,然后再执行后续代码
def sleep(secs: Union[int, float]) -> None: ... # 返回指定t的格式format的字符串类型时间,例如:time.strftime("%Y-%m-%dT%H:%M:%SZ", a) = '2018-07-22T05:13:58Z'
def strftime(format: str, t: Union[TimeTuple, struct_time, None] = ...) -> str: ... # return current time # 给定指定的str类型的字符串时间,返回struct_time类型时间对象,例如:time.strptime("2018-07-18T13:12:11","%Y-%m-%dT%H:%M:%S")= time.struct_time(tm_year=2018, tm_mon=7, tm_mday=18, tm_hour=13, tm_min=12, tm_sec=11, tm_wday=2, tm_yday=199, tm_isdst=-1)
def strptime(string: str, format: str = ...) -> struct_time: ... # 返回系统当前的时间戳
def time() -> float: ... if sys.platform != 'win32':
# 将本地时区初始化或重新初始化为存储的值os.environ[ 'TZ'],默认为空
def tzset() -> None: ... # Unix only if sys.version_info >= (3, 3): def get_clock_info(name: str) -> SimpleNamespace: ... def monotonic() -> float: ... def perf_counter() -> float: ... def process_time() -> float: ... if sys.platform != 'win32': def clock_getres(clk_id: int) -> float: ... # Unix only def clock_gettime(clk_id: int) -> float: ... # Unix only def clock_settime(clk_id: int, time: float) -> None: ... # Unix only if sys.version_info >= (3, 7): def clock_gettime_ns(clock_id: int) -> int: ... def clock_settime_ns(clock_id: int, time: int) -> int: ... def monotonic_ns() -> int: ... def perf_counter_ns() -> int: ... def process_time_ns() -> int: ... def time_ns() -> int: ...
参考资料:
- 1.python--利用datetime模块计算时间差(https://blog.csdn.net/wo1182929447/article/details/77841529)
- 2.【python】获取指定日期的后(前)一(n)天(https://blog.csdn.net/evillist/article/details/50522505)
- 3.Python的datetime模块分析(https://blog.csdn.net/memory_qianxiao/article/details/80953710)
- 4.python——从datetime模块探索python的数据架构(https://www.cnblogs.com/Simon-xm/p/3935812.html#top)
- 5.Python标准库笔记(3) — datetime模块(http://www.cnblogs.com/jhao/p/6678921.html#top)
- 6.Python 日期和时间(http://www.runoob.com/python/python-date-time.html)
- 7.8.1. datetime — Basic date and time types(https://docs.python.org/3/library/datetime.html#module-datetime)
- 8.Python 3.6新特性官方文档中文版(https://juejin.im/entry/5860db8a1b69e6005625eb91)
- 9.Python3.6新特性官方文档中文版(https://pycntech.github.io/Python3.6%E6%96%B0%E7%89%B9%E6%80%A7%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E4%B8%AD%E6%96%87%E7%89%88.html)
基于Python的datetime模块和time模块源码阅读分析的更多相关文章
- 基于Python接口自动化测试框架(初级篇)附源码
引言 很多人都知道,目前市场上很多自动化测试工具,比如:Jmeter,Postman,TestLink等,还有一些自动化测试平台,那为啥还要开发接口自动化测试框架呢?相同之处就不说了,先说一下工具的局 ...
- Flask之基于route装饰器的路由系统(源码阅读解析)
一 路由系统 1. 在flask中配置URL和视图函数的路由时,首先需要在main.py中实例化一个app对象: from flask import Flask, render_template ap ...
- abp vnext2.0之核心组件模块加载系统源码解析与简单应用
abp vnext是abp官方在abp的基础之上构建的微服务架构,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext ...
- 基于Eclipse IDE的Ardupilot飞控源码阅读环境搭建
基于Eclipse IDE的Ardupilot飞控源码阅读环境搭建 作者:Awesome 日期:2017-10-21 需准备的软件工具 Ardupilot飞控源码 PX4 toolchain JAVA ...
- Python机器学习经典实例电子版和附带源码
Python机器学习经典实例电子版和附带源码 下载:https://pan.baidu.com/s/1m6ODNJk--PWHW8Vdsdjs-g 提取码:nyc0 分享更多python数据分析相关电 ...
- SDL源码阅读笔记(1) 基本模块
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 前言 对于大牛来说,写关于阅读源码的文章都会叫源码剖析或者深入浅出啥的,对于我,自己阅读阅读源码,写 ...
- 基于python语言使用余弦相似性算法进行文本相似度分析
编写此脚本的目的: 本人从事软件测试工作,近两年发现项目成员总会提出一些内容相似的问题,导致开发抱怨.一开始想搜索一下是否有此类工具能支持查重的工作,但并没找到,因此写了这个工具.通过从纸上谈兵到着手 ...
- 干货——基于Nop的精简版开发框架(附源码)
.NET的开发人员应该都知道这个大名鼎鼎的高质量b2c开源项目-nopCommerce,基于EntityFramework和MVC开发,拥有透明且结构良好的解决方案,同时结合了开源和商业软件的最佳特性 ...
- python线程同步原语--源码阅读
前面两篇文章,写了python线程同步原语的基本应用.下面这篇文章主要是通过阅读源码来了解这几个类的内部原理和是怎么协同一起工作来实现python多线程的. 相关文章链接:python同步原语--线程 ...
随机推荐
- python 全栈开发,Day102(支付宝支付)
昨日内容回顾 1. django请求生命周期? - 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者po ...
- this和判断的位置对赋值的要求
package charter01; public class Person { private String name; private int age; public String getName ...
- WebApi的调用-1.前端调用
前端调用 html <div class="row"> <form id="queryForm"> <input name=&qu ...
- POJ 1258 Agri-Net (Prim&Kruskal)
题意:FJ想连接光纤在各个农场以便网络普及,现给出一些连接关系(给出邻接矩阵),从中选出部分边,使得整个图连通.求边的最小总花费. 思路:裸的最小生成树,本题为稠密图,Prim算法求最小生成树更优,复 ...
- [转]什么时候该用NoSQL?
NoSQL这两年越来越热,尤其是大型互联网公司非常热衷这门技术.根据笔者的经验,并不是任何场景,NoSQL都要优于关系型数据库.下面我们来具体聊聊,什么时候使用NoSQL比较给力: 1) 数据库表sc ...
- Python高级正则
import re p = re.compile("^[0-9]") m = p.match('13435aSAdb') print(m.group()) 一.上面的第二行和第三行 ...
- java web开发阅读笔记:第一章
学习该书前所用推荐书籍<名师讲坛—java开发实战经典> 一web开发前奏 1.1网页发展 首先搞懂. 1.HTTP:超级文本传输协议,是一种通讯协议. 通过这个网络协议WW浏览器与WWW ...
- java中关于重载与重写的区别
1.重载 允许多个同名但是形式参数个数或参数类型不同的方法存在同一个类中,在调用时根据形式参数列表来调用对应的方法. 2.判断 (1):方法名必须相同. (2):形式参数个数不同或者参数类型不同(满足 ...
- 查找mac下腾讯视频下载地址
mac 腾讯视频下载的视频是不可见的,也许是因为版权原因吧.使用以下方法可以在文件中找到缓存的视频(不过都是被断开的很多短视频). 在terminal输入: cd Library/Containers ...
- Linux开源监控平台 -- Zabbix 小白安装以及使用
安装准备: 1.安装前需要先关闭selinux和firewall. 关闭Linux: [root@zabbix ~]# vi /etc/selinux/config 将SELINUX=enforcin ...