[TOC]
参考
- https://itopic.org/python-time-module.html
- https://www.liaoxuefeng.com/wiki/1016959663602400/1017648783851616
- https://blog.csdn.net/watfe/article/details/84943732
time模块
1 | print(time.__doc__) |
获取时间戳
1 | time.time() |
停留x秒
1 | print time.sleep.__doc__ |
time与字符串互转
1 | >>> print time.strftime.__doc__ |
1 | >>> print time.strptime.__doc__ |
1 | #!/usr/bin/python3 |
datetime模块
获取当前日期和时间
1 | from datetime import datetime |
注意到datetime
是模块,datetime
模块还包含一个datetime
类,通过from datetime import datetime
导入的才是datetime
这个类。
如果仅导入import datetime
,则必须引用全名datetime.datetime
。
datetime.now()
返回当前日期和时间,其类型是datetime
。
获取指定日期和时间
要指定某个日期和时间,我们直接用参数构造一个datetime
:
1 | from datetime import datetime |
datetime转换为timestamp
在计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0
(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。
你可以认为:
1 | timestamp = 0 = 1970-1-1 00:00:00 UTC+0:00 |
对应的北京时间是:
1 | timestamp = 0 = 1970-1-1 08:00:00 UTC+8:00 |
可见timestamp的值与时区毫无关系,因为timestamp一旦确定,其UTC时间就确定了,转换到任意时区的时间也是完全确定的,这就是为什么计算机存储的当前时间是以timestamp表示的,因为全球各地的计算机在任意时刻的timestamp都是完全相同的(假定时间已校准)。
把一个datetime
类型转换为timestamp只需要简单调用timestamp()
方法:
1 | from datetime import datetime |
注意Python的timestamp是一个浮点数。如果有小数位,小数位表示毫秒数。
某些编程语言(如Java和JavaScript)的timestamp使用整数表示毫秒数,这种情况下只需要把timestamp除以1000就得到Python的浮点表示方法。
timestamp转换为datetime
要把timestamp转换为datetime
,使用datetime
提供的fromtimestamp()
方法:
1 | >>> from datetime import datetime |
注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。
本地时间是指当前操作系统设定的时区。例如北京时区是东8区,则本地时间:
1 | 2015-04-19 12:20:00 |
实际上就是UTC+8:00时区的时间:
1 | 2015-04-19 12:20:00 UTC+8:00 |
而此刻的格林威治标准时间与北京时间差了8小时,也就是UTC+0:00时区的时间应该是:
1 | 2015-04-19 04:20:00 UTC+0:00 |
timestamp也可以直接被转换到UTC标准时区的时间:
1 | >>> from datetime import datetime |
str转换为datetime
很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()
实现,需要一个日期和时间的格式化字符串:
1 | >>> from datetime import datetime |
字符串'%Y-%m-%d %H:%M:%S'
规定了日期和时间部分的格式。详细的说明请参考Python文档。
注意转换后的datetime是没有时区信息的。
datetime转换为str
如果已经有了datetime对象,要把它格式化为字符串显示给用户,就需要转换为str,转换方法是通过strftime()
实现的,同样需要一个日期和时间的格式化字符串:
1 | >>> from datetime import datetime |
datetime加减
对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用+
和-
运算符,不过需要导入timedelta
这个类:
1 | >>> from datetime import datetime, timedelta |
可见,使用timedelta
你可以很容易地算出前几天和后几天的时刻。
本地时间转换为UTC时间
本地时间是指系统设定时区的时间,例如北京时间是UTC+8:00时区的时间,而UTC时间指UTC+0:00时区的时间。
一个datetime
类型有一个时区属性tzinfo
,但是默认为None
,所以无法区分这个datetime
到底是哪个时区,除非强行给datetime
设置一个时区:
1 | >>> from datetime import datetime, timedelta, timezone |
如果系统时区恰好是UTC+8:00,那么上述代码就是正确的,否则,不能强制设置为UTC+8:00时区。
时区转换
我们可以先通过utcnow()
拿到当前的UTC时间,再转换为任意时区的时间:
1 | # 拿到UTC时间,并强制设置时区为UTC+0:00: |
时区转换的关键在于,拿到一个datetime
时,要获知其正确的时区,然后强制设置时区,作为基准时间。
利用带时区的datetime
,通过astimezone()
方法,可以转换到任意时区。
注:不是必须从UTC+0:00时区转换到其他时区,任何带时区的datetime
都可以正确转换,例如上述bj_dt
到tokyo_dt
的转换。
小结
datetime
表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。
如果要存储datetime
,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。
dateutil模块
安装
1 | pip install python-dateutil |
parser
parser是根据字符串解析成datetime,字符串可以很随意,可以用时间日期的英文单词,可以用横线、逗号、空格等做分隔符,可以包含时区。
没指定时间默认是0点,没指定日期默认是今天,没指定年份默认是今年。
1 | from dateutil.parser import parse |
rrule
rrule(self, freq, dtstart=None, interval=1, wkst=None,count=None, until=None, bysetpos=None,bymonth=None, bymonthday=None, byyearday=None, byeaster=None,byweekno=None, byweekday=None, byhour=None, byminute=None, bysecond=None,cache=False)
- freq:可以理解为单位。可以是 YEARLY, MONTHLY, WEEKLY,DAILY, HOURLY, MINUTELY, SECONDLY。即年月日周时分秒
- dtstart,until:是开始和结束时间
- wkst:周开始时间
- interval:间隔
- count:指定生成多少个
- byxxx:指定匹配的周期。比如byweekday=(MO,TU)则只有周一周二的匹配。byweekday可以指定MO,TU,WE,TH,FR,SA,SU。即周一到周日。
1 | from dateutil import rrule |
计算时间差
rrule可计算出两个datetime对象间相差的年月日等时间数量
1 | 两个日期相差10天 |
两个日期相差几个月
前一个月为m月,后一个月为n月,当日期不满整月时,差的月数按n-m算,当日期满整月后,差的月数按n-m+1算。
差的年数同月数的情况一样。
例子如下:
1 | '2018-3-15'),until=parse('2018-11-10')).count() rrule.rrule(rrule.MONTHLY,dtstart=parse( |
技巧
当前时间转文本
无论是time
或datetime
,哪个模块都可以,具体怎么输出,自行调整格式参数'%Y-%m-%d %H:%M:%S'
%字符 | 表意 | 数值范围 |
---|---|---|
%y | 年(2位) | 00, 01, …, 99 |
%Y | 年(4位) | 0001, 0002, …, 2013, 2014, …, 9998, 9999 |
%m | 月 | 01, 02, …, 12 |
%d | 日 | 01, 02, …, 31 |
%H | 时(24小时制) | 00, 01, …, 23 |
%M | 分 | 00, 01, …, 59 |
%S | 秒 | 00, 01, …, 59 |
%f | 毫秒 | 000000, 000001, …, 999999 |
%z | 时区 | (empty), +0000, -0400, +1030, +063415, -030712.345216 |
这里只列一下我用到的,更多可以看官方文档:
https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
【注意】:time、datetime两种时间模块虽然都有strftime,但是(格式,时间)参数位置正好相反。
time模块(格式在前,时间在后)
1 | import time |
datetime模块(格式在后,时间在前)
1 | import datetime |
文本转日期
常规方法strptime("日期时间文本","文本格式")
制定时间格式,进行解析
1 | import datetime |
万能方法parse("日期时间文本")
自动解析
1 | from dateutil.parser import parse |
该方法适用于很多类型时间格式,建议使用前自行测试
1 | dt = ["2001.07.04 AD at 12:08:56 PDT", |
但是注意,国外日期时间的常用格式和国内不一样。单写19-05-25
会被解析成2025年5月19日
1 | print(parse("19-05-25")) |
如果是2019-05-25
就不会错了
1 | print(parse("2019-05-25")) |
时间戳相关
生成10或13位时间戳(做一些网页爬虫或构造提交时候可能用到)
1 | import time |
时间戳转日期时间(10位或13位通用)
1 | import datetime |
时间差计算
如果是两个datatime
格式的日期,直接计算一下差值即可
1 | import datetime |
如果是两个文本格式的日期,用parse()
转换成datetime
,同样计算差值即可
1 | import datetime |
时区转换
直接获取0时区的datetime
,并转化为东8区datetime
。
1 | from datetime import datetime,timezone,timedelta |
如果是想将文本格式的2019-05-25T02:48:54.281741+00:00
转化到东8区datetime
1 | from datetime import datetime,timezone,timedelta |
获取常用时间
1 | from datetime import datetime, timedelta |