Python时间模块

https://blog.csdn.net/wuwei_201/article/details/105164151

一、datetime模块

datetime模块提供用于处理日期和时间的类。支持日期时间数学运算,更着重于有效地解析其属性用于格式化输出和数据操作。
官方文档
datetime模块中常用的和方法有:date、time、datetime、strtime、strftime、strptime、replace
导入模块:

import datetime

 
 
  • 1

1、date 类

datetime模块中的一个类,用于创建一个包含年月日的日期

d = datetime.date(2020, 3, 23)  # date的参数必须是int,需要注意的是1月就是1不是01
print(d)  
print(d.year)  # 获取时间变量的年份,月份:d.month 日期: d.day
print(datetime.date.today())  # 今天的日期
print(d.weekday())  # 返回日期是周几,周一是0
print(d.isoweekday())  # 返回日期是周几,周一是1, isoweekday = weekday()+1

2、time 类

datetime模块中的一个类,用于创建一个包含时分秒的时间(每天24x60x60秒)

d = datetime.time(8, 3, 15, 30)  # default: tzinfo=None
print(d)
print(d.hour)  # 提取时间的小时数
print(d.minute)  # 分
print(d.second)  # 秒
print(d.microsecond)  # 微秒
print(d.tzinfo)  # 时区, 源数据参数 tzinfo=None 时,这里也返回None

3、datetime 类

datatime模块中的datetime类,可以看作是上面date和time的组合。Attributes: year, month, day, hour, minute, second, microsecond(微秒)

d = datetime.datetime(2020, 3, 18, 20, 15, 20, 300)
print(d)  # -->2020-03-18 20:15:20.000300
print(d.month)  # 获取时间变量的月份
print(d.timestamp())  # 把易读时间转换为时间戳格式,方式一
time = datetime.datetime.timestamp(d)  # 把易读时间转换为时间戳格式 方式二
print(time)
time = datetime.datetime.fromtimestamp(time)  # 把时间戳转换为易读时间格式
print(time)
print(datetime.date(2020, 4, 10) - datetime.date(2020, 4, 9))  # 时间差
d = datetime.datetime.now(tz=pytz.utc)  
print(d)
print(d.date())
print(d.time())  # 17:29:19.824968 提取时间,不包括 tzinfo 属性
print(d.timetz())  # 17:29:19.824968 提取时间,包括 tzinfo 属性
print(d.astimezone())  # 返回带有本地时区的时间 2020-03-28 17:29:19.824968+08:00
print(d.utcoffset())  # 返回时间变量的时区,如果原数据参数的tz=None 那么这里也返回None
print(d.dst())  # 夏令时
print(d.timetuple())  # 返回一个元组格式的时间,可以用[index] 提取对应内容,比如 d.timetuple() -- year 返回值格式:
# time.struct_time(tm_year=2020, tm_mon=3, tm_mday=28, tm_hour=9, tm_min=41, tm_sec=28, tm_wday=5, tm_yday=88,
# tm_isdst=0)
# 其实datetime 就是 date + time,属性也是覆盖date 和 time
# 需要注意的时,date 没有 tzinfo属性,而time和datetime都有

4、strftime 方法

datatime 类中的一个方法,用于把时间格式化,返回一个字符串

d = datetime.datetime.now()  # 当前的电脑时间
print(d.strftime('%Y-%m-%d %H:%M:%S'))  # 返回2020-03-28 10:20:20
print(d.strftime('%y-%m-%d %H:%M:%S'))  # 返回20-03-28 10:20:20  注意年的大写Y和小写y的区别
print(d.strftime('%D %H:%M:%S'))  # 返回03/28/20 10:21:57  注意D的用法
print(d.strftime('%b-%d-%y %H:%M:%S'))  # Mar-28-20 10:20:20
print(d.strftime('%B-%d-%y %H:%M:%S'))  # March-28-20 10:23:39  注意B和b的区别,分别是月份的全拼和简写

5、strptime 方法

datatime 类中的一个类方法,用于把字符串格式的时间转换为datetime.datetime格式,
需要注意的是date类 和 time类都没有这个方法

d = datetime.datetime.now()
print(datetime.datetime.strptime('March-28-20 10:23:39', '%B-%d-%y %H:%M:%S'))
print(datetime.datetime.strptime('2020-03-28', '%Y-%m-%d'))  # 2020-03-28 00:00:00 如果只有日期,自动填充时间0
print(datetime.datetime.strptime('10:34:22', '%H:%M:%S'))  # 1900-01-01 10:34:22 如果只有时间,那么年份将是 1900-01-01
# 返回数据类型 <class 'datetime.datetime'>
print(type(datetime.datetime.strptime('2020-03-24 10:27:29', '%Y-%m-%d %H:%M:%S')))

6、replace 方法

返回一个带相同属性的datetime,除了指定关键字参数的新值之外,还可以指定tzinfo新值

d = datetime.datetime.now()  # --> 2020-03-28 11:00:41.296596
print(d.replace(year=2022, day=23))  # --> 2022-03-23 11:00:41.296596
# replace 的全部参数:
# 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)
# 其中tzinfo是修改时区
print(d.replace(tzinfo=pytz.timezone('Asia/Shanghai')))  # 把原时间的时区替换为参数的时区

单纯看上面的用法貌似基本用不到,一般我们不会去强行改变一个时间的某个值。有一种情况就是如果我们要获取这个月的最后一天是几号,有的月份是30天有的有31日,二月还是28/29天,你当然可以使用字典,但是太死板,使用replace就非常方便,下面自定义函数,可以获取月份的最后一天:

def last_day_month(date_time: datetime.datetime):
    """
    返回月份的最后一天
    :return:
    """
    next_month = date_time.replace(day=28) + datetime.timedelta(days=4)  # 把天数替换为28日,因为月份中最少的天数就是28了,+4天肯定到下一个月了
    delta = datetime.timedelta(days=next_month.day)  # next_month.day 下个月的天数,
    return next_month - delta 

7、timedelta 类

datetime模块中的一个类,表示两个日期或时间的差

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

所有参数都是可选的,默认为0。参数可以是整数或浮点数,也可以是正数或负数。

d = datetime.date(2020, 3, 23)
later = datetime.timedelta(days=9)  # 创建一个时间间隔(9天)
print(later)
t = d + later
print(t)  # 返回结果:2020-04-01; 源数据是3月23日,加9天,超过了31天了,程序会自动计入4月份,时分秒同理
print(later.total_seconds())  # 把时间间隔转换为秒数

通过参数可以注意到,timedelta 只能在日及以下级别偏移,如果要偏移一个月或一年的?那就要用到 dateutil 模块的 relativedelta(下面会介绍)。

8、tzinfo 和 timezone

tzinfo 也是datetime下的类,但是这个类不会用来实例化,只是捕获关于特定时区的信息,一般在datetime和time传参时使用。上面已经多次用到,这里不再举例。
timezone 是 tzinfo 的子类,它的每个实例都表示一个由UTC的固定偏移量定义的时区

二、dateutil 模块

官方文档
dateutil 是不同于datetime模块的一个第三方时间处理模块,其实常用的时间处理模块还是datetime,但是datetime有些不足的地方,比如 timedelta 偏移月份和年不方便,再比如把一个 ‘20200325082532’ 这样的字符串之间转换为时间类型或易读的字符串格式。那么这里就介绍这两个功能的补充:
导入模块:

from dateutil.relativedelta import * 
from dateutil.parser import parse  

1、relativedelta 类

从导入的方式可以推测,这是在 dateutil 模块中 relativedelta子模块中的一个类
类的定义:
relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0,
hours=0, minutes=0, seconds=0, microseconds=0,
year=None, month=None, day=None, weekday=None,
yearday=None, nlyearday=None,
hour=None, minute=None, second=None, microsecond=None)
所有参数都有默认值,参数很多,通过观察可以发现大部分参数可以分为两类,比如year/years,month/months…等,其实这里是datetime类中replace和timedelta的结合体
year,month,…参数就是把变量的时间替换为关键字参数的新值,而years,months,…参数其实就是timedelta的功能,即时间间隔,可以为负数,但是不能为小数,这是与timedelta的区别,从参数就可以看到很明显,增加了years,months的偏移,弥补了 timedelta 短板。例如:

d = datetime.datetime(2020, 3, 31, 8, 3, 15, 30)
print(d)
later = relativedelta(months=2)  # 返回relativedelta(months=+2),两个月的间隔,会按月天数自动计入
print(d+later)  # --> 2020-05-31 08:03:15.000030
later = relativedelta(month=2)  # 注意 months 和 month的区别,month是把月份改成2月,months是两个月间隔,累加2个月。返回日期2月份没有31日,会自动转换到2月的最后一天
print(d + later) # --> 2020-02-29 08:03:15.000030

relativedelta 除了补充timedelta的月和年偏移意外,还有一些很方便的扩展功能:
dt1和dt2,直接看案例:

c = relativedelta(dt1=d, dt2=datetime.date(2001, 1, 1))  # dt1-dt2 两个日期之间差,返回一个relativedelta类的元祖
print(c)  # 返回 relativedelta(years=+19, months=+2, days=+30, hours=+8, minutes=+3, seconds=+15, microseconds=+30)
print(c.years)  # relativedelta 使用参数dt1和dt2返回的结果,只能使用类似属性的方式获取

参数 weekday=None,其实也非常方便:

print(datetime.date.today()+relativedelta(weekday=FR))  # 获取下一个周五的日期,也可用datetime,获取下一个周五的相同时间
print(datetime.date.today()+relativedelta(day=31, weekday=FR(-1)))  # 获取这个月最后一个周五,MO, TU, WE, TH, FR, SA, SU
print(datetime.date.today() + relativedelta(day=1, weekday=FR))  # 获取这个月第一个周五
print(datetime.date.today() + relativedelta(weekday=WE(+1)))  # 从今天开始算的下一个周三
print(datetime.date.today() + relativedelta(days=+5, weekday=WE(+1)))  # 从5天后开始算的下一个周三
print(datetime.date.today() + relativedelta(months=+1, day=1, weekday=FR))  # 下个月的第一个周五

参数yearday=None, nlyearday=None,个人感觉就有些鸡肋了

print(datetime.datetime.now() + relativedelta(yearday=260))  # 260天后的日期,但是不能大于366天,而且最终结果不能跨年,如果跨年返回的结果就是今年最后一天的日期,不能跨年在作用上就有些受限了,敝人经历中很少用到,到时 weekday 比较常用,比如在期货交易中计算交割日
print(datetime.date(2000, 1, 1) + relativedelta(yearday=260))
print(datetime.date(2000, 1, 1) + relativedelta(nlyearday=260))  # nlyearday 主要区别与 yearday 是否忽略闰年

是 dateutil 模块中子模块,这个模块提供了一个通用的日期/时间字符串解析器,它能够解析大多数已知的格式来表示日期和/或时间。据官方文档介绍,即使有一些时间日期是模糊的,这个模块也可以处理。其实主要用的是模块中的 parse 函数,函数的定义:
parse(timestr, parserinfo=None, **kwargs):
解析非标准格式字符串时间方法:

d = '20200325082532'
print(parse(d))  # 返回 2020-03-25 08:25:32  <class 'datetime.datetime'>
print(parse(d).strftime('%Y-%m-%d %H:%M:%S'))  # 返回 2020-03-25 08:25:32  <class 'str'>

至于他的模糊处理还是比较麻烦的,其实也比较少用,这里列举一个官方的简单例子

m = parse("Today is January 1, 2047 at 8:21:00AM", fuzzy_with_tokens=True)
print(m)  # --> 返回一个元祖(datetime.datetime(2047, 1, 1, 8, 21), ('Today is ', ' ', ' ', 'at '))
print(m[0])  # 元祖的第一个值是处理后的时间,第二个值是一些干扰字符

官方文档
官方文档介绍简述:pytz模块可以实现精确的跨平台时区计算,并且解决了夏令时结束时的模糊时间问题。

1、查看时区,给时间添加时区属性

print(pytz.common_timezones_set)  # 返回结果-->LazySet({'Asia/Muscat', 'America/Tortola', 'Antarctica/Troll', 'Europe/Monaco', ...})
for n in pytz.common_timezones_set:  # 查看pytz中常见哪些时区,中国只有上海
    print(n)
for n in pytz.all_timezones:  # 查看全部时区,返回值是列表格式的可迭代对象:<class 'pytz.lazy.LazyList.__new__.<locals>.LazyList'>
    print(n)
for n in pytz.all_timezones_set:  # 查看全部时区 与 pytz.all_timezones 结果相同,只是返回值是一个集合格式的可迭代对象 <class 'pytz.lazy.LazySet.__new__.<locals>.LazySet'>
    print(n)
print(pytz.country_names['CN'])  # 查看国家的全称
print(pytz.country_timezones['CN'])  # 查看对应国家的时区代表城市
tz = pytz.timezone('America/New_York')  # 纽约时区
print(datetime.datetime.now(tz))  # 对应时区的当前时间
print(datetime.datetime(2020, 3, 30, 16, 20, tzinfo=tz))  # 这里需要注意的是,now(tz=pytz.timezone)是直接获得了对应时区的当前时间,但是datetime(int,int,...,tzinfo=pytz.timezone)并不是把时间转换的对应时区,而是给前面的时间增加了时区属性,时间数值并没有改变,所以不能用这个方式进行时区换算。对于没有夏令时转换的时区这样创建跨时区时间是没有问题的。如果涉及跨时区和夏令时的转换,可以使用下面的localize和astimezone

localize 是pytz模块下UTC类内的一个方法。定义:localize(dt, is_dst=False);
但是astimezone并不是pytz模块下的类或方法,而是datetime模块下的一个方法,之所以放到这里介绍,主要是因为这个方法下的唯一参数就是时区,需要用到pytz模块的属性,定义:astimezone(self, tz=None):

eastern = pytz.timezone('US/Eastern')  # 
print(eastern.zone)
amsterdam = pytz.timezone('Europe/Amsterdam')  # 欧洲--阿姆斯特丹
print(amsterdam)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
# localize给一个没有设置时区的时间设置时区,另外可以增加是否夏令时参数,但是这里并不如直接使用后面的astimezone更加方便。这里注意的是,要增加时区的变量时间必须是之前没有timezone属性,否则会报错!
loc_dt = eastern.localize(datetime.datetime(2020, 3, 28, 1, 0, 0), is_dst=True)
print(loc_dt)
print(loc_dt.strftime(fmt))
 # astimezone 把变量时间转换为指定时区的时间,前面变量时间不管有是否有timezone属性,都会按标准转换为参数的时区时间
ams_dt = loc_dt.astimezone(amsterdam)  # 把已经设置timezone属性的loc_dt转换为amsterdam时区时间
print(ams_dt.strftime(fmt))
ams_dt = datetime.datetime.now().astimezone(amsterdam)  # 把本地化的当前时间转换为指定时区的时间,这里的效果其实与datetime.datetime.now(tz=amsterdam)相同
print(ams_dt)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值