time — 시간 관련 함수¶
time 모듈은 현재 시간과 날짜를 가져오고, 시간 간격을 측정하고, 지연을 수행하는 함수들을 제공합니다.
시간 에포크: Alif 및 i.MX RT 기반 OpenMV Cam은 POSIX 에포크인 1970-01-01 00:00:00 UTC를 사용합니다. STM32 기반 OpenMV Cam은 2000-01-01 00:00:00 UTC 에포크를 사용합니다. 에포크 연도는 런타임에 gmtime(0)[0]으로 확인할 수 있습니다.
실제 달력 날짜/시간 유지: 이를 위해서는 실시간 클록(RTC)이 필요합니다. OpenMV Cam에서 시스템 시간은 machine.RTC 객체에 의해 제공됩니다. 현재 달력 시간은 machine.RTC().datetime(tuple)로 설정할 수 있으며 다음 중 하나로 유지됩니다:
백업 배터리(일부 OpenMV Cam에서는 선택적 구성 요소입니다).
ntptime과 같은 네트워크 시간 프로토콜(네트워크 연결이 필요합니다).전원을 켤 때마다 수동으로 설정. 그러면 RTC는 일반적으로 소프트 리셋 후에도 유지되지만, 백업 배터리가 장착되지 않은 경우 전원이 차단되면 손실됩니다.
달력 시간이 유지되지 않으면, 현재 절대 시간을 참조하는 아래 함수들은 예상대로 동작하지 않습니다.
함수¶
- time.gmtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
- time.localtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
에포크(위 참조) 이후 초 단위로 표현된 시간 secs를
(year, month, mday, hour, minute, second, weekday, yearday)를 담은 8-튜플로 변환합니다. secs가 제공되지 않거나 None이면 RTC의 현재 시간이 사용됩니다.gmtime()함수는 UTC 기준 날짜-시간 튜플을 반환하고,localtime()은 지역 시간 기준 날짜-시간 튜플을 반환합니다.8-튜플의 항목 형식은 다음과 같습니다:
year는 세기를 포함합니다(예: 2014).
month는 1-12입니다
mday는 1-31입니다
hour는 0-23입니다
minute은 0-59입니다
second는 0-59입니다
weekday는 월요일~일요일에 대해 0-6입니다
yearday는 1-366입니다
- time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int¶
이것은 localtime의 역함수입니다. 인자는 localtime과 같은 방식으로 시간을 표현하는 전체 8-튜플입니다. 시간 에포크 이후의 초 수를 정수로 반환합니다.
- time.sleep(seconds: float) None¶
주어진 초 수만큼 대기합니다. seconds는 부동소수점 숫자일 수 있으며, 초의 소수 부분만큼 대기할 수 있습니다. 더 세밀하거나 정수 전용 지연이 필요하면
sleep_ms()및sleep_us()함수를 사용하세요.sleep(0)을 포함하여sleep()을 호출하면 대기 중인 콜백 함수가 호출되는 것이 보장됩니다.
- time.sleep_ms(ms: int) None¶
주어진 밀리초 수만큼 지연하며, 값은 양수이거나 0이어야 합니다.
이 함수는 최소한 주어진 밀리초 수만큼 지연하지만, 인터럽트 핸들러나 다른 스레드 등 다른 처리가 발생해야 하는 경우 더 오래 걸릴 수 있습니다. ms에 0을 전달해도 이러한 다른 처리는 여전히 발생할 수 있습니다. 더 정밀한 지연을 위해서는
sleep_us()를 사용하세요.sleep_ms(0)을 포함하여sleep_ms()를 호출하면 대기 중인 콜백 함수가 호출되는 것이 보장됩니다.
- time.sleep_us(us: int) None¶
주어진 마이크로초 수만큼 지연하며, 값은 양수이거나 0이어야 합니다.
이 함수는 최소한 us 마이크로초의 정확한 지연을 제공하려고 시도하지만, 시스템에 수행해야 할 더 높은 우선순위의 처리가 있는 경우 더 오래 걸릴 수 있습니다.
- time.ticks_ms() int¶
임의의 기준점을 가지며 특정 값 이후에 순환하는, 증가하는 밀리초 카운터를 반환합니다.
순환 값은 명시적으로 노출되지 않지만, 논의를 단순화하기 위해 이를 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()의 인자로 전달하는 것도 이 함수들로부터 잘못된 결과를 초래합니다.
- time.ticks_us() int¶
위의
ticks_ms()와 동일하지만 마이크로초 단위입니다.
- time.ticks_cpu() int¶
ticks_ms()및ticks_us()와 유사하지만, 시스템에서 가능한 가장 높은 해상도를 가집니다. 이것은 보통 CPU 클록이며, 그래서 함수 이름이 그렇게 지어졌습니다. 하지만 반드시 CPU 클록일 필요는 없으며, 시스템에서 사용 가능한 다른 타이밍 소스(예: 고해상도 타이머)가 대신 사용될 수 있습니다. 이 함수의 정확한 타이밍 단위(해상도)는time모듈 수준에서 지정되지 않지만, 특정 포트의 문서에서 더 구체적인 정보를 제공할 수 있습니다. 이 함수는 매우 세밀한 벤치마킹이나 매우 빡빡한 실시간 루프를 위한 것입니다. 이식 가능한 코드에서는 사용을 피하세요. 모든 OpenMV Cam에서 사용할 수 있습니다.
- time.ticks_add(ticks: int, delta: int) int¶
ticks 값을 주어진 수만큼 오프셋하며, 이 수는 양수 또는 음수일 수 있습니다. ticks 값이 주어지면, 이 함수는 틱 값의 모듈러 산술 정의(위의
ticks_ms()참조)에 따라 그보다 delta 틱 이전 또는 이후의 틱 값을 계산할 수 있게 합니다. ticks 매개변수는ticks_ms(),ticks_us(),ticks_cpu()함수 호출(또는 이전의ticks_add()호출)의 직접적인 결과여야 합니다. 그러나 delta는 임의의 정수 또는 수치 표현식일 수 있습니다.ticks_add()는 이벤트/작업의 데드라인을 계산하는 데 유용합니다. (참고: 데드라인을 다루려면ticks_diff()함수를 사용해야 합니다.)예시:
# 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))
- time.ticks_diff(ticks1: int, ticks2: int) int¶
ticks_ms(),ticks_us(),ticks_cpu()함수가 반환한 값들 사이의 틱 차이를 순환할 수 있는 부호 있는 값으로 측정합니다.인자 순서는 뺄셈 연산자와 동일하여,
ticks_diff(ticks1, ticks2)는ticks1 - ticks2와 같은 의미를 가집니다. 그러나ticks_ms()등의 함수가 반환하는 값은 순환할 수 있으므로 그 값들에 직접 뺄셈을 사용하면 잘못된 결과가 발생합니다. 그래서ticks_diff()가 필요하며, 이 함수는 모듈러(더 구체적으로는 환) 산술을 구현하여 순환 값에 대해서도 (값들이 서로 너무 멀리 떨어져 있지 않은 한, 아래 참조) 올바른 결과를 산출합니다. 이 함수는 [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] 범위의 부호 있는 값을 반환합니다(이것은 2의 보수 부호 있는 이진 정수의 전형적인 범위 정의입니다). 결과가 음수이면 ticks1이 ticks2보다 시간상 더 일찍 발생했음을 의미합니다. 그렇지 않으면 ticks1이 ticks2 이후에 발생했음을 의미합니다. 이것은 ticks1과 ticks2가 서로 TICKS_PERIOD/2-1 틱을 넘지 않게 떨어져 있을 때만 성립합니다. 그렇지 않으면 잘못된 결과가 반환됩니다. 구체적으로, 두 틱 값이 TICKS_PERIOD/2-1 틱만큼 떨어져 있으면 그 값이 함수에 의해 반환됩니다. 그러나 두 값 사이에 TICKS_PERIOD/2의 실시간 틱이 경과하면, 함수는 대신 -TICKS_PERIOD/2를 반환합니다. 즉, 결과 값이 가능한 값의 음수 범위로 순환합니다.위 제약에 대한 비공식적 근거: 당신이 표준 12눈금 시계 외에 시간의 경과를 확인할 방법이 없는 방에 갇혀 있다고 가정해 보세요. 그러면 지금 시계판을 보고 13시간 동안(예: 오랫동안 잠들어 버린 경우) 다시 보지 않으면, 마침내 다시 봤을 때 1시간만 지난 것처럼 보일 수 있습니다. 이 실수를 피하려면 시계를 규칙적으로 보면 됩니다. 당신의 애플리케이션도 마찬가지여야 합니다. “너무 긴 잠” 비유는 애플리케이션 동작에도 직접 적용됩니다: 애플리케이션이 단일 작업을 너무 오래 실행하지 않게 하세요. 작업을 단계별로 실행하고 중간중간에 시간 기록을 하세요.
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 으로 알려져 있습니다.
- time.time() int¶
기반 RTC가 위에서 설명한 대로 설정되고 유지된다고 가정하고, 에포크 이후의 초 수를 정수로 반환합니다. RTC가 설정되지 않은 경우, 이 함수는 포트별 기준 시점 이후의 초 수를 반환합니다(배터리 백업 RTC가 없는 임베디드 보드의 경우 보통 전원 켜기 또는 리셋 이후). 이식 가능한 MicroPython 애플리케이션을 개발하려면, 이 함수가 초보다 높은 정밀도를 제공할 것이라고 의존해서는 안 됩니다. 더 높은 정밀도의 절대 타임스탬프가 필요하면
time_ns()를 사용하세요. 상대 시간이 허용된다면ticks_ms()및ticks_us()함수를 사용하세요. 달력 시간이 필요하면 인자 없이gmtime()또는localtime()을 사용하는 것이 더 나은 선택입니다.CPython과의 차이점
CPython에서 이 함수는 Unix 에포크(1970-01-01 00:00 UTC) 이후의 초 수를 부동소수점 값으로, 보통 마이크로초 정밀도로 반환합니다. OpenMV Cam에서는 1초 정밀도의 정수를 반환하며 – 하드웨어는 긴 시간 범위와 1초 미만 정밀도를 모두 float로 표현할 수 없습니다 – 에포크는 보드마다 다릅니다(위의 시간 에포크 참조). 설정된 배터리 백업 RTC가 없으면 대신 전원 켜기/리셋 이후의 초를 셉니다.