ホームページ >バックエンド開発 >Python チュートリアル >Python で一般的に使用される標準ライブラリとサードパーティ ライブラリ 3 - 日付と時刻処理モジュール
時刻処理は、時刻タイプの変換など、プログラミングにおける一般的な状況です。バックエンド インターフェイスがパラメーターを渡すとき、通常はタイムスタンプも渡します。フロントエンドによって取得されるインターフェイスの戻り値のタイムスタンプは、通常、次のとおりである必要があります。表示する前にフォーマットされます。 Python では、時間を処理するモジュールには time と datetime が含まれます。
タイム モジュールは、時間を処理するために特別に使用される Python の組み込みライブラリです。これには、異なる時刻タイプを相互に変換できる多くのメソッドが付属しています。たとえば、タイムスタンプ タイプをタイム タプルに、タイム タプルを書式設定された時刻に、書式設定された時刻をタイムスタンプに変換できます。時間タイプ
import time # 时间戳类型 t1 = time.time() print(t1) r_time = round(t1 * 1000)# 四舍五入,精确到毫秒 print(r_time) ''' 1677555790.7605402 1677555790761 ''' # 时间字符串 t2 = time.asctime() print(t2) ''' Tue Feb 28 11:44:15 2023 ''' # 时间元组 t3 = time.localtime() print(t3) ''' 依次对应:年份,月份,一个月的第几天,几点,几分,几秒,星期几,一年中的第几天,是否为闰年 time.struct_time(tm_year=2023, tm_mon=2, tm_mday=28, tm_hour=11, tm_min=44, tm_sec=53, tm_wday=1, tm_yday=59, tm_isdst=0) '''
① Timestamp
タイムタプル変換time.time()現在時刻のタイムスタンプ戻り値形式を返します: 1677563451.2548294# 时间戳<===>时间元组 相互转换 # 1-时间戳转换为时间元组 tt1 = time.localtime(time.time()) print(tt1) ''' time.struct_time(tm_year=2023, tm_mon=2, tm_mday=28, tm_hour=11, tm_min=48, tm_sec=57, tm_wday=1, tm_yday=59, tm_isdst=0) ''' # 2-时间元组转换为时间戳 tt2 = time.mktime(time.localtime()) print(tt2) ''' 1677556220.0 '''
# 时间元组<===>格式化时间 相互转换 # 1-时间元组转换为格式化时间 tt3 = time.localtime() print(time.strftime("%Y-%m-%d %H:%M:%S".format(tt3))) ''' 2023-02-28 13:52:02 ''' # 2-格式化时间转换为时间元组 tt4 = time.strptime("2023-02-28 11:54:25", "%Y-%m-%d %H:%M:%S") print(tt4) ''' time.struct_time(tm_year=2023, tm_mon=2, tm_mday=28, tm_hour=11, tm_min=54, tm_sec=25, tm_wday=1, tm_yday=59, tm_isdst=-1) '''
# 时间戳<===>格式化时间 相互转换 # 1-格式化时间转换为时间戳 time_format = "2023-02-28 19:11:56" # 先将格式化时间转换为时间元组 time_stamp1 = time.strptime(time_format, "%Y-%m-%d %H:%M:%S") # 再将时间元组转换为时间戳 tt7 = time.mktime(time_stamp1) print(tt7) ''' 1677582716.0 ''' # 2-时间戳转换为格式化时间 time_stamp2 = 1677582716.0 tt8 = time.strftime("%Y-%m-%d %H:%M:%S".format(time_stamp2)) print(tt8) ''' 2023-02-28 19:11:56 '''
④ 指定されたタイプの時刻を時刻文字列に変換します
time.asctime() 時刻タプルを時刻文字列に変換します。パラメータは時刻タプルで、戻り値の形式は次のとおりです: Tue Feb 28 11:51:05 2023;# 指定类型时间转换为时间字符串 # 1-时间元组转换为时间字符串 tt5 = time.asctime(time.localtime()) print(tt5) ''' Tue Feb 28 11:51:05 2023 ''' # 2-时间戳转换为时间字符串 timestamp = 1677582279.0 tt6 = time.ctime(timestamp) print(tt6) ''' Tue Feb 28 11:51:05 2023 '''
一般的に使用される日時のカテゴリは次のとおりです:
date: 日付クラス、主に年、月、日の処理に使用されます;2 .date クラスの共通メソッドまたは属性
指定した日付を設定
import datetime # 设置指定日期 set_date = datetime.date(day=1, month=3, year=2025) print(set_date)# 2025-03-01
# 获取今天日期的年份、月份、日 today = datetime.date.today() print("标准日期格式:", today.isoformat())# 标准日期格式: 2023-03-01 print("当前日期的三元元祖: 年、第几周、一周的第几天:", today.isocalendar())# 当前日期的三元元祖: 年、第几周、一周的第几天: (2023, 9, 3) print("当前日期:", today)# 当前日期: 2023-03-01 print("当前年月日:", today.today())# 当前年月日: 2023-03-01 print("当前年份:", today.year)# 当前年份: 2023 print("当前月份:", today.month)# 当前月份: 3 print("当前日:", today.day)# 当前日: 1
# 判断今天是这周的第几天 today = datetime.date.today() print("当前日期是这周的第几天(星期一==0/周日==6):", today.weekday())# 当前日期是这周的第几天(星期一==0/周日==6): 2 print("当前日期是这周的第几天(星期一==1/周日==7):", today.isoweekday())# 当前日期是这周的第几天(星期一==1/周日==7): 3
# 当前日期的其他格式 today = datetime.date.today() print("当前日期的时间字符串形式:", today.ctime())# 当前日期的时间字符串形式: Wed Mar1 00:00:00 2023 print("当前日期的元组形式:", today.timetuple()) print("当前日期的格式化时间形式:", today.strftime("%Y-%m-%d %H:%M:%S"))# 当前日期的格式化时间形式: 2023-03-01 00:00:00
# 替换日期 today = datetime.date.today() new_day = today.replace(year=2038, month=8, day=31) print("替换后的日期为:", new_day)# 替换后的日期为: 2038-08-31
# 指定格式转换为日期 today = datetime.date.today() t1 = today.fromtimestamp(1691453288)# 注意精确到秒、不是毫秒 print("从时间戳转换为日期:", t1)# 从时间戳转换为日期: 2023-08-08 t2 = today.fromisoformat("2025-03-03") print("从三元组转换为日期:", t2)# 从三元组转换为日期: 2025-03-03 t3 = today.fromisocalendar(year=2038, week=9, day=7) print("从三元组转换为日期:", t3)# 从三元组转换为日期: 2038-03-07
t = datetime.time(hour=12, minute=59, second=59, microsecond=59)# 实例化time对象,传入时、分、秒、微秒 print("当前时间:", t)# 当前时间: 12:59:59.000059 # 常用属性 print("时:", t.hour)# 时: 12 print("分:", t.minute)# 分: 59 print("秒:", t.second)# 秒: 59 print("微秒:", t.microsecond)# 微秒: 59 print("最大时间:", t.max)# 最大时间: 23:59:59.999999 print("最小时间:", t.min)# 最小时间: 00:00:00
t = datetime.time(hour=12, minute=59, second=59, microsecond=59)# 实例化time对象,传入时、分、秒、微秒 print("当前时间:", t)# 当前时间: 12:59:59.000059 # 常用方法 print("返回格式化时间:", t.isoformat())# 格式化时间: 12:59:59.000059 print("从格式化时间转换:", t.fromisoformat('12:00:00'))# 从格式化时间转换: 12:00:00 print("转换为格式化时间:", t.strftime("%Y-%m %H:%M:%S"))# 转换为格式化时间: 1900-01 12:59:59
dt = datetime.datetime.now()# 实例化datetime类 print("当前日期:", dt)# 当前日期: 2023-03-01 15:17:00.350579 # 常用属性 print("当前年份:", dt.year)# 当前年份: 2023 print("当前月份:", dt.month)# 当前月份: 3 print("当前日:", dt.day)# 当前日: 1 print("时:", dt.hour)# 时: 15 print("分:", dt.minute)# 分: 17 print("秒:", dt.second)# 秒: 0 print("微秒:", dt.microsecond)# 微秒: 350579 print("最大时间:", dt.max)# 最大时间: 9999-12-31 23:59:59.999999 print("最小时间:", dt.min)# 最小时间: 0001-01-01 00:00:00
dt = datetime.datetime.now()# 实例化datetime类 print("当前日期:", dt)# 当前日期: 2023-03-01 15:17:00.350579 # 常用方法 print("今天日期时间:", dt.today())# 今天日期时间: 2023-03-01 15:23:55.703063 print("当前日期:", dt.date())# 当前日期: 2023-03-01 print("当前日期时间的格式化输出:", dt.isoformat())# 当前日期时间的格式化输出: 2023-03-01T15:23:55.703063 print("当前日期的三元组:", dt.isocalendar())# 当前日期的三元组: (2023, 9, 3) print("当前日期一周中的第几天:", dt.isoweekday())# 当前日期一周中的第几天: 3 print("从指定日期时间转换并格式化输出:", dt.fromisoformat("2023-02-28 19:11:56"))# 从指定日期时间转换并格式化输出: 2023-02-28 19:11:56 print("从指定时间戳转换并格式化输出:", dt.fromtimestamp(1677644920))# 从指定时间戳转换并格式化输出: 2023-03-01 12:28:40 print("从三元组转换并格式化输出:", dt.fromisocalendar(year=2025, week=4, day=2))# 从三元组转换并格式化输出: 2025-01-21 00:00:00
datetime.timedelta() 类可以传递多个参数,用来表示时间间隔,返回形式为标准时间格式:0:00:00
print(datetime.timedelta(days=3))# 3 days, 0:00:00 print(datetime.timedelta(hours=3))# 3:00:00 print(datetime.timedelta(minutes=10))# 0:10:00 print(datetime.timedelta(milliseconds=5000))# 0:00:05 print(datetime.timedelta(microseconds=5000000))# 0:00:05
timeit 模块提供了多种方法,可以用来测量 Python 小段代码执行时间。它既可以在命令行界面直接使用,也可以通过导入模块进行调用。
timeit 模块定义了三个实用函数和一个公共类,分别为timeit.timeit()方法、timeit.repeat()方法、timeit.default_timer()方法、timeit.Timer类。部分源码如下:
def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number) def repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer, globals).repeat(repeat, number)
从上述源码中可以看出,无论是timeit还是repeat方法,都是先生成Timer对象,然后调用了Timer对象的timeit或repeat函数。
timeit.timeit(stmt='pass', setup='pass', timer=
, number=1000000)
创建一个 Timer 实例,参数分别是:
注:由于 timeit() 正在执行语句,语句中如果存在返回值的话会阻止 timeit() 返回执行时间。timeit() 会取代原语句中的返回值。
"""timeit()方法""" # 统计代码运行时间 # stmt:要测试的代码,setup:初始化导入语句、要传入的变量属性等 tm1 = timeit.timeit(stmt="[i**2 for i in testlist]", setup="testlist=range(1000)", number=3)# 统计代码运行时间 print(tm1)# 0.0007954000000000017 # 统计代码运行时间,setup为复合语句 tm2 = timeit.timeit(stmt="[i**2 for i in testlist]", setup="a=1000;testlist=range(a)", number=3)# 统计代码运行时间 print(tm2)# 0.0007886000000000282
timeit.repeat(stmt='pass', setup='pass', timer=
, repeat=3, number=1000000)
创建一个 Timer 实例,参数分别是:
"""repeat()方法""" # 统计代码运行时间,重复两次,返回结果为列表 # stmt:要测试的代码,setup:初始化导入语句、要传入的变量属性等 tp1 = timeit.repeat(stmt="[i**2 for i in testlist]", setup="testlist=range(1000)", number=3, repeat=5) print(tp1)# [0.0007632000000000194, 0.0007527999999999979, 0.000754300000000041] # 统计代码运行时间,setup为复合语句 tp2 = timeit.repeat(stmt="[i**2 for i in testlist]", setup="a=1000;testlist=range(a)", number=3, repeat=5) print(tp2)# [0.0007581999999999867, 0.0007580999999999838, 0.0007536000000000209]
timeit.default_timer()默认的计时器,一般是 time.perf_counter(),time.perf_counter() 方法能够在任一平台提供最高精度的计时器(它也只是记录了自然时间,记录自然时间会被很多其他因素影响,例如计算机的负载)。
timeit.Timer是计算小段代码执行速度的类:
timer = timeit.Timer(stmt='pass', setup='pass', timer=
timer.timeit(number=10)
timer.repeat(number=10, repeat=5)
构造函数需要的参数有:
前两个参数的默认值都是 'pass',timer 参数是平台相关的;前两个参数都可以包含多个语句,多个语句间使用分号(;)或新行分隔开。
第一次测试语句的时间,可以使用 timeit() 方法;repeat() 方法相当于持续多次调用 timeit() 方法并将结果返回为一个列表。
stmt 和 setup 参数也可以是可供调用但没有参数的对象,这将会在一个计时函数中嵌套调用它们,然后被 timeit() 所执行。注意,由于额外的调用,计时开销会相对略到。
"""Timer类""" timer = timeit.Timer(stmt="[i**2 for i in testlist]", setup="a=1000;testlist=range(a)") # 调用timeit方法 print(timer.timeit(number=3))# 0.0008310999999999735 # 调用repeat方法,返回一个时间列表 print(timer.repeat(number=3, repeat=3))# [0.0007549000000000028, 0.0007492000000000054, 0.0007519999999999749]
通过"python -m timeit -h"查看帮助信息:
Tool for measuring execution time of small code snippets.
用于测量小代码片段执行时间的工具。
This module avoids a number of common traps for measuring execution
回。O'Reilly 発行の Python Cookbook
の Tim Peters によるアルゴリズムの章の紹介も参照してください。
このモジュールは、実行トラップ時間を測定するための多くの一般的な手法を回避します。オライリー社発行の Tim Peters の Python Cookbook も参照してください。
ライブラリの使用法: Timer クラスを参照。
ライブラリの使用法: Timer クラスを参照。
コマンドラインの使用法:
コマンドラインの使用法:
python timeit.py [-n N] [-r N] [-s S] [-p] [ -h] [--] [ステートメント]
オプション: オプション:
-n/--number N: 「ステートメント」を実行する回数 (デフォルト: 以下を参照)
-r/--repeat N: タイマーを繰り返す回数 (デフォルトは 5)
#-s/--setup S: 最初に 1 回実行されるステートメント (デフォルトは「pass」)。 このセットアップ ステートメントの実行時間は計時されていません。-p/--process: time.process_time() を使用します (デフォルトは time.perf_counter()) -v/--verbose: 生のタイミング結果を出力します。より多くの桁の精度を得るために繰り返します。-u/--unit: 出力時間の単位を設定します (nsec、usec、msec、または sec)# #-h/--help: この使用法メッセージを出力して終了
--: オプションをステートメントから分離し、ステートメントが -
で始まる場合に使用しますステートメント: タイミングを計るステートメント (デフォルトは 'pass ')
複数行のステートメントは、各行を
#別個の引数として指定することによって指定できます。#引数を引用符で囲み、先頭にスペースを使用することにより、行をインデントすることができます複数の -s オプションは、同様に扱われます。複数の -s オプションを含めても同様に処理されます。
-n が指定されていない場合は、合計時間が少なくとも 0.2 秒になるまで
連続 10 のべき乗を試行することで、適切なループ数が計算されます。
そうでない場合は、 -n を指定すると、合計時間が 0.2 秒以上になるまで試行します。
注:
pass ステートメントの実行には、特定のベースライン オーバーヘッドが関連付けられています。これはバージョンによって異なります。ここのコードは、
それを隠蔽しようとはしませんが、ベースラインのオーバーヘッドは、引数なしでプログラムを呼び出すことで測定できます。
注: pass ステートメントを実行します。バージョンによって異なります。ここのコードはそれを隠そうとはしていませんが、注意しておく必要があります。ベースラインのオーバーヘッドは、パラメーターを指定せずにプログラムを呼び出すことで測定できます。
クラス:
タイマー
関数:
timeit(string, string) -> float
repeat(string, string) -> list
default_timer() -> float
具体的な使用法:
python timeit.py [-n N] [-r N] [-s S] [ -p] [-h] [--] [ステートメント]
各オプションの意味:
##意味 |
##-n N |
--number=N ステートメントが実行された回数 |
#-r N | --repeat=N | テストを繰り返します回数 (デフォルトは 5 回) |
--setup=S |
| 最初の実行ステートメント (変数、渡される属性など)。|
--process |
実際の実行時間ではなくプロセス時間を測定します (デフォルトの time.perf_counter() の代わりに time.process_time() を使用します) | |
--verbose | 生のタイミング結果を出力します。数値を増やすには繰り返します。精度 | |
--unit | 出力の設定時間単位 (nsec、usec、msec、または sec) | |
#--help | ヘルプ情報の出力 | |
--
|
||
##statement | 次のステートメント時間を計る(デフォルトは「パス」) |
这种场景主要适用于在接口传参时的时间日期转换,因为在后端接口传参中,一般都是用时间戳进行传递,而不是传统的"2023-02-28 19:11:56"格式。例如当前有一个新增车辆的接口,其中部分字段涉及到时间日期转换:道路运输证有效期止、行驶证有效期止:
在页面上我选择的都是2023-03-31,但在真实的接口传参中,会自动将其转换为时间戳的形式:
时间2023-03-31自动转换为了时间戳1680192000000,我们再通过工具将1680192000000转换为正常的格式化时间看看确实为2023-03-31,转换正确:
时间戳转换网站:https://www.php.cn/link/6e187996e9cc9d93c5f4452695768290
使用Python进行接口测试或模拟接口调用,也需要传递时间戳,Python中time.time()可以直接获取到当前时间的时间戳,但是获取到的是浮点型的数,可以借助round方法进行四舍五入,然后再*1000,从而精确到毫秒:
# 获取当前时间的时间戳 current_time = time.time() print(current_time)# 1677635951.946926 timestamp = round(current_time) * 1000 print(timestamp)# 1677635952000 # 将时间戳转换为格式化时间 format_time = time.strftime("%Y-%m-%d %H:%M:%S".format(current_time)) print(format_time)# 2023-03-01 09:59:11
将上述代码优化一下,封装成函数,直接进行调用:
def get_current_timestamp(): # 获取当前时间的时间戳 current_time = time.time() timestamp = round(current_time) * 1000 return timestamp def timestamp_to_format(timestamp): # 将时间戳转换为格式化时间 format_time = time.strftime("%Y-%m-%d %H:%M:%S".format(timestamp)) return format_time
同样是模拟接口调用,但是在造数据时,时间字段我想要模拟的不是当前时间,而是指定的日期时间,如三小时前、三天前等。以下分别介绍time模块和datetime模块如何快速模拟指定时间:
我们都知道1小时有3600秒,也就是3600*1000毫秒,所以如果是模拟3小时前的时间戳,则只需要拿到当前时间的时间戳-3600*1000*3即可:
def get_current_timestamp(): # 获取当前时间的时间戳 current_time = time.time() timestamp = round(current_time) * 1000 return timestamp three_hour_timestamp = get_current_timestamp() - 3600 * 3 * 1000 print(three_hour_timestamp)# 1677630754000
通过站长工具转换时间戳为格式化时间,确实是3个小时前的时间:
使用time模块处理的话需要经过一些计算,而使用datetime模块的timedelta类处理则简单得多,直接填写间隔的时长即可,可以是天、小时、分钟、秒等,获取当前日期时间的三天前的时间戳,整体过程大致分为以下步骤:
# 获取当前日期时间 now_date = datetime.datetime.now() print(now_date)# 2023-03-01 11:47:06.361630 # 获取三天前的日期时间 three_days_ago_date = datetime.datetime.now() - datetime.timedelta(days=3) print(three_days_ago_date) # 将时间元组转换为时间戳 time_tup = int(three_days_ago_date.timestamp() * 1000) print(time_tup)# 1677399019273
这种情况常常用在文件命名上,比如日志文件,通过文件名,可以区分是具体是什么日期时间生成的日志。例如:
# 定义log生成路径、log文件名称 logTime = time.strftime('%Y_%m_%d-%H_%M_%S', time.localtime(time.time())) # logPath = os.path.dirname(os.path.abspath('.')) + '\log\' logPath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '\logs\' logName = logPath + logger + "_" + logTime + '.log'
生成的日志文件如下:
在之前介绍装饰器的时候,我们有个案例就是通过time模块来统计代码运行时间的,示例如下:
def timer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() timer = end_time - start_time print("%s函数运行共耗时: %s秒" % (func.__name__, timer)) return res return wrapper @timer def run_timer(): time.sleep(1) print("测试---统计函数运行时间") run_timer() ''' 测试---统计函数运行时间 run_timer函数运行共耗时: 1.0101909637451172秒 '''
import time import timeit def run_time(): # 被测函数 time.sleep(1) print("used 1 second") # 统计代码运行时间 # stmt:要测试的代码,setup:要传入的变量属性等,number:每次测量中语句被执行的次数 tt = timeit.timeit(stmt=lambda: run_time(), number=3) print(tt) ''' used 1 second used 1 second used 1 second 3.001044 ''' # 统计代码运行时间,返回结果为列表 # stmt:要测试的代码,setup:要传入的变量属性等,repeat:重复测试的次数,number:每次测量中语句被执行的次数 tp = timeit.repeat(stmt="[i * 2 for i in testlist]", setup="testlist=range(1000)", repeat=5, number=1) print(tp) ''' [0.00011680000000025004, 9.259999999988722e-05, 8.76000000000765e-05] '''
以上がPython で一般的に使用される標準ライブラリとサードパーティ ライブラリ 3 - 日付と時刻処理モジュールの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。