time – time related functions

时间模块 提供了获取当前时间和日期、测量时间间隔以及进行延迟的函数。

Time Epoch: It is January 1, 1970, 00:00:00 (UTC) on all platforms. Epoch year may be determined with gmtime(0)[0].

在具有底层操作系统(包括某些RTOS)的系统上

  • 通过备用电池(这可能是特定板的附加可选组件)。

  • 使用网络时间协议(需要由端口/用户进行设置)。

  • 由用户在每次开机时手动设置(许多板卡随后会在硬复位时保持RTC时间,尽管有些板卡在这种情况下可能需要重新设置)。

如果实际日历时间不是通过系统/MicroPython RTC维护的,那么以下需要参考当前绝对时间的函数可能不会按预期工作。

Functions

time.timezone([tz])

不传入任何参数时,获取当前的时区,返回时区的字符串。

UIFLOW2:

timezone.svg

传入一个时区的字符串,用于设置时区。tz 的值可以在这个 链接 找到。

UIFLOW2:

timezone1.svg timezone2.svg

time.gmtime([secs])
time.localtime([secs])

将自纪元(见上文)以来的秒数(以秒为单位)转换为一个8元组,其中包含: (年, 月, 日, 小时, 分钟, 秒, 星期几, 年中的第几天)。如果未提供秒数或秒数为None,则使用RTC中的当前时间。

The gmtime() function returns a date-time tuple in UTC, and localtime() returns a date-time tuple in local time.

8元组中的条目格式如下:

  • year includes the century (for example 2014).

  • month is 1-12

  • mday is 1-31

  • hour is 0-23

  • minute is 0-59

  • second is 0-59

  • weekday is 0-6 for Mon-Sun

  • yearday is 1-366

UIFLOW2:

gmtime.svg localtime.svg

time.mktime()

This is inverse function of localtime. It’s argument is a full 8-tuple which expresses a time as per localtime. It returns an integer which is the number of seconds since Jan 1, 2000.

UIFLOW2:

mktime.svg mktime1.svg

time.sleep(seconds)

休眠给定的秒数。一些板卡可能接受浮点数作为秒数来进行小数秒数的休眠。请注意,其他板卡可能不接受浮点参数,为了与它们兼容,请使用 sleep_ms()sleep_us() 函数。

UIFLOW2:

sleep.svg

time.sleep_ms(ms)

延迟给定的毫秒数,应为正数或0。

此函数将至少延迟给定的毫秒数,但如果必须执行其他处理(例如中断处理程序或其他线程),则可能需要更长时间。将0传递给ms仍允许执行其他处理。对于更精确的延迟, 请使用 sleep_us()

UIFLOW2:

sleep_ms.svg

time.sleep_us(us)

延迟给定的微秒数,应为正数或0。

此函数尝试提供至少us微秒的准确延迟,但如果系统有其他更高优先级的处理要执行,则可能需要更长时间。

UIFLOW2:

sleep_us.svg

time.ticks_ms()

返回一个不断增加的毫秒计数器,具有任意参考点,在达到某个值后会回绕。

回绕值并未明确公开,但为了简化讨论,我们将它称为 TICKS_MAX。值的周期是 TICKS_PERIOD = TICKS_MAX + 1。TICKS_PERIOD 保证是 2 的幂,但不同端口可能有所不同。所有 ticks_ms()、ticks_us()、ticks_cpu() 函数都使用相同的周期值(为了简化)。因此,这些函数将返回一个在 [0 .. TICKS_MAX] 范围内的值(包括边界值),总共有 TICKS_PERIOD 个值。请注意,这里只使用非负值。在大多数情况下,你应该将这些函数返回的值视为不透明的。对于这些值,唯一可用的操作是下面描述的 ticks_diff() 和 ticks_add() 函数。

注意:直接在这些值上执行标准数学运算(+,-)或关系运算符(<,<=,>,>=)将导致无效结果。执行数学运算然后将结果作为参数传递给 ticks_diff()`或 `ticks_add() 函数,也会导致这些函数产生无效结果。

UIFLOW2:

ticks_ms.svg

time.ticks_us()

与上面的 ticks_ms() 类似,但单位是微秒。

UIFLOW2:

ticks_ms.svg

time.ticks_cpu()

ticks_ms()ticks_us() 类似,但具有系统中可能达到的最高分辨率。这通常是CPU时钟,因此该函数以这种方式命名。但它不一定是CPU时钟,系统中可用的其他计时源(例如高分辨率计时器)也可以被使用。这个函数的确切计时单位(分辨率)在 time 模块级别上并未指定,但特定端口的文档可能会提供更具体的信息。此函数主要用于非常精细的基准测试或非常严格的实时循环。请避免在可移植代码中使用它。

可用性:并非每个端口都实现了这个函数。

UIFLOW2:

ticks_cpu.svg

time.ticks_add(ticks, delta)

根据给定的数值(可以是正数或负数)来偏移ticks值。给定一个ticks值,此函数允许按照tick值的模运算定义(见上文 ticks_ms() )来计算在此值之前或之后的ticks值delta。ticks参数必须是调用 ticks_ms()ticks_us()ticks_cpu() 函数(或之前调用ticks_add())的直接结果。然而,delta可以是任意整数或数值表达式。 ticks_add() 对于计算事件/任务的截止时间很有用。(注意:你必须使用 ticks_diff() 函数来处理截止时间。)

Examples:

# Find out what ticks value there was 100ms ago
print(ticks_add(time.ticks_ms(), -100))

# Calculate deadline for operation and test for it
deadline = ticks_add(time.ticks_ms(), 200)
while ticks_diff(deadline, time.ticks_ms()) > 0:
    do_a_little_of_something()

# Find out TICKS_MAX used by this port
print(ticks_add(0, -1))

UIFLOW2:

ticks_add.svg

time.ticks_diff(ticks1, ticks2)

测量 ticks_ms()ticks_us()ticks_cpu() 函数返回的值之间的ticks差异,作为一个可能回绕的有符号值。

ticks_diff() 函数的参数顺序与减法运算符相同, ticks_diff(ticks1, ticks2)ticks1 - ticks2 具有相同的意义

上述约束的非正式理由:假设你被锁在一个房间里,除了一个标准的12个刻度的时钟外,没有任何方式来监控时间的流逝

ticks_diff() 的设计是为了适应各种使用模式,其中包括:

  • 带有超时的轮询。在这种情况下,事件的顺序是已知的,你只会处理 ticks_diff() 的正结果:

    # Wait for GPIO pin to be asserted, but at most 500us
    start = time.ticks_us()
    while pin.value() == 0:
        if time.ticks_diff(time.ticks_us(), start) > 500:
            raise TimeoutError
    
  • 事件调度。在这种情况下,如果事件逾期,ticks_diff() 的结果可能为负:

    # This code snippet is not optimized
    now = time.ticks_ms()
    scheduled_time = task.scheduled_time()
    if ticks_diff(scheduled_time, now) > 0:
        print("Too early, let's nap")
        sleep_ms(ticks_diff(scheduled_time, now))
        task.run()
    elif ticks_diff(scheduled_time, now) == 0:
        print("Right at time!")
        task.run()
    elif ticks_diff(scheduled_time, now) < 0:
        print("Oops, running late, tell task to run faster!")
        task.run(run_faster=true)
    

注意: 不要将 time() 的值传递给 ticks_diff() ,你应该对它们使用正常的数学运算。但请注意, time() 也可能会(并且会)溢出。这被称为https://en.wikipedia.org/wiki/Year_2038_problem .

UIFLOW2:

ticks_diff.svg

time.time()

返回自纪元以来的秒数,作为整数,假设底层RTC(实时时钟)已按上述描述设置并维护。如果RTC未设置,此函数将返回自特定端口参考时间点以来的秒数(对于没有电池供电RTC的嵌入式板,通常是从开机或复位开始)。如果你想开发可移植的MicroPython应用程序,你不应该依赖此函数提供高于秒的精度。如果你需要更高的精度或绝对时间戳,请使用 time_ns() 。如果可接受相对时间,则使用 ticks_ms()ticks_us() 函数。如果你需要日历时间,不带参数的 gmtime()localtime() 是更好的选择。

Difference to CPython

在CPython中,此函数返回自Unix纪元(1970年1月1日00:00 UTC)以来的秒数,作为浮点数返回,通常具有微秒级别的精度。而MicroPython中,只有Unix端口使用相同的纪元,如果浮点精度允许,它将返回秒以下的精度。嵌入式硬件通常没有浮点精度来同时表示长时间范围和秒以下的精度,因此它们使用具有秒精度的整数值。一些嵌入式硬件还缺乏电池供电的RTC(实时时钟),因此返回自上次开机或其他与硬件相关的相对时间点(例如重置)以来的秒数。

UIFLOW2:

time.svg

time.time_ns()

类似于 time(),但返回自纪元以来的纳秒数,作为一个整数(通常是一个大整数,因此会在堆上分配)。

UIFLOW2:

None