HOWTO · Python

Python datetime을 밀리초가 있는 문자열로 변환

Python datetime을 정확히 세 자리 밀리초가 있는 ISO 스타일 또는 사용자 지정 문자열로 변환합니다.

이 페이지의 내용

ISO 스타일 결과가 적합하면 value.isoformat(timespec="milliseconds")를 사용합니다. 사용자 지정 레이아웃이 필요하면 strftime()에서 %f를 사용하고 마지막 세 자리를 제거합니다. 두 방법 모두 마이크로초를 반올림하지 않고 밀리초로 잘라냅니다.

서식 지정은 표현만 바꾸며 datetime 값 자체를 바꾸지 않습니다. 예제는 출력을 정확히 검증할 수 있도록 고정 입력을 사용합니다. 필요한 레이아웃을 선택한 뒤에는 이 생성자를 애플리케이션의 값으로 바꾸세요. 수신 시스템이 오프셋을 기대한다면 서식 지정 전에 값에 시간대를 지정합니다.

isoformat()으로 세 자리 밀리초 정밀도 사용

datetime.isoformat()은 ISO 8601 스타일 문자열에 가장 명확한 선택입니다. timespec="milliseconds" 인수는 초의 소수 부분을 항상 정확히 세 자리로 출력합니다. Python 3.6 이상에서 사용할 수 있습니다.

소문자 복수 문자열 "milliseconds"를 정확히 전달합니다. 지원되는 다른 timespec 값은 다른 정밀도를 선택하고, 알 수 없는 값은 ValueError를 발생시킵니다. 하위 스키마가 일정한 필드 폭을 요구할 때는 기본 "auto" 동작에 의존하는 것보다 이 명시적 매개변수가 낫습니다.

다음 결정적 예제는 시간대가 있는 datetime을 사용하므로, 결과는 isoformat()이 UTC 오프셋을 유지한다는 점도 보여 줍니다.

"""Show the recommended ISO-style millisecond formatting behavior."""

from datetime import datetime, timezone


value = datetime(2026, 9, 16, 12, 34, 56, 789654, tzinfo=timezone.utc)
print(value.isoformat(timespec="milliseconds"))

출력:

2026-09-16T12:34:56.789+00:00

여섯 자리 microsecond 값 789654는 .789가 됩니다. Python은 값을 .790으로 반올림하지 않습니다. timespec은 표시할 구성 요소를 제어하며 제외된 시간 구성 요소는 잘립니다.

문자열이 시스템 간 실제 시점을 식별해야 한다면 시간대가 있는 datetime을 사용합니다. naive 값에는 UTC 오프셋이 없으므로, 형식화된 텍스트만으로는 로컬 시간인지 UTC인지 다른 시간대인지 구분할 수 없습니다.

isoformat()은 객체에 이미 붙어 있는 오프셋을 보존합니다. 값을 UTC로 변환하지 않습니다. 데이터 계약이 UTC를 요구한다면 먼저 datetime을 정규화하세요. 반대로 소비자가 의도적으로 로컬 벽시계 값을 기대할 때만 시간대 변환을 생략합니다.

사용자 지정 레이아웃에는 strftime() 사용

순서, 구분 기호 또는 다른 필드를 제어해야 하면 strftime()을 사용합니다. %f 지시자는 여섯 자리 마이크로초를 생성합니다. [:-3] 슬라이스는 마지막 세 자리를 의도적으로 제거하여 밀리초 정밀도를 남깁니다.

"""Show millisecond precision in a custom datetime string format."""

from datetime import datetime


value = datetime(2026, 9, 16, 12, 34, 56, 789654)
print(value.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3])

출력:

2026-09-16 12:34:56.789

이 슬라이스는 안전합니다. 원래 값에 마이크로초가 없어도 %f가 항상 0으로 채운 여섯 자리 필드를 제공하기 때문입니다. [:-3]를 사용하기 전에 형식 끝에 .%f를 유지하세요. 그렇지 않으면 슬라이스가 다른 필드의 문자를 제거할 수 있습니다.

이 작업은 반올림이 아니라 잘라내기입니다. 예를 들어 789999 마이크로초도 789 밀리초가 됩니다. 명세가 반올림을 요구한다면 서식 지정 전에 datetime을 반올림하고 다음 초로 넘어갈 수 있는 올림을 처리하세요. 단순히 %f를 자르는 것으로는 그 규칙을 구현할 수 없습니다.

가져오기 스타일은 클래스를 호출하는 방법을 결정합니다. from datetime import datetime을 사용하면 datetime.now()를 호출합니다. 대신 import datetime을 작성했다면 datetime.datetime.now()를 호출합니다.

str()과 슬라이싱 경계 이해

단순한 str(value)는 value.isoformat(" ")와 같습니다. 기본 timespec="auto"는 microsecond가 0이면 소수 필드를 생략하고, 그렇지 않으면 여섯 자리 마이크로초를 모두 출력합니다. 따라서 str(value)는 세 자리 밀리초 필드를 보장하지 않으며, 무조건 [:-3]를 적용하는 것은 안전하지 않습니다.

이 가변 폭 동작은 비공식 표시에는 유용하지만 고정 폭 필드에는 맞지 않습니다. 슬라이스 전에 소수점을 확인하면 초를 망가뜨리는 일은 피할 수 있지만, 이미 isoformat(timespec="milliseconds")가 처리하는 논리를 중복하고 시간대 접미사에도 추가 주의가 필요합니다.

이 경계 예제는 밀리초 출력이 999999 마이크로초에서 잘리고, 단수 값 "millisecond"가 유효하지 않다는 점도 보여 줍니다.

"""Expose truncation, zero-microsecond slicing, and invalid-timespec boundaries."""

from datetime import datetime


almost_next_second = datetime(2026, 9, 16, 12, 34, 56, 999999)
without_fraction = datetime(2026, 9, 16, 12, 34, 56)

print(almost_next_second.isoformat(timespec="milliseconds"))
print(str(without_fraction))
print(str(without_fraction)[:-3])

try:
    without_fraction.isoformat(timespec="millisecond")
except ValueError as error:
    print(f"{type(error).__name__}: {error}")

출력:

2026-09-16T12:34:56.999
2026-09-16 12:34:56
2026-09-16 12:34
ValueError: Unknown timespec value

세 번째 줄은 유효한 밀리초 변환이 아닙니다. 입력에 소수 필드가 없어서 :56을 제거합니다. 가변 길이 str() 결과를 슬라이스하지 말고 isoformat(timespec="milliseconds")를 사용하거나 %f가 포함된 형식을 사용하세요.

적절한 방법 선택

기계가 읽는 타임스탬프와 표준 교환에는 isoformat(timespec="milliseconds")를 사용합니다. 0 마이크로초, 잘라내기, 시간대 오프셋을 수동 문자열 조작 없이 처리합니다. 소비자가 사용자 지정 레이아웃을 요구하면 strftime()과 [:-3]를 사용합니다.

편의가 아니라 출력 계약에 따라 선택하세요. isoformat()은 표준화된 날짜-시간 형태를 제공하고, strftime()은 호출자가 정의한 형태를 제공하며, str()은 소수 정밀도가 가변적인 사람이 읽기 쉬운 기본값을 제공합니다. 어떤 경우든 오프셋이 없다는 것이 로컬 시간, 관례상 UTC, 또는 알 수 없는 시간대를 의미하는지 문서화하세요.

이 방법들은 기존 datetime을 서식화합니다. Unix epoch 이후의 밀리초로 변환하거나 문자열을 datetime으로 파싱하지 않습니다. 또한 표시된 세 자리는 밀리초 정밀도를 설명할 뿐, 시계나 저장된 원본 값의 정확도를 반드시 의미하지는 않습니다.