内建的 datetime 模块

在跳转到其他库之前,让我们回顾一下如何使用 datetime 模块将日期字符串转换为 Python datetime 对象。

假设我们从 API 接受到一个日期字符串,并且需要它作为 Python datetime 对象存在:

2018-04-29T17:45:25Z

这个字符串包括:

· 日期是 YYYY-MM-DD 格式的

· 字母 T 表示时间即将到来

· 时间是 HH:II:SS 格式的

· 表示此时间的时区指示符 Z 采用 UTC (详细了解日期时间字符格式

要使用 datetime 模块将此字符串转换为 Python datetime 对象,你应该从 strptime 开始。 datetime.strptime 接受日期字符串和格式化字符并返回一个 Python datetime 对象。

我们必须手动将日期时间字符串的每个部分转换为 Python 的 datetime.strptime 可以理解的合适的格式化字符串。四位数年份由 %Y 表示,两位数月份是 %m,两位数的日期是 %d。在 24 小时制中,小时是 %H,分钟是 %M,秒是 %S。

为了得出这些结论,需要在Python 文档的表格中多加注意。

由于字符串中的 Z 表示此日期时间字符串采用 UTC,所以我们可以在格式中忽略此项。(现在,我们不会担心时区。)

转换的代码是这样的:

$ from datetime import datetime 

$ datetime.strptime('2018-04-29T17:45:25Z', '%Y-%m-%dT%H:%M:%SZ')

datetime.datetime(2018, 4, 29, 17, 45, 25)

格式字符串很难阅读和理解。我必须手动计算原始字符串中的字母 T 和 “Z”的位置,以及标点符号和格式化字符串,如 %S 和 %m。有些不太了解 datetime 的人阅读我的代码可能会发现它很难理解,尽管其含义已有文档记载,但它仍然很难阅读。

让我们看看其他库是如何处理这种转换的。

Dateutil

dateutil 模块对 datetime 模块做了一些扩展。

继续使用上面的解析示例,使用 dateutil 实现相同的结果要简单得多:

$ from dateutil.parser import parse

$ parse('2018-04-29T17:45:25Z')

datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

如果字符串包含时区,那么 dateutil 解析器会自动返回字符串的时区。由于我们在 UTC 时区,你可以看到返回来一个 datetime 对象。如果你想解析完全忽略时区信息并返回原生的 datetime 对象,你可以传递 ignoretz=True 来解析,如下所示:

$ from dateutil.parser import parse

$ parse('2018-04-29T17:45:25Z', ignoretz=**True**)

datetime.datetime(2018, 4, 29, 17, 45, 25)

dateutil 还可以解析其他人类可读的日期字符串:

$ parse('April 29th, 2018 at 5:45 pm')

datetime.datetime(2018, 4, 29, 17, 45)

dateutil 还提供了像 relativedelta 的工具,它用于计算两个日期时间之间的时间差或向日期时间添加或删除时间,rrule 创建重复日期时间,tz 用于解决时区以及其他工具。

Arrow

Arrow 是另一个库,其目标是操作、格式化,以及处理对人类更友好的日期和时间。它包含 dateutil,根据其文档,它旨在“帮助你使用更少的包导入和更少的代码来处理日期和时间”。

要返回我们的解析示例,下面介绍如何使用 Arrow 将日期字符串转换为 Arrow 的 datetime 类的实例:

$ import arrow 

$ arrow.get('2018-04-29T17:45:25Z')

<Arrow [2018-04-29T17:45:25+00:00]>

你也可以在 get() 的第二个参数中指定格式,就像使用 strptime 一样,但是 Arrow 会尽力解析你给出的字符串,get() 返回 Arrow 的 datetime 类的一个实例。要使用 Arrow 来获取 Python datetime 对象,按照如下所示链式 datetime:

$ arrow.get('2018-04-29T17:45:25Z').datetime

datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

通过 Arrow datetime 类的实例,你可以访问 Arrow 的其他有用方法。例如,它的 humanize() 方法将日期时间翻译成人类可读的短语,就像这样:

$ import arrow

$ utc= arrow.utcnow()

$ utc.humanize()

'seconds ago'

在 Arrow 的文档中阅读更多关于其有用方法的信息。

Moment

Moment 的作者认为它是“内部测试版”,但即使它处于早期阶段,它也是非常受欢迎的,我们想来讨论它。

Moment 的方法将字符转换为其他更有用的东西很简单,类似于我们之前提到的库:

$ import moment

$ moment.date('2018-04-29T17:45:25Z')

<Moment(2018-04-29T17:45:25)>

就像其他库一样,它最初返回它自己的 datetime 类的实例,要返回 Python datetime 对象,添加额外的 date() 调用即可。

$ moment.date('2018-04-29T17:45:25Z').date

datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<StaticTzInfo 'Z'>)

这将 Moment datetime 类转换为 Python datetime 对象。

Moment 还提供了使用人类可读的语言创建新日期的方法。例如创建一个明天的日期:

$ moment.date("tomorrow")

<Moment(2018-04-06T11:24:42)>

它的 add() 和 subtract() 命令使用关键字参数来简化日期的操作。为了获得后天,Moment 会使用下面的代码:

$ moment.date("tomorrow").add(days=1)

<Moment(2018-04-07T11:26:48)>

Maya

Maya 包含了 Python 中其他流行处理日期时间的库,包括 Humanize、 pytz 和 pendulum 等等。这个项目旨在让人们更容易处理日期。

Maya 的 README 包含几个有用的实例。以下是如何使用 Maya 来重新处理以前的解析示例:

$ import maya

$ maya.parse('2018-04-29T17:45:25Z').datetime()

datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<UTC>)

注意我们必须在 maya.parse() 之后调用 datetime()。如果我们跳过这一步,Maya 将会返回一个 MayaDT 类的示例:。

由于 Maya 与 datetime 库中很多有用的方法重叠,因此它可以使用 MayaDT 类的实例执行诸如使用 slang_time() 方法将时间偏移量转换为纯文本语言,并将日期时间间隔保存在单个类的实例中。以下是如何使用 Maya 将日期时间表示为人类可读的短语:

$ import maya

$ maya.parse('2018-04-29T17:45:25Z').slang_time()

'23 days from now

显然,slang_time() 的输出将根据距离 datetime 对象相对较近或较远的距离而变化。

Delorean

Delorean,以 《返回未来》 电影中的时间旅行汽车命名,它对于操纵日期时间特别有用,包括将日期时间转换为其他时区并添加或减去时间。

Delorean 需要有效的 Python datetime 对象才能工作,所以如果你需要使用时间字符串,最好将其与上述库中的一个配合使用。例如,将 Maya 与 Delorean 一起使用:

$ import maya 

$ d_t= maya.parse('2018-04-29T17:45:25Z').datetime()

现在,你有了一个 datetime 对象 d_t,你可以使用 Delorean 来做一些事情,例如将日期时间转换为美国东部时区:

$ from delorean import Delorean

$ d= Delorean(d_t)

$ d

Delorean(datetime=datetime.datetime(2018, 4, 29, 17, 45, 25), timezone='UTC')

$ d.shift('US/Eastern')

Delorean(datetime=datetime.datetime(2018, 4, 29, 13, 45, 25), timezone='US/Eastern')

看到小时是怎样从 17 变成 13 了吗?

你也可以使用自然语言方法来操作 datetime 对象。获取 2018 年 4 月 29 日之后的下个星期五(我们现在使用的):

$ d.next_friday()

Delorean(datetime=datetime.datetime(2018, 5, 4, 13, 45, 25), timezone='US/Eastern')

在 Delorean 的文档中阅读更多关于其的用法。

Freezegun

Freezegun 是一个可以帮助你在 Python 代码中测试特定日期的库。使用 @freeze_time 装饰器,你可以为测试用例设置特定的日期和时间,并且所有对 datetime.datetime.now()、 datetime.datetime.utcnow() 等的调用都将返回你指定的日期和时间。例如:

from freezegun import freeze_time

import datetime

@freeze_time("2017-04-14")

def test(): 

    **assert** datetime.datetime.now()== datetime.datetime(2017, 4, 14)

要跨时区进行测试,你可以将 tz_offset 参数传递给装饰器。freeze_time 装饰器也接受更简单的口语化日期,例如 @freeze_time('April 4, 2017')。

上面提到的每个库都提供了一组不同的特性和功能,也许很难决定哪一个最适合你的需要。Maya 的作者, Kenneth Reitz 说到:“所有这些项目相辅相成,它们都是我们的朋友”。

这些库共享一些功能,但不是全部。有些擅长时间操作,有些擅长解析,但它们都有共同的目标,即让你对日期和时间的工作更轻松。下次你发现自己对 Python 的内置 datetime 模块感到沮丧,我们希望你可以选择其中的一个库进行试验。

更多Python技术文章请关注2019,Python技术持续更新(附教程)

程序员常用6 个 Python 的日期时间库的更多相关文章

  1. Java程序员常用工具类库

    有人说当你开始学习Java的时候,你就走上了一条不归路,在Java世界里,包罗万象,从J2SE,J2ME,J2EE三大平台,到J2EE中的13中核心技术,再到Java世界中万紫千红的Framework ...

  2. 程序员如何高效学Python,如何高效用Python挣钱

    本人在1年半之前,不熟悉Python(不过有若干年Java开发基础),由于公司要用Python,所以学习了一通.现在除了能用Python做本职工作外,还出了本Python书,<基于股票大数据分析 ...

  3. Spring MVC 程序首页的设置 - 一号门-程序员的工作,程序员的生活(java,python,delphi实战)

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  4. JAVA程序员常用英语

    JAVA程序员常用英语 干程序员这行实在是离不开英语,干程序员是一项很辛苦的工作,要成为一个高水平的程序员尤为艰难.这是因为计算机软件技术更新的速度越来越快,而这些技术大多来源于英语国家,我们在引进这 ...

  5. 【常用软件】木木的常用软件点评(2)------VC程序员常用工具篇

     摘自:http://blog.csdn.net/liquanhai/article/details/7215045 木木的常用软件点评(2)------VC程序员常用工具篇 分类: VC++经验总结 ...

  6. Java程序员常用的@Component、@Repository、@Controller、@Service系列【案例demo3】

    Java程序员常用的@Component.@Repository.@Controller.@Service系列[案例demo3]   很多程序员通过在类上使用@Repository.@Componen ...

  7. 平分的直线 牛客网 程序员面试金典 C++ Python

    平分的直线 牛客网 程序员面试金典 C++ Python 题目描述 在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分.假定正方形的上下两条边与x轴平行. 给定两个vecotrA和B ...

  8. 奇偶位交换 牛客网 程序员面试金典 C++ Python

    奇偶位交换 牛客网 程序员面试金典 C++ Python 题目描述 请编写程序交换一个数的二进制的奇数位和偶数位.(使用越少的指令越好) 给定一个int x,请返回交换后的数int. 测试样例: 10 ...

  9. 字符串压缩 牛客网 程序员面试金典 C++ Python

    字符串压缩 牛客网 程序员面试金典 C++ Python 题目描述 利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能.比如,字符串"aabcccccaaa"经压缩会变 ...

随机推荐

  1. 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP)

    wechat github 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP) 概述 公众号开发是痛苦的,痛苦在好多问题开发者文档是没有提到的,是需要你猜的. 在开发过程中 ...

  2. 函数基础(二)(day11整理)

    目录 昨日内容 函数的定义 函数的三种定义方式 空函数 有参函数 无参函数 函数的调用 函数的返回值 函数的参数 形参 实参 今日内容 可变长参数 可变长形参 可变长实参(仅作了解) 函数对象 函数嵌 ...

  3. Mysql数据库(七)触发器

    一.MySQL触发器 触发器是由MySQL的基本命令事件来触发某种特定操作,这些基本的命令由INSERT.UPDATE.DELETE等事件来触发某些特定操作.满足触发器的触发条件时,数据库系统就会自动 ...

  4. Spring IoC的概念

    Spring IoC的基础知识 Spring 框架可以说是Java世界中最成功的框架,它的成功来自于理念,而不是技术,它最核心的理念是IoC(控制反转)和AOP(面向切面编程),其中IoC是Sprin ...

  5. spring cloud 2.x版本 Eureka Server服务注册中心教程

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 1.创建服务注册中心 1.1 新建Spring boot工程:eureka-server 1 ...

  6. yii2中commands的简单应用

    class HelloController extends Controller { /** * This command echoes what you have entered as the me ...

  7. mysql设计规范二

    一.基本规范 必须使用InnoDB存储引擎 必须使用UTF8字符集 数据表.数据字段必须加入中文注释 二.设计规范 库名称.表名称.字段名称必须使用小写,最好不要使用驼峰式,使用“_”区分,例如use ...

  8. NOIP模拟 21

    可爱的Dybala走了..(当然只是暂时) 又考了大众分.从rank5到rank17一个分. T1 折纸 秒切,爽啊 天皇偷看我代码,结束看见我A了还很惊讶,说我代码有锅 好沙雕哦 就跟个2b似的. ...

  9. 「NOIP模拟赛」数位和乘积(dp,高精)

    统计方案数,要么组合数,要么递推(dp)了. 这是有模拟赛历史以来爆炸最狠的一次 T1写了正解,也想到开long long,但是开错了地方然后数组开大了结果100->0 T3看错题本来简单模拟又 ...

  10. Machine Learning in Action ---- kNN

    ------------恢复内容开始------------ # -*- coding: utf-8 -*- """ Created on Thu Nov 14 19:2 ...