内建的 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. Java多线程编程(五)定时器Timer

    一.定时器Timer的使用 在JDK库中Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类确实TimerTask类,执行计 ...

  2. Vuforia添加虚拟按键

    AR虚拟按键为真实识别图上的按键,通过按键可以实现真实与虚拟之间的按键交流 (一)添加按键 点击target,打开advance,添加虚拟按键,即可在此target下添加虚拟按键 注:虚拟按键无法旋转 ...

  3. 对于Serializable的理解

    对于Serializable的理解 Last Edited: Apr 04, 2019 2:53 PM Tags: java 开始 序列化:把Java对象转换为字节序列的过程. 反序列化:把字节序列恢 ...

  4. windows下搭建开发环境

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...

  5. redis入门(三)

    目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...

  6. Microsoft.Extensions.DependencyInjection 之三:反射可以一战(附源代码)

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  7. Python 加密 shellcode 免杀

    Python 加密 shellcode 免杀 环境准备:   Windows7 32 位系统: Shellcode 使用 kali linux Metasploit 生成 shellcode Wind ...

  8. csps模拟测试70

    又炸了,T1没开$long long$,炸掉$50pts$,昨天因为SB错误挂掉$100pts$. 我kuku了,以后细心点吧.

  9. JVM初体验

    一.设计堆内存溢出异常:OutOfMemoryError: public class Main { public static void main(String[] args) { List<D ...

  10. python——函数的形参和实参、参数

    python的参数分类 python参数可以分为两类:1.定义时的参数--形参(形式参数).2.调用时的参数--实参(实际参数,传参) 实参的规则 实参就是在函数调用的时候,通过函数后面的括号传递给函 ...