Python/MySQL时间的实际应用记录

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 前言网上关于mysq时间、python时间与时间戳等文章很多,翻来翻去找不到头绪,根据不同博客的写法,挑了几个来测试,这里记录一下。况且,不以实际需求为前提的博文,就是瞎写,估计以后自己都看不懂。

前言

网上关于mysq时间、python时间与时间戳等文章很多,翻来翻去找不到头绪,根据不同博客的写法,挑了几个来测试,这里记录一下。

况且,不以实际需求为前提的博文,就是瞎写,估计以后自己都看不懂。


Mysql 时间类型

在数据库建表的时候,通常有5中字段类型让人选择: TIME、DATE、DATETIME、TIMESTAMP、YEAR,它们又各自是什么格式呢?要写的让自己容易记:

  • TIME类型 :存储空间[3 bytes] - 时间格式[HH:MM:SS] - 时间范围[-838:59:59  到  ~ 838:59:59]
  • DATE类型 :存储空间[3 bytes] - 时间格式[YYYY-MM-DD] - 时间范围[1000-01-01 到 9999-12-31] (可以理解为年月日)
  • DATETIME类型 :存储空间[8 bytes] - 时间格式[YYYY-MM-DD HH:MM:SS] - 时间范围[1000-01-01 00:00:00 到 9999-12-31 23:59:59] (可以理解为年月日时分秒)
  • TIMESTAMP类型 :存储空间[4 bytes] - 时间格式[YYYY-MM-DD HH:MM:SS] - 时间范围[1970-01-01 00:00:01 到 2038-01-19  03:14:07] (以秒为计算)
  • YEAR类型 :存储空间[1 bytes] - 时间格式[YYYY] - 时间范围1901  到  2155

根据上面的类型得知,YEAR这种类型用的稍微少一点,TIME用的估计也不多,比较多的还是DATE、DATETIME和时间戳TIMESTAMP


Python 日期和时间

Python提供了三种时间函数,时间模块time、基本时间日期模块datetime和日历模块Calendar,具体的详细介绍和用法在[菜鸟教程-时间和日期:传送A传送B]有介绍,这里不复制粘贴了。

日历模块Calendar是用的次数比较少的(在爬虫和Django开发的实际应用较少),出现较多的是time模块和dateteime模块:

  • time模块  --  比较接近底层的
  • datetime模块  --  基于time新增了很过功能,提供了更多函数

使用对比

1、获取当前时间

import datetime,time

""" 当前时间 """
print(time.time())
print(datetime.datetime.now())

得到的输出结果是:

1516200437.9920225
2018-01-17 22:47:17.992047

2、当前时间格式化

import datetime,time

""" time当前时间 """
localtime = time.localtime(time.time())
print("本地时间为 :", localtime)
gtime = time.strftime('%Y-%m-%d',localtime)
print("可以把时间转换为 :",gtime)
gltime = time.strftime('%Y-%m-%d %H:%M:%S',localtime)
print("可以把时间转换为 :",gltime)
#------------------------------------------------
""" datetime当前时间 """
localtime = datetime.datetime.now()
gtime = datetime.datetime.now().strftime("%Y-%m-%d")
gltime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(localtime)
print(gtime)
print(gltime)

得到的结果是:

本地时间为 : time.struct_time(tm_year=2018, tm_mon=1, tm_mday=17, tm_hour=22, tm_min=55, tm_sec=46, tm_wday=2, tm_yday=17, tm_isdst=0)
可以把时间转换为 : 2018-01-17
可以把时间转换为 : 2018-01-17 22:55:46
#------------------------------------------------
2018-01-18 08:03:18.760582
2018-01-18
2018-01-18 08:03:18

这里可以看出,用两个模块获得的当前时间都不是人类容易阅读的,都需要通过strftime函数进行格式化。

3、文本时间转换

这里我指的是爬虫获取的其他网站的时间,通常有几种格式:

  • 长时间 -- 2018-01-06 18:35:05、2018-01-06 18:35
  • 日期 --  2018-01-06
  • 月时间 -- 2018-01
  • 时间 --  18:35:05

通常,爬虫得到的时间都是人阅读的,只不过分隔符不同。并且在入库的时候,我希望他们的时间格式是统一的,年月日时分秒或者年月日,如果可以就用时间戳,方便计算(年月日时分秒对应年月日时分秒,年月日不可直接转换为年月日时分秒)。

遇到日期类型2018-01-06的时间格式,是不可以用函数直接转成长时间2018-01-06 18:35:05格式的,报错。当遇到这种情况,而我又想将时间统一,只能进行转换。转换又分为两种,相同时间格式转换与不同时间格式转换:

第一种情形

目标:2018-01-06 18:35:05 转换为2018-01-06 18:35:05

它有两种方法可以满足

方法一的逻辑是不同格式的时间转换要先转成时间数组,然后再由时间数组格式化成想要的类型:

import datetime,time

a = "2013-10-10 23:40:00"  # 想要转换成 a = "2013/10/10 23:40:00"

timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray)
print(timeArray)
print(otherStyleTime)

从输出结果:

time.struct_time(tm_year=2013, tm_mon=10, tm_mday=10, tm_hour=23, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=283, tm_isdst=-1)
2013/10/10 23:40:00

可以看到,先通过time.strptime把它转换成时间数组,然后通过time.strftime把时间数组格式化成我想要的格式。

方法二,由于最终格式化的时间也是字符串str,所以当遇到这种情况的时候,还可以直接用replace来进行转换:

a = "2013-10-10 23:40:00"  # 想要转换成 a = "2013/10/10 23:40:00"

print(a.replace("-", "/"))

输出结果为:

2013/10/10 23:40:00

第二种情形

目标:2018-01-06  转换为2018-01-06 18:35:05

它也有两种方法可以满足

它的逻辑是将年月日的字符串拼接上时分秒,然后再按照上面的两种方法进行转换,比如:

a = "2013-10-10 "  # 想要转换成 a = "2013/10/10 23:40:00"
ac = a + "00:00:00"
print(ac.replace("-", "/"))

得到输出结果

2013/10/10 00:00:00

第三种情形

目标:2018-01-06 18:35:05 转换为2018-01-06

思路与第一种一致,先转换为时间数组,然后再由时间数组进行格式化:

import datetime,time

a = "2013-10-10 23:40:00"  # 想要转换成 a = "2013/10/10"
timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
otherStyleTime = time.strftime("%Y/%m/%d", timeArray)
print(type(timeArray))
print(otherStyleTime)

得到结果输出为(可以看到timeArray的类型是time.struct_time):


2013/10/10

4、时间的比较运算

都知道字符串是不可以进行比较计算的,那么我们就需要用到其他的格式进行。time的strptime转换成时间数组是不可以进行运算的,但是datetime可以。

第一种 ,时间格式相同

import datetime,time

d1 = datetime.datetime.strptime('2012-03-05 17:41:20', '%Y-%m-%d %H:%M:%S')
d2 = datetime.datetime.strptime('2012-03-05 16:41:20', '%Y-%m-%d %H:%M:%S')
delta = d1 - d2
print(type(d1))
print(delta.seconds)
print(delta)

得到的输出是:


3600
1:00:00

从结果上可以看到,格式相同的两种时间,可以通过datetime.datetime.strptime进行转换后再运算,在结果中还可以通过.seconds来计算 相差秒数 和通过.days来计算 相差天数

第二种 ,如果时间格式不一样,但是转换后的类型一样,也是可以比较的:

import datetime,time

d1 = datetime.datetime.strptime('2012/03/05 17:41:20', '%Y/%m/%d %H:%M:%S')

d2 = datetime.datetime.strptime('2012-03-05 16:41:20', '%Y-%m-%d %H:%M:%S')
delta = d1 - d2
print(delta.seconds)
print(delta)

这段代码里面时间的字符串形式就不一样,但是通过同样的函数进行转换后就可以比较计算了。

第三种 ,年月日时分秒与年月日的计算,其实原理是一样的,转换后他们的格式都一样,所以也是可以计算的,2012/03/05 17:41:20与2012-03-05的时间相差:

import datetime,time

d1 = datetime.datetime.strptime('2012/03/05 17:41:20', '%Y/%m/%d %H:%M:%S')
d2 = datetime.datetime.strptime('2012-03-01', '%Y-%m-%d')
delta = d1 - d2
print(delta.days,delta.seconds)
print(delta)
print(type(delta))

输出结果是

4 63680
4 days, 17:41:20

通过print的结果可以得到几点信息:
不同格式的时间在转化后是可以进行比较运算的
可以通过.days和.seconds来进行天数与时分秒的展示
计算后得到的数据类型是 'datetime.timedelta' 而不是str类型

比如计算3天后的时间:

import datetime,time

now = datetime.datetime.now()
delta = datetime.timedelta(days=3)
n_days = now + delta
print(type(n_days))
print(n_days.strftime('%Y-%m-%d %H:%M:%S'))

得到的结果是:


2018-01-21 10:26:14

用datetime.timedelta取得3天时间,然后将当前时间加上3天,得到的是'datetime.datetime'类型数据,变成人类阅读的格式则需要strftime函数进行格式化,最终得到想要的2018-01-21 10:26:14。


5、时间戳

把字符串时间转换为时间戳:

import datetime,time

a = "2013-10-10 23:40:00"
# 转换为时间数组
timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
# 转换为时间戳:
timeStamp = time.mktime(timeArray)
print(timeArray)
print(timeStamp)

输出结果为:

time.struct_time(tm_year=2013, tm_mon=10, tm_mday=10, tm_hour=23, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=283, tm_isdst=-1)
1381419600.0

可以看到time的时间数组与时间戳并不是同一样东西,他们是有区别的


6、strftime与strptime

这两个是python中常用的

strftime函数:

  • 函数接收以时间元组,并返回以可读字符串表示的当地时间,格式由参数format决定。
  • time.strftime(format[, t])
  • format -- 格式字符串。t -- 可选的参数t是一个struct_time对象。
  • 返回以可读字符串表示的当地时间。
import time

t = (2009, 2, 17, 17, 3, 38, 1, 48, 0)
t = time.mktime(t)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(t)))

得到结果输出:

2009-02-17 09:03:38

strptime()
函数根据指定的格式把一个时间字符串解析为时间元组。
time.strptime(string[, format])
string -- 时间字符串。format -- 格式化字符串。
返回struct_time对象。

import datetime,time

d1 = datetime.datetime.strptime('20120305 17:41:20', '%Y%m%d %H:%M:%S')
d2 = datetime.datetime.strptime('2012-03-01', '%Y-%m-%d')
print(d1)
print(d2)

得到结果:

2012-03-05 17:41:20
2012-03-01 00:00:00

时间格式与入库

前面铺垫了这么多,最终的目的还是需要入库。这里以4种数据库时间类型为例:

  • 字段名 => 数据类型
  • r_time       =>        time
  • r_date         =>     date
  • r_datetime  =>    datetime
  • r_timestamp  => timestamp

根据最上方所写的Mysql时间类型,可以得出对应的时间格式为:

  • 时间格式 => 数据类型
  • 17:35:05      =>        time
  • 2018-3-1         =>     date
  • 2018/3/1 17:35  =>    datetime
  • 2018/3/1 17:35  => timestamp

time类型

time类型的格式指定为17:35:05,不可替换为(17-35-05或者17/35/05),会报错

可以简写成17:35,数据库会自动补全后面的00,入库后最终数据17:35:00

如果简写成17,则入库后变成00:00:17

当然,如果更奇葩的写法17:,17:35:这种是会报错的


date类型

date类型的格式指定为2018-3-1与2018/3/1,最终入库格式是(2018-03-01),它会自动补全

可以简写成[18/3/1]、[17/3/1]、[07/3/1]、[97/3/1],数据库会自动补全前面的年份,入库后最终数据2018-03-01、2017-03-01、2007-03-01、1997-03-01

不可简写成[2017]、[2017/3],会报错,必须是完整的日期格式


datetime类型

datetime类型的格式指定为2018-3-1 17:35:00和2018/3/1 17:35:00,最终入库格式是2018-03-01 17:35:00

它是date与time的结合,有很多共同特性

可以简写成[18/3/1 17:35:05]、[17/3/1 17:35]、[07/3/1 17]、[97/3/1 17],数据库会自动补全前面的年份,入库后最终数据2018-03-01 17:35:05、2017-03-01 17:35:00、2007-03-01  17:00:00、1997-03-01 17:00:00。可以看到它自动将时间格式补全成统一格式,这里与time不同的是,如果只写17不写分秒,time会默认将17当成秒,这里则是默认当成小时。

与date一样,年月日不可省略,必须以年月日格式出现


timestamp类型

根据上面的描述,timestamp的入库格式与datetime是一样的,不同的是时间范围和存储空间,它的格式与用法跟datetime一致

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
18天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
29天前
|
人工智能 安全 Java
Java和Python在企业中的应用情况
Java和Python在企业中的应用情况
52 7
|
27天前
|
机器学习/深度学习 Python
堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能
本文深入探讨了堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能。文章详细介绍了堆叠的实现步骤,包括数据准备、基础模型训练、新训练集构建及元学习器训练,并讨论了其优缺点。
44 3
|
27天前
|
机器学习/深度学习 算法 数据挖掘
线性回归模型的原理、实现及应用,特别是在 Python 中的实践
本文深入探讨了线性回归模型的原理、实现及应用,特别是在 Python 中的实践。线性回归假设因变量与自变量间存在线性关系,通过建立线性方程预测未知数据。文章介绍了模型的基本原理、实现步骤、Python 常用库(如 Scikit-learn 和 Statsmodels)、参数解释、优缺点及扩展应用,强调了其在数据分析中的重要性和局限性。
57 3
|
1月前
|
存储 监控 安全
如何在Python Web开发中确保应用的安全性?
如何在Python Web开发中确保应用的安全性?
|
15天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
98 15
|
27天前
|
存储 前端开发 API
Python在移动应用开发中的应用日益广泛
Python在移动应用开发中的应用日益广泛
43 10
|
21天前
|
缓存 开发者 Python
深入探索Python中的装饰器:原理、应用与最佳实践####
本文作为技术性深度解析文章,旨在揭开Python装饰器背后的神秘面纱,通过剖析其工作原理、多样化的应用场景及实践中的最佳策略,为中高级Python开发者提供一份详尽的指南。不同于常规摘要的概括性介绍,本文摘要将直接以一段精炼的代码示例开篇,随后简要阐述文章的核心价值与读者预期收获,引领读者快速进入装饰器的世界。 ```python # 示例:一个简单的日志记录装饰器 def log_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__} with args: {a
34 2
|
21天前
|
机器学习/深度学习 人工智能 自然语言处理
探索未来编程:Python在人工智能领域的深度应用与前景###
本文将深入探讨Python语言在人工智能(AI)领域的广泛应用,从基础原理到前沿实践,揭示其如何成为推动AI技术创新的关键力量。通过分析Python的简洁性、灵活性以及丰富的库支持,展现其在机器学习、深度学习、自然语言处理等子领域的卓越贡献,并展望Python在未来AI发展中的核心地位与潜在变革。 ###
|
27天前
|
机器学习/深度学习 自然语言处理 语音技术
Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧
本文介绍了Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧,并通过TensorFlow和PyTorch等库展示了实现神经网络的具体示例,涵盖图像识别、语音识别等多个应用场景。
52 8