博采众长穿梭时空|Maya库使用笔记

徘徊边缘 提交于 2021-02-16 09:36:04

Maya简介

用time、datetime等内置库处理时区需要挺多的代码,而且写法很不优雅,Maya是一个不错的第三方时间库,在pytz、pendulum等库基础上增强了对时区的处理。 

Maya的时间对象是自定义的MayaDT对象,是按时间戳表示的,因此在时区问题上更容易进行转换了。从功能上看,Maya的时间创建能力上排名前列,在时间偏移和属性获取上方面接口也挺简洁,综合来看是不错的Python时间库,在GitHub[1] 上目前有3.2k的star。

Maya库功能概览导图

时间输入与转换

Maya提供了丰富的接口用于从各种数据中解析出时间对象,既有简约的from_datetime()把datetime对象转为MayaDT时间对象,也有强大的when()parse()从字符串中解析时间要素。一些示例代码如下。

import mayamaya.parse('2020-12-08T03:15') #字符串转maya时间对象#Out[]:<MayaDT epoch=1607397346.636102>maya.when('1011-02-07') #因为是用的epoch,小于1970年是负数#<MayaDT epoch=-30259958400.0>dt=maya.now() #获取当前时间maya.when('tomorrow') #明天的这个时候,直接从自然语言转MayaDTmaya.MayaDT.from_datetime(datetime.now()) #datetime对象转MayaDTmaya.MayaDT.from_struct(time.gmtime()) maya.MayaDT(1606533154) #时间戳转Maya时间对象dt.day #获取时间要素属性

Maya库记录时间对象是用epoch时间戳,表示的是时间基准点至特定时间dt的总秒数,该基准点在Unix及类Unix系统中是格林威治时间1970年01月01日00时0分0秒,也称为Unix时间戳(Timestamp)。Maya可以充分地把其他基础库的时间对象转为MayaDT对象。另一方面,把一个MayaDT对象转为datetime对象或者转换为字符串也挺简单。

dt.datetime():把dt转为datetime对象;dt.date:转为datetime库的date对象,也就是只保留年月日,date后面没有小括号;dt.epoch:输出时间戳;dt.iso8601():输出符合ISO-8601标准[2] 的字符串,例如'2020-12-07T00:00:00Z';对应的还有dt.rfc3339()dt.rfc2822()

要输出为自定形式的字符串会麻烦一些,没有format方法可以用,需要用maya.Datetime.strftime(dt.datetime(),fmt)进行转换,fmt是time模块所支持的占位字符串,例如'%Y-%m-%d %H:%M:%S'。这里maya.Datetime就是用的datetime库的strftime。

属性获取与特性

MayaDT展示的虽然是epoch一个浮点数,其获取时间对象的年月日等时间要素的接口并不少,可以很自然地通过dt.day等得到时间要素,和datetime没有隔阂,year、month、second等都有,通过dt.timezone获取时区。其默认的时区是UTC的,其特性是获取属性时是转换为datetime再获取属性的。

dt=maya.parse('2020-12-07')dt.year #2020dt.timezone #UTCdt.local_datetime()dt.local_timezonedt.iso8601()dt.slang_time() #输出为自然语言
class MayaDT(object): @property def year(self): return self.datetime().year

Maya也是支持自然语言的输出的,只需要使用dt.slang_time(),也可以结合时间偏移功能连缀使用。slang是俚语的意思。MayaDT有slang_time和slang_date两个方法可以使用,slang_date更专注在日期维度的表达。

dt=maya.when('2020, 12, 7')dt.slang_time()# '8 hours ago'dt.add(days=10).slang_time()# 'in 1 week'dt.snap('@d+3h').slang_time()# '5 hours ago'dt.slang_date()# 'today'

时间偏移及序列

Maya对时间偏移抽象的接口是add和subtract,和其他库接口一致。dt.subtract(days=1)代表dt向前推移1天,输入的参数是years、days这些,数值可以为负数,subtract(days=-1)和add(days=1)效果是一致的。另外一种简写的方法是使用snap,例如dt.snap('@d+3h')表示在dt当天的基础上加3个小时,只要符合规则,可以写dt.snap("+8h@d+1d+11h")这类复杂的操作,这三个方法生成的是新对象,不是直接修改原dt对象。Maya的snap方法是调用的snaptime库,具体snap字符串参数的规则可以看snaptime文档[3] 。

Maya要生成一个时间序列可以使用maya.intervals或者MayaInterval类,实例如下。

list(maya.intervals(start=maya.now(),                    end=maya.now().add(days=1),                    interval=60*60))#生成start到end的每小时间隔的时间值序列
[i for i in maya.MayaInterval(start=now, end=now.add(hours=1))]

MayaInterval的参数有start、end和duration,duration间隔单位也是秒。

总结

Maya通过把时间统一表示为时间戳避免了各种时区问题,能够达到独立于系统和机器环境,站在datetime、pendulum、snaptime等模块的肩膀上,实现了各种实用的时间计算方法,增强了对时区的处理,在满足基本功能的基础上,别有特色地简化了满足ISO-8601、RFC-2822时间表达字符串的输入输出。

Maya功能和方法思维导图


References

[1] Maya文档: https://github.com/timofurrer/maya
[2] ISO-8601标准: https://help.tableau.com/current/pro/desktop/zh-cn/dates_calendar.htm
[3] snaptime文档: https://github.com/zartstrom/snaptime


本文分享自微信公众号 - 蛰虫始航(lyns_sailing)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!