目录
前言
记录一下自己在平时遇到的时间格式处理方式.只是简单的日期和时间处理,datetime和time模块就足够了;如果需要更高级的功能和易用性,可以考虑使用arrow、pandas或dateutil等第三方库。
过去用datetime模块,现在掌握了新的方式(arrow模块)去解决问题.主要是这次遇到的时间格式比较新颖(ddd MMM DD HH:mm:ss YYYY Z)
常用的库
datetime: datetime是Python内置的日期和时间处理模块。它提供了DateTime、Date、Time等类来处理日期和时间相关操作,并支持日期和时间的格式化、计算、比较等功能。
time: time模块也是Python内置的模块,用于处理时间相关的操作。它提供了一些函数来获取当前时间、睡眠、计时等功能,可以用于简单的时间处理需求。
arrow: arrow是一个第三方库,提供了更简洁和易用的API来处理日期和时间。它支持日期和时间的解析、格式化、计算、时区转换等功能,并且具有良好的可读性。
pandas: pandas是一个强大的数据分析库,也提供了对日期和时间数据的处理能力。它提供了Timestamp对象和DatetimeIndex对象来处理时间序列数据,并支持时间的索引、切片、重采样等高级操作。
dateutil: dateutil是一个第三方库,提供了一些有用的函数和类来处理日期和时间。它可以解析各种常见的日期和时间格式,并支持相对日期和时间的计算、时区转换等功能。
datetime
import datetime
current_datetime = datetime.datetime.now()
print(current_datetime) # <class 'datetime.datetime'>
""" 2023-10-26 10:52:26.473845 """
# datetime.strptime(): 将字符串解析为datetime对象,根据指定的格式进行解析。
date_string = "2023-10-26"
date_format = "%Y-%m-%d"
parsed_date = datetime.datetime.strptime(date_string, date_format)
print(parsed_date, type(parsed_date))
""" 2023-10-26 00:00:00 <class 'datetime.datetime'>"""
# datetime.strftime(): 将datetime对象格式化为指定格式的字符串。
current_datetime = datetime.datetime.now()
formatted_date = current_datetime.strftime("%Y-%m-%d %H:%M:%S")
print(formatted_date, type(formatted_date))
"""2023-10-26 10:57:00 <class 'str'>"""
# 2023-10-26 10:57:00 <class 'str'>
delta = datetime.timedelta(days=7, hours=12) # 表示7天12小时的时间间隔
now = datetime.datetime.now()
future = now + delta # 当前时间加上时间间隔
print(future)
"""2023-11-02 22:57:53.233680"""
# datetime.replace(): 替换datetime对象的部分属性,生成一个新的datetime对象。
current_datetime = datetime.datetime.now()
new_datetime = current_datetime.replace(year=2022, month=1, day=1)
print(new_datetime)
"""2022-01-01 10:58:36.875121"""
# datetime.weekday(): 返回日期对应的星期几,星期一为0,星期日为6。
current_datetime = datetime.datetime.now()
weekday = current_datetime.weekday()
print(weekday)
""" 3 """
time
import time
# time.time(): 返回当前时间的时间戳,即从1970年1月1日午夜开始经过的秒数。
current_time = time.time()
print(current_time)
""" 1698290167.59498 """
# time.sleep(): 让程序暂停指定的秒数。
time.sleep(3) # 暂停3秒
# time.localtime(): 返回当前时间的本地时间结构,以元组形式表示。
local_time = time.localtime()
print(local_time, type(local_time))
"""time.struct_time(tm_year=2023, tm_mon=10, tm_mday=26, tm_hour=11, tm_min=17, tm_sec=40, tm_wday=3, tm_yday=299, tm_isdst=0) <class 'time.struct_time'"""
# time.strftime(): 将时间格式化为指定格式的字符串。
current_time = time.time()
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(current_time))
print(formatted_time, type(formatted_time))
"""2023-10-26 11:18:52 <class 'str'>"""
# time.gmtime(): 返回当前时间的UTC时间结构,以元组形式表示。
utc_time = time.gmtime()
print(utc_time, type(utc_time))
"""time.struct_time(tm_year=2023, tm_mon=10, tm_mday=26, tm_hour=3, tm_min=19, tm_sec=31, tm_wday=3, tm_yday=299, tm_isdst=0) <class 'time.struct_time'>"""
# time.mktime(): 将时间结构转换为时间戳。
current_time = time.localtime()
timestamp = time.mktime(current_time)
print(timestamp, type(timestamp))
"""1698290741.0 <class 'float'>"""
arrow
Arrow是一个流行的Python库,用于处理日期、时间和时间跨度。
import arrow
# arrow.now(): 返回当前的日期和时间。
current_datetime = arrow.now()
print(current_datetime, type(current_datetime))
"""2023-10-26T11:35:32.681083+08:00 <class 'arrow.arrow.Arrow'>"""
# arrow.get(): 将字符串解析为Arrow对象,根据指定的格式进行解析。
date_string = "2023-10-26"
date_format = "YYYY-MM-DD"
parsed_date = arrow.get(date_string, date_format)
print(parsed_date, type(parsed_date))
"""2023-10-26T00:00:00+00:00 <class 'arrow.arrow.Arrow'>"""
# arrow.format(): 将Arrow对象格式化为指定格式的字符串。
formatted_date = current_datetime.format("YYYY-MM-DD HH:mm:ss")
print(formatted_date, type(formatted_date))
"""2023-10-26 11:35:32 <class 'str'>"""
# arrow.shift(): 对Arrow对象进行偏移,生成一个新的Arrow对象。
future_datetime = current_datetime.shift(days=7, hours=12) # 偏移7天12小时
print(future_datetime, type(future_datetime))
"""2023-11-02T23:35:32.681083+08:00 <class 'arrow.arrow.Arrow'>"""
# arrow.replace(): 替换Arrow对象的部分属性,生成一个新的Arrow对象。
new_datetime = current_datetime.replace(year=2022, month=1, day=1)
print(new_datetime, type(new_datetime))
"""2022-01-01T11:35:32.681083+08:00 <class 'arrow.arrow.Arrow'>"""
# arrow.weekday(): 返回日期对应的星期几,星期一为0,星期日为6。
weekday = current_datetime.weekday()
print(weekday, type(weekday))
"""3 <class 'int'>"""
pandas
import pandas as pd
# 1. 创建时间序列:
# - 使用`pd.to_datetime`将字符串转换为Pandas的`Timestamp`对象。
# - 使用`pd.date_range`生成一系列日期。
date_strings = ['2023-01-01', '2023-01-02', '2023-01-03']
dates = pd.to_datetime(date_strings)
print(dates)
"""
DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03'], dtype='datetime64[ns]', freq=None)
"""
# 2. 设置时间序列为索引:
# - 使用`df.set_index('column_name')`将某一列设置为时间序列的索引。
data = {'date': ['2023-01-01', '2023-01-02', '2023-01-03'],
'value': [10, 20, 30]}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
print(df)
"""
value
date
2023-01-01 10
2023-01-02 20
2023-01-03 30
"""
# 3. 时间序列的切片和筛选:
# - 使用`df.loc[start_date:end_date]`对时间范围内的数据进行切片。
# - 使用`df[df.index.year == 2023]`对特定年份的数据进行筛选。
data = {'date': ['2023-01-01', '2023-01-02', '2023-01-03'],
'value': [10, 20, 30]}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
sliced_df = df.loc['2023-01-02':'2023-01-03']
print(sliced_df)
"""
value
date
2023-01-02 20
2023-01-03 30
"""
# 4. 时间重采样:
# - 使用`df.resample('D').mean()`将时间序列重采样为每天的均值。
# - 使用`df.resample('M').sum()`将时间序列重采样为每月的总和。
data = {'date': pd.date_range(start='2023-01-01', periods=7),
'value': [10, 20, 30, 40, 50, 60, 70]}
df = pd.DataFrame(data)
df.set_index('date', inplace=True)
resampled_df = df.resample('D').mean()
print(resampled_df)
"""
value
date
2023-01-01 10.0
2023-01-02 20.0
2023-01-03 30.0
2023-01-04 40.0
2023-01-05 50.0
2023-01-06 60.0
2023-01-07 70.0
"""
# 5. 移动窗口计算:
# - 使用`df.rolling(window=3).mean()`计算滑动窗口为3的移动平均值。
data = {'date': pd.date_range(start='2023-01-01', periods=7),
'value': [10, 20, 30, 40, 50, 60, 70]}
df = pd.DataFrame(data)
df.set_index('date', inplace=True)
rolling_mean = df['value'].rolling(window=3).mean()
print(rolling_mean)
"""
date
2023-01-01 NaN
2023-01-02 NaN
2023-01-03 20.0
2023-01-04 30.0
2023-01-05 40.0
2023-01-06 50.0
2023-01-07 60.0
Name: value, dtype: float64
"""
# 6. 时间序列的偏移:
# - 使用`df.shift(1)`将时间序列向前平移1个时间单位。days weeks、months、years
# - 使用`df.diff()`计算相邻时间点之间的差异。
# 创建一个示例的时间序列数据
dates = pd.date_range(start='2023-01-01', periods=5, freq='D')
df = pd.DataFrame({'date': dates, 'value': range(5)})
print("原始数据:")
print(df)
# 对时间序列进行向前偏移一天
df['date_shifted_1'] = df['date'] + pd.DateOffset(days=1)
print("\n向前偏移一天:")
print(df)
# 对时间序列进行向后偏移两天
df['date_shifted_2'] = df['date'] - pd.DateOffset(days=2)
print("\n向后偏移两天:")
print(df)
"""
原始数据:
date value
0 2023-01-01 0
1 2023-01-02 1
2 2023-01-03 2
3 2023-01-04 3
4 2023-01-05 4
向前偏移一天 和 偏移2天:
date value date_shifted_1 date_shifted_2
0 2023-01-01 0 2023-01-02 2022-12-30
1 2023-01-02 1 2023-01-03 2022-12-31
2 2023-01-03 2 2023-01-04 2023-01-01
3 2023-01-04 3 2023-01-05 2023-01-02
4 2023-01-05 4 2023-01-06 2023-01-03
"""
# 7. 时间序列的频率转换:
# - 使用`df.asfreq('H')`将时间序列转换为每小时的频率。
# - 使用`df.asfreq('2W')`将时间序列转换为每两周的频率。
# 创建一个示例时间序列数据
data = {'date': pd.date_range('2023-01-01', periods=30, freq='D'),
'value': [i for i in range(1, 31)]}
df = pd.DataFrame(data)
# 将日期设置为索引
df.set_index('date', inplace=True)
# 将时间序列数据重新采样为每周频率(W)
resampled_df = df.asfreq('W')
print(resampled_df)
"""
value
date
2023-01-01 1
2023-01-08 8
2023-01-15 15
2023-01-22 22
2023-01-29 29
"""
# 8. 时间序列的统计分析:
# - 使用`df.mean()`计算时间序列的均值。
# - 使用`df.resample('M').max()`计算每月的最大值。
print('均值')
print(df.mean())
"""
value 15.5
dtype: float64
"""
print('计算每月的最大值')
print(df.resample('M').max())
"""
value
date
2023-01-31 30
"""
模块之间的差异
datetime与arrow之间的格式差异
datetime format | 效果1 | arrow format | 效果2 |
%Y-%m-%d %H:%M:%S%z | 2022-07-27 01:40:47.776620 | YYYY-MM-DD HH:mm:ssZ | 2022-07-27 09:40:47+0800 |
%d/%b/%Y:%H:%M:%S%z | 2022-07-27 01:41:55.023716 | DD/MMM/YYYY:HH:mm:ssZ | 27/Jul/2022:09:41:55+0800 |
%Y-%m-%dT%H:%M:%S %z | 2022-07-27 01:45:56.766133 | YYYY-MM-DDTHH:mm:ss Z | 2022-07-27T09:45:56 +0800 |
%c %z | 2022-07-27 01:51:18.266915 | ddd MMM DD HH:mm:ss YYYY Z | Wed Jul 27 09:51:18 2022 +0800 |
arrow库代码范例
#!/usr/bin/env python
# :*: coding:utf:8 :*:
# @FileName :time_format.py.py
# @Time :2022/7/27 10:07
# @Author :Marst
import time
from datetime import datetime
import pytz
import arrow
# 获取所有时区的名称
all_zone = pytz.all_timezones
# print(len(all_zone), all_zone)
# 0时区
utc_now = datetime.utcnow()
# 转换时区 东八区 +08:00 / 0800
# 先设定时区
tz = pytz.timezone("Asia/Shanghai")
# 转换 0时区 -> 东八区 z表示时区
# cst_time = tz.fromutc(utc_now).strftime("%Y-%m-%d %H:%M:%S%z")
# print(f"0时区 {utc_now} -> 东八区 {cst_time}")
# 转换成时间戳 ①不同的函数 采用的时间格式不同
def time_format1():
"""
0时区 -> 东八区 -> 时间戳
2022-07-27 01:40:47.776620 -> 2022-07-27 09:40:47+0800 -> 1658886047
"""
fmt = "%Y-%m-%d %H:%M:%S%z"
arrow_fmt = "YYYY-MM-DD HH:mm:ssZ"
_cst_time = tz.fromutc(utc_now).strftime(fmt)
print(f"0时区 {utc_now} -> 东八区 {_cst_time}")
arrow_time = arrow.get(_cst_time, arrow_fmt).timestamp
print(arrow_time)
def time_format2():
"""
0时区 -> 东八区 -> 时间戳
2022-07-27 01:41:55.023716 -> 27/Jul/2022:09:41:55+0800 -> 1658886115
"""
fmt = "%d/%b/%Y:%H:%M:%S%z"
arrow_fmt = "DD/MMM/YYYY:HH:mm:ssZ"
_cst_time = tz.fromutc(utc_now).strftime(fmt)
print(f"0时区 {utc_now} -> 东八区 {_cst_time}")
arrow_time = arrow.get(_cst_time, arrow_fmt).timestamp
print(arrow_time)
def time_format3():
"""
0时区 -> 东八区 -> 时间戳
2022-07-27 01:45:56.766133 -> 东八区 2022-07-27T09:45:56 +0800 -> 1658886356
"""
fmt = "%Y-%m-%dT%H:%M:%S %z"
arrow_fmt = "YYYY-MM-DDTHH:mm:ss Z"
_cst_time = tz.fromutc(utc_now).strftime(fmt)
print(f"0时区 {utc_now} -> 东八区 {_cst_time}")
arrow_time = arrow.get(_cst_time, arrow_fmt).timestamp
print(arrow_time)
def time_format4():
"""
0时区 -> 东八区 -> 时间戳
2022-07-27 01:51:18.266915 -> 东八区 Wed Jul 27 09:51:18 2022 +0800 -> 1658886678
"""
fmt = "%c %z"
arrow_fmt = "ddd MMM DD HH:mm:ss YYYY Z"
_cst_time = tz.fromutc(utc_now).strftime(fmt)
print(f"0时区 {utc_now} -> 东八区 {_cst_time}")
arrow_time = arrow.get(_cst_time, arrow_fmt).timestamp
print(arrow_time)
if __name__ == '__main__':
time_format4()