Python时间处理完全手册
專 欄
❈
gw1770df,Python中文社区专栏作者,从事Python开发工作,全栈工程师。
博客:
https://word.gw1770df.cc
Github:
https://github.com/gw1770df
❈——
处理时间是工作中非常常见的操作,最基本的获取当前时间,格式化时间,计算两个时间差,时间戳转换等等.
Python内置两个非常常用的时间处理库 time
和datetime
,足以满足工作中的各种需求。
datetime
功能更加强大, time
库就较为简练一些。
两个库互补使用,所有问题迎刃而解。
官方文档Python2.7 datetime(https://docs.python.org/2/library/datetime.html?highlight=datetime#module-datetime) 和 time(https://docs.python.org/2/library/time.html?highlight=time#module-time)
注意:time 或者 datetime 库需要提前import
WIKI:
UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从协调世界时1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒。 在多数Unix系统上Unix时间可以通过date +%s指令来检查。 各地日期和时间表示法:yyyy = 年份,mm = 月份,dd = 日期,MMM = 月份三字母缩写,mmmm = 月份全名,hr = 小时,mi = 分钟,se = 秒钟 国际标准ISO 8601:yyyy-mm-dd,hr:mi:se(24小时制) 中国:yyyy年m月d日;hr时mi分se秒;hr:mi:se(12/24小时制) 美国:mm/dd/yyyy;mm/dd/yy;mmmm dd, yyyy;hr:mi:se(12小时制) 澳大利亚:dd/mm/yyyy;MMM dd, yyyy;hr:mi:se a.m./p.m.(12/24小时制) 时区是地球上的区域使用同一个时间定义。以前,人们通过观察太阳的位置(时角)决定时间,这就使得不同经度的地方的时间有所不同(地方时)。1863年,首次使用时区的概念。时区通过设立一个区域的标准时间部分地解决了这个问题。
一. 获取并格式化时间
使用time
模块获取当前时间
print time.strftime('%Y-%m-%d %H:%M:%S')
# Out: '2016-12-01 16:10:27'
使用datetime
模块获取当前日期和当前时间
# 获取当前日期today = datetime.date.today()
print today.strftime('%Y-%m-%d')
# Out: '2016-12-01' # 获取当前日期
now = datetime.datetime.now()
print now.strftime('%Y-%m-%d %H:%M:%S')
# Out: '2016-12-01 16:14:22' # 获取当前日期时间
二. 转换时间格式
例如我们拿到了一个时间字符串 161201 16:14:22
需要将其转换成其他格式。
struct_time = time.strptime('161201 16:14:22', '%y%m%d %H:%M:%S')
# struct_time 为一个时间元组对象
print time.strftime('%Y-%m-%d %H:%M:%S', struct_time)
# Out: '2016-12-01 16:14:22'
dt = datetime.datetime.strptime('161201 16:14:22', '%y%m%d %H:%M:%S')
# dt 为 datetime.datetime对象 # 通过调用 timetuple()方法将datetime.datetime对象转化为时间元组
print dt.strftime('%Y-%m-%d %H:%M:%S')
# Out: '2016-12-01 16:14:22'
三. 计算两个时间间隔
计算时间间隔使用datetime
模块比较方便。
datetime.date为日期对象,最小精度为天。
datetime.datetime为日期时间对象,最小精度为妙(毫秒也可以)
实际使用中按需选择。
- 计算2016-12-1和1990-1-1中间天数和秒数
-
dt = datetime.date(2016,12,1)
- datetime.date(1990,1,1)
dt.days # 间隔天数
# 将字符串转换为datetime.date对象
-
dt_a = datetime.datetime.strptime('2016-12-1',
'%Y-%m-%d')
# datetime.date 无 strptime 方法
-
dt_b = datetime.datetime.strptime('1990-1-1',
'%Y-%m-%d')
# 虽然格式化时间的时候%m为两位数月份
-
# 但是反格式化时一位月份也可工作
dt = dt_a - dt_b
dt.days # 为 间隔天数
-
dt.total_seconds()
# 为 间隔秒数
-
- 计算两个时间戳间隔时间
-
timestamp_a, timestamp_b =
1480582517,
1480472517
-
dt = datetime.datetime.fromtimestamp(timestamp_a)
- datetime.datetime.fromtimestamp(timestamp_b)
print dt.days, dt.total_seconds()
# Out: 1 110000.0
-
四. 获取前N天,或者后N天时间
datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
now = datetime.datetime.now()
before_time = now - datetime.timedelta(days=1)
after_time = now + datetime.timedelta(days=1)
print before_time
# Out: 2016-11-30 17:03:40.420000
print after_time
# Out: 2016-12-02 17:03:40.420000
五. 时间戳相关计算
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。 通过时间戳可以快速直接得到很多信息
ts = int(time.time()) # ts = 1480583196
print ts / 86400 % 7 + 3 # 获取时间戳对应的星期 0 周日 - 6 周六
# Out: 3 # 周四
# ===============
timestamp_a, timestamp_b = 1480582517, 1480472517
ts = timestamp_a - timestamp_b
print ts / 86400 # 获取两个时间戳相隔天数
# ===============
# 获取当天00:00:00的时间戳
ts = int(time.time())
print ts / 86400 * 86400
# Out: 1480550400
# ===============
# 获取当天23:59:59的时间戳
ts = int(time.time())
print ts / 86400 * 86400 + 86400 - 1
# Out: 1480636799
个人认为时间戳才是最有魅力的
六. 各种数据类型间转换
- str > datetime.datetime
-
datetime.datetime.strptime('161201 16:14:22',
'%y%m%d %H:%M:%S')
-
- str > 时间元组
-
dt = datetime.datetime.strptime('161201 16:14:22',
'%y%m%d %H:%M:%S')
dt.timetuple()
# or
-
struct_time = time.strptime('161201 16:14:22',
'%y%m%d %H:%M:%S')
-
- 时间戳 > datetime.datetime 或 datetime.date
datetime.datetime.fromtimestamp(时间戳)
# or
datetime.date.fromtimestamp(时间戳)
- 时间戳 > 时间元组
time.gmtime(时间戳)
- 时间元组 > 时间戳
time.mktime(时间戳)
- 时间元组 > datetime.datetime 或 datetime.date
datetime.datetime.fromtimestamp(time.mktime(时间元组))
# or
datetime.date.fromtimestamp(time.mktime(时间元组))
- 时间戳 > 时间元组
time.gmtime(时间戳)
# or
dt = datetime.datetime.fromtimestamp(时间戳)
dt.timetuple()
七、格式化与反格式化控制字符对照表
字符 |
含义 |
例子 |
---|---|---|
%a |
当地格式的星期缩写 |
Sun,Mon...Sat(en_US);So,Mo...Sa(de_DE) |
%A |
当地格式的星期全拼 |
Sunday,Monday...Saturday(en_US);Sonntag,Montag...Samstag(de_DE) |
%w |
星期的数字表示0表示周日,6表示周六 |
0,1...6 |
%d |
日,当月第几天,两位数 |
01,02...31 |
%b |
当地格式的月份缩写 |
Jan,Feb...Dec(en_US);Jan,Feb...Dez(de_DE) |
%B |
当地格式的月份全拼 |
January, February,...,December(en_US);Januar,Februar...Dezember(de_DE) |
%m |
月份的数字表示,两位数 |
01,02...12 |
%y |
年份表示,不带世纪,两位数 |
00,01...99 |
%Y |
年份表示 |
1970,1971...2016 |
%H |
小时 0-23 |
00,01...23 |
%I |
小时 01-12 |
01,02...12 |
%p |
当地格式的上午下午表示 |
AM,PM(en_US);am,pm(de_DE) |
%M |
分钟,两位数 |
00,01...59 |
%S |
秒,两位数 |
00,01...59 |
%f |
微妙,六位数 |
000000,000001...999999 |
%z |
时区偏移量,表示为+HHMM或-HHMM或空 |
(空),+0000,-0400,+0800 |
%Z |
时区名字 |
(空),UTC, EST, CST |
%j |
日,当年第几天,三位数 |
001,002...366 |
%U |
周,在年第几周,周日为一周的第一天,新年第一个星期日第0周,两位数 |
00,01...53 |
%W |
周,在年第几周,周一为一周的第一天,新年第一个星期一第0周,两位数 |
00,01...53 |
%c |
当地格式的时间日期表示 |
Tue Aug 16 21:30:00 1988 (en_US);Di 16 Aug 21:30:00 1988 (de_DE) |
%x |
当地格式的日期表示 |
08/16/88 (None);08/16/1988 (en_US);16.08.1988 (de_DE) |
%X |
当地格式的时间表示 |
21:30:00 (en_US);21:30:00 (de_DE) |
%% |
%字符 |
% |
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [白话解析] 深入浅出边缘计算
- 变废为宝 | 旧电脑变云数据中心 | Esxi 配置
- 【Java面试总结】Java基础(上篇)
- Esxi安装LEDE(OpenWrt) | 旧电脑变庞路由
- [白话解析] 深入浅出贝叶斯定理
- LEDE(OpenWrt)安装openclash |旁路由技巧 | 配置网络流量全部通过旁路由
- [白话解析] 深入浅出朴素贝叶斯模型原理及应用
- 【Java面试总结】Java基础(下篇)
- 使用现代化的脚本进行 ArcGIS JS API 开发
- TextField suffixIcon点击时TextField 选中弹出键盘<Flutter Bug篇>
- seata redis模式重构之全局事务更新
- 【STM32F407】第7章 RL-TCPnet V7.X网络协议栈移植(RTX5)
- 【STM32F429】第7章 RL-TCPnet V7.X网络协议栈移植(RTX5)
- [白话解析] 深入浅出 极大似然估计 & 极大后验概率估计
- 【STM32H7】第7章 RL-TCPnet V7.X网络协议栈移植(RTX5)