原文链接:https://dreamhomes.top/posts/202103091919.html
由于从事智能运维AIOps相关的算法研究,因此日常接触的最多就是时间序列相关的数据。在不同场景下时间字符串表示的格式可能都不相同,因此本文记录下所了解的字符串解析方法。
time 模块
一般情况下都是将时间字符串转为时间戳或者反之转换,time 模块即可解决问题;
import time
# 时间戳转为日期
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t))
# 日期转为时间戳
time.mktime(time.strptime(d, "%Y-%m-%dT%H:%M:%S.%fZ"))
⚠️ 注意:上面时间转换方法操作简单,可以满足大部分需求;但是存在两种问题:
- 时区问题,例如UTC格式;【如果是时间戳就没什么区别?】
- 字符串格式问题,例如不同的日期字符串格式;
datetime 模块
datetime 模块比 time 模块功能更加丰富;
详细的接口说明参考:https://docs.python.org/zh-cn/3.8/library/datetime.html
例如将 UTC 时间转为本地时间格式:
from datetime import datetime, timedelta
utc = "2021-03-08T08:28:47.776Z"
UTC_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
utc_time = datetime.strptime(utc, UTC_FORMAT)
local_time = utc_time + timedelta(hours=8)
print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f")) # 2021-03-08 16:28:47.776000
时间戳转为时间字符串:
ts = 1615289959 # datetime.now().timestamp()
datetime.fromtimestamp(1615289959).strftime("%Y-%m-%d %H:%M:%S.%f") # '2021-03-09 19:39:19.000000'
dateutil 模块
dateutil 模块具有扩展时区和解析支持的第三方库,时间解析功能非常强大几乎包含任何形式的时间字符串格式;
详细接口参考文档:https://dateutil.readthedocs.io/en/stable/
参考案例:
>>> from dateutil.relativedelta import *
>>> from dateutil.easter import *
>>> from dateutil.rrule import *
>>> from dateutil.parser import *
>>> from datetime import *
>>> now = parse("Sat Oct 11 17:13:46 UTC 2003")
>>> today = now.date()
>>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
>>> rdelta = relativedelta(easter(year), today)
>>> print("Today is: %s" % today)
Today is: 2003-10-11
>>> print("Year with next Aug 13th on a Friday is: %s" % year)
Year with next Aug 13th on a Friday is: 2004
>>> print("How far is the Easter of that year: %s" % rdelta)
How far is the Easter of that year: relativedelta(months=+6)
>>> print("And the Easter of that year is: %s" % (today+rdelta))
And the Easter of that year is: 2004-04-11
Pytz 模块可以与之共同使用来指定时区;Pytz 参考:https://pypi.org/project/pytz/
参考案例:
>>> from datetime import datetime, timedelta
>>> from pytz import timezone
>>> import pytz
>>> utc = pytz.utc
>>> utc.zone
'UTC'
>>> eastern = timezone('US/Eastern')
>>> eastern.zone
'US/Eastern'
>>> amsterdam = timezone('Europe/Amsterdam')
>>> fmt = '%Y-%m-%d %H:%M:%S %Z%z'
>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500
>>> ams_dt = loc_dt.astimezone(amsterdam)
>>> ams_dt.strftime(fmt)
'2002-10-27 12:00:00 CET+0100'
其它技巧
macOS :
// 将时间戳转为日期
$ date -r 1615289959
// 将日期转为时间戳
$ date -j -f "%Y-%m-%d %H:%M:%S" "2021-03-09 07:10:00" "+%s"
附录
python中时间日期格式化符号:
%y
两位数的年份表示(00-99)%Y
四位数的年份表示(000-9999)%m
月份(01-12)%d
月内中的一天(0-31)%H
24小时制小时数(0-23)%I
12小时制小时数(01-12)%M
分钟数(00-59)%S
秒(00-59)%a
本地简化星期名称%A
本地完整星期名称%b
本地简化的月份名称%B
本地完整的月份名称%c
本地相应的日期表示和时间表示%j
年内的一天(001-366)%p
本地A.M.或P.M.的等价符%U
一年中的星期数(00-53)星期天为星期的开始%w
星期(0-6),星期天为 0,星期一为 1,以此类推。%W
一年中的星期数(00-53)星期一为星期的开始%x
本地相应的日期表示%X
本地相应的时间表示%Z
当前时区的名称%%
%号本身