24.4 时间对象

    Python 的日期和时间对象类在单独的 datetime 模块中定义。datetime 模块包含处理日期、时间以及日期或时间之差(delta)的类。

    术语箱
    delta 的含义是“差”。这是一个希腊字母,看起来像是一个三角形(Δ)。
    科学和数学领域经常使用希腊字母作为某些量的简写。delta 用于表示两个值之差。

    我们要使用的第一种对象是 datetime 对象。(没错,这个类与模块同名。)datetime 对象包含年、月、日、小时、分和秒。可以像这样创建一个 datetime 对象(在交互模式中):

    空标题文档 - 图1

    下面来看会得到什么:

    >>> print when
    2012-10-24 10:45:56

    我们创建了一个 datetime 对象,名为 when,其中包含日期和时间值。

    创建一个 datetime 对象时,参数的顺序(括号中的数)应当是年、月、日、小时、分和秒。不过如果你记不住这个顺序,也可以按任意顺序放置参数,只是要告诉 Python 各个参数分别表示什么,如下:

    >>> when = datetime.datetime(hour=10, year=2012, minute=45, month=10,
    second=56, day=24)

    还可以对 datetime 对象做一些其他处理,你可以得到单个部分,比如年、日或者分。还可以得到日期和时间的一个格式化字符串。在交互模式中试试下面的代码:

    空标题文档 - 图2

    datetime 对象分日期类和时间类。如果只关心日期,可以使用 date 类,其中只有年、月和日。如果只关心时间,可以使用 time 类,其中只包括小时、分和秒。

    如下所示:

    >>> today = datetime.date(2012, 10, 24)
    >>> some_time = datetime.time(10, 45, 56)
    >>> print today
    2012-10-24
    >>> print some_time
    10:45:56

    类似于 datetime 对象,如果指定了各个参数分别表示什么,完全可以按不同的顺序传入参数:

    >>> today = datetime.date(month=10, day=24, year=2012)
    >>> some_time = datetime.time(second=56, hour=10, minute=45)

    还有一种方法可以把 datetime 对象分解为 date 对象和 time 对象:

    >>> today = when.date()
    >>> some_time = when.time()

    另外可以使 用 datetime 模块中 datetime 类的 combine() 方法把 datetime 对象结合起来构成 datetime 对象:

    空标题文档 - 图3

    我们已经知道了什么是 datetime 对象,也了解了它的一些属性,下面来看如何比较两个 datetime 对象,得到它们的差(两个时间之间间隔多长)。

    两个时间之差

    在仿真中,我们常常需要知道经过了多长时间。例如,在一个电子宠物程序中,可能需要知道上一次给宠物喂食之后过去了多长时间,来确定它是不是饿了。

    datetime 模块为此提供了一个对象类,可以帮助我们得出两个日期或时间之差。这个类名为 timedelta。应该记得 delta 表示“差”。所以 timedelta 就是两个时间之差。

    要创建一个 timedelta,得到两个时间之差,只需要将这两个时间相减,如下:

    空标题文档 - 图4

    注意,将两个 datetime 对象相减时,我们得到的不是另一个 datetime,而是一个 timedelta 对象。Python 会自动完成这一点。

    小段时间

    到目前为止,我们一直都在讨论按整秒度量的时间。但是时间对象(datetimedatetimetimedelta)比这更精确。它们可以精确度量到微秒级,也就是百万分之一秒。

    要了解这一点,可以试试 now() 方法,它会给出计算机时钟的当前时间:

    >>> print datetime.datetime.now()
    2012-10-24 21:25:44.343000

    注意这个时间不仅仅包含秒,还包括不到 1 秒的部分:

    44.343000

    我的计算机上,最后 3 位总是 0,因为我的操作系统的时钟只能精确到毫秒(千分之一秒)。不过对我来说这已经足够精确了!

    有一点很重要,尽管秒部分看起来像是浮点数,但它实际上存储为秒数(整数)和微秒数(整数),也就是 44 秒和 343 000 微秒。要把它转换为浮点数还需要一个小公式。假设有一个名为 some_time 的时间对象,如果希望按浮点数形式得到秒数,相应的公式如下:

    seconds_float = some_time.seconds + some_time.microseconds / float(1000000)

    这里使用 float() 函数来确保不会遭遇整数相除问题。

    空标题文档 - 图5

    可以使用 now() 方法和一个 timedelta 对象来测试你的打字速度。代码清单 24-2 中的程序会显示一条随机消息,用户必须键入这条消息。程序将检查用户键入这条消息所用的时间,然后计算出打字速度。你可以试试看。

    代码清单 24-2 度量时间差——打字速度测试

    空标题文档 - 图6

    关于 timedelta 对象还有一点应当知道。与 datetime 对象不同(datetime 对象包含年、月、日、小时、分和秒(以及微秒)),timedelta 对象只有日、秒和微秒。如果想得到月或年,必须根据天数计算出来。如果希望得到分或小时数,必须根据秒数来计算。