날짜 및 시간
이 페이지의 내용
개요
이 가이드에서는 PyMongo에서 Python datetime
객체를 처리하는 방법을 배울 수 있습니다.
용어
Python 은 전용 데이터 유형datetime.datetime
을(를) 사용하여 날짜와 시간을 나타냅니다. MongoDB 는 영국 런던을 기준으로 하는 글로벌 시간 표준 인 협정 세계시(UTC) 를 기준으로 datetime
값을 저장합니다.
Naive Datetimes
UTC 오프셋 또는 구역 에 대한 추가 정보를 포함하지 않는 datetime
값은 순진한 것입니다. 다음은 순진한 datetime
객체 의 예시 입니다.
datetime(2002, 10, 27, 14, 0, 0)
날짜/시간 인식
datetime
값은 tzinfo
속성이 포함된 경우 이를 인식 합니다. 이 속성은 UTC 시간과의 값 오프셋, 해당 시간대, 일광 절약 시간제의 적용 여부를 나타냅니다. 다음은 인식 datetime
객체의 예입니다.
datetime(2002, 10, 27, 6, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)
현지화
현지화 는 datetime
값에 시간을 더하거나 빼서 해당 값을 다른 표준 구역 로 변환하는 프로세스 입니다. datetime
값을 현지화하려면 다음 단계를 수행합니다.
pip를 사용하여 Python 환경에
pytz
라이브러리를 설치합니다:pip install pytz
pytz.timezone
객체 를 만듭니다. 대상 구역 를 생성자에 string 로 전달합니다.timezone
객체에서localize()
메서드를 호출하고datetime
값을 전달하여 현지화합니다.
다음 코드 예시에서는 datetime
값을 8시간 오프셋인 "US/Pacific"
표준 시간대로 현지화합니다.
from datetime import datetime from pytz import timezone utc_datetime = datetime(2002, 10, 27, 6, 0, 0) pacific = timezone("US/Pacific") local_datetime = pacific.localize(utc_datetime) print(f"UTC datetime: {utc_datetime}") print(f"Local datetime: {local_datetime}")
UTC datetime: 2002-10-27 06:00:00 Local datetime: 2002-10-27 06:00:00-08:00
구역 문자열의 표준 목록은 시간대 데이터베이스 또는 Wikipedia의 해당 문서를 참조하세요.
중요
PyMongo 를 사용하면 시간이 없는 날짜에 대한 BSON 유형이 없기 때문에 datetime.date
인스턴스를 저장할 수 없습니다. 모든 date
객체를 datetime
객체로 변환한 후 MongoDB 에 저장합니다.
날짜/시간 읽기
PyMongo 를 사용하여 datetime
값을 조회 할 때 운전자 는 이 값을 순수 UTC, 인식 UTC 또는 현지화된 값으로 형식을 지정할 수 있습니다. 다음 섹션에서는 각 종류의 값을 조회 하는 방법을 설명합니다.
이 섹션의 경우 sample_collection
이라는 이름의 MongoDB 컬렉션 에 다음 문서 가 포함되어 있다고 가정합니다. "date"
필드 의 값은 UTC datetime
값입니다.
{"date": datetime(2002, 10, 27, 14, 0, 0)}
나이브 UTC 날짜/시간
기본값 으로 PyMongo 는 추가 정보 없이 UTC datetime
값을 검색합니다. 다음 코드 예시 에서는 샘플 문서 를 검색하고 datetime
값을 출력합니다. 인쇄된 값은 샘플 문서 에 있는 값과 동일합니다.
from datetime import datetime collection = database["sample_collection"] find_result = collection.find_one()["date"] print(f"datetime: {find_result}") print(f"datetime.tzinfo: {find_result.tzinfo}")
datetime: 2002-10-27 14:00:00 datetime.tzinfo: None
UTC 날짜/시간 인식
PyMongo가 인식 datetime
값을 검색하도록 지시하려면 CodecOptions
객체를 생성하고 tz_aware = True
를 생성자에 전달합니다. 그런 다음 CodecOptions
객체를 get_collection()
메서드에 전달합니다.
다음 코드 예시 에서는 샘플 문서 에서 datetime
값을 인식 datetime
로 검색합니다.
from pymongo import MongoClient from datetime import datetime from bson.codec_options import CodecOptions options = CodecOptions(tz_aware = True) collection = database.get_collection("sample_collection", options) find_result = collection.find_one()["date"] print(f"datetime: {find_result}") print(f"datetime.tzinfo: {find_result.tzinfo}")
datetime: 2002-10-27 14:00:00+00:00 datetime.tzinfo: <bson.tz_util.FixedOffset object at 0x104db2b80>
현지화된 날짜/시간
사용자에게 datetime
값을 표시하려는 경우, MongoDB에서 읽은 모든 시간을 특정 시간대로 자동으로 변환하도록 PyMongo에 지시할 수 있습니다. 이렇게 하려면 용어 섹션에 설명된 대로 대상 시간대에 대한 timezone
객체를 만듭니다. 그런 다음 CodecOptions
객체를 만들고 생성자에 다음 인수를 전달합니다.
tz_aware
:True
로 설정합니다.tzinfo
:timezone
객체입니다.
다음 코드 예시 에서는 샘플 문서 를 조회하지만 tz_aware
및 tzinfo
인수를 사용하여 datetime
값을 "US/Pacific"
표준 구역 에 자동으로 현지화합니다.
from pymongo import MongoClient from datetime import datetime from bson.codec_options import CodecOptions import pytz from pytz import timezone pacific = timezone("US/Pacific") options = CodecOptions(tz_aware = True, tzinfo = pacific) collection = database.get_collection("sample_collection", options) find_result = collection.find_one()["date"] print(f"datetime: {find_result}") print(f"datetime.tzinfo: {find_result.tzinfo}")
datetime: 2002-10-27 06:00:00-08:00 datetime.tzinfo: US/Pacific
팁
앞의 예제에서는 컬렉션 수준에서 코덱 옵션을 지정합니다. 클라이언트 또는 데이터베이스 수준에서 코덱 옵션을 지정할 수도 있습니다.
날짜/시간 저장
일관성 을 위해 MongoDB 에 UTC datetime
값만 저장 합니다. PyMongo 를 사용하여 datetime
값이 포함된 필드 를 만들거나 업데이트 할 때 운전자 는 먼저 datetime
값이 순진한지 또는 인식하는지 여부를 확인합니다.
datetime
가 순진한 경우, PyMongo는datetime
이 UTC라고 가정하고 이를 변경하지 않고 MongoDB에 저장합니다.datetime
가 인식하면 PyMongo는 시간을 MongoDB에 저장하기 전에 자동으로 UTC로 변환합니다.
다음 코드 예시에서는 "US/Pacific"
시간대에 현지화된 datetime
값이 포함된 문서를 삽입합니다. PyMongo는 첨부된 시간대를 사용하여 현지 시간을 UTC로 변환합니다. MongoDB에서 문서를 검색할 때 datetime
값은 UTC입니다.
from pymongo import MongoClient from datetime import datetime from pytz import timezone utc_datetime = datetime(2002, 10, 27, 6, 0, 0) pacific = timezone("US/Pacific") local_datetime = pacific.localize(utc_datetime) print(f"datetime before storage: {local_datetime}") collection.insert_one({"date": local_datetime}) find_result = collection.find_one()["date"] print(f"datetime after storage: {find_result}")
datetime before storage: 2002-10-27 06:00:00-08:00 datetime after storage: 2002-10-27 14:00:00
중요
datetime.now()
인수 없이 datetime.now()
메서드를 호출하지 않도록 합니다. 현재 현지 시간을 반환합니다.
대신 항상 현재 시간을 UTC로 반환하는 datetime.now(tz=datetime.timezone.utc)
메서드를 호출하세요.
범위를 벗어난 날짜/시간 처리
Python의 datetime
클래스는 datetime
datetime.min
에서 datetime.max
(연도 1-9999) 사이의 값만 표현할 수 있습니다. Unix epoch 의 모든비트 밀리초 값을 허용하는 BSON 을 사용하면 훨씬 더 범위 의 날짜와 시간을 표현할 수 있습니다.64
PyMongo 로 BSON 시간을 표현하려면 Python의 내장 int
유형에 대한 래퍼인 datetime_ms.DatetimeMS
객체 를 만듭니다. 다음 값 중 하나를 전달하여 DatetimeMS
객체 를 수동으로 만들 수 있습니다.
Unix epoch 이후의 밀리초 수를 나타내는
int
입니다.datetime
객체
다음 코드 예시에서는 연도를 나타내는 int
값( datetime
범위를 벗어난 날짜인146136543)을 전달하여 DatetimeMS
객체를 구성합니다.
from bson.datetime_ms import DatetimeMS out_of_range = DatetimeMS(-(2**62))
PyMongo가 UTC datetime
값을 DatetimeMS
객체로 자동으로 디코딩하도록 지시할 수도 있습니다. 이렇게 하려면 CodecOptions
의 datetime_conversion
매개 변수를 datetime_ms.DatetimeConversion
열거형의 값으로 설정합니다. 다음 섹션에서는 이러한 값에 대해 설명합니다.
팁
DatetimeMS
객체는 DatetimeMS
의 다른 인스턴스에 대한 풍부한 비교 메서드를 지원합니다. DatetimeMS.to_datetime()
메서드를 사용하여 datetime
객체로 변환할 수도 있습니다.
DatetimeConversion.DATETIME
DatetimeConversion.DATETIME
은(는) 기본값 입니다. 이 값으로 인해 PyMongo 는 다음 예시 와 같이 범위를 벗어난 날짜를 디코딩하려고 할 때 오류를 발생시킵니다.
from datetime import datetime from bson import encode, decode from bson.datetime_ms import DatetimeMS out_of_range = DatetimeMS(-(2**62)) val = encode({"date": out_of_range}) decoded = decode(val) print(decoded)
... bson.errors.InvalidBSON: year -146136543 is out of range (Consider Using CodecOptions(datetime_conversion=DATETIME_AUTO) or MongoClient(datetime_conversion='DATETIME_AUTO')). ...
DatetimeConversion.DATETIME_MS
이 값은 날짜가 datetime
범위 내에 있더라도 PyMongo가 DatetimeMS
객체만 반환하도록 지시합니다.
from datetime import datetime from bson import encode, decode from bson.datetime_ms import DatetimeMS from bson.codec_options import CodecOptions, DatetimeConversion val = encode({"date": datetime(1970, 1, 2)}) codec_ms = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_MS) decoded = decode(val, codec_options=codec_ms) print(decoded)
{"date": DatetimeMS(86400000)}
DatetimeConversion.DATETIME_AUTO
이 값은 값이 datetime
범위 내에 있으면 datetime
객체를 반환하고 그렇지 않으면 DatetimeMS
객체를 반환하도록 PyMongo에 지시합니다. 다음 코드 예제에서는 datetime
범위에 있는 날짜/시간 하나와 범위 외부에 있는 날짜/시간 하나를 인코딩 및 디코딩합니다.
from datetime import datetime from bson import encode, decode from bson.datetime_ms import DatetimeMS from bson.codec_options import CodecOptions, DatetimeConversion in_range = encode({"date": datetime(1970, 1, 1)}) out_of_range = encode({"date": DatetimeMS(-(2**62))}) codec_auto = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_AUTO) in_decoded = decode(in_range, codec_options=codec_auto) out_decoded = decode(out_of_range, codec_options=codec_auto) print(f"in-range date: {in_decoded}") print(f"out-of-range date: {out_decoded}")
in-range date: {"date": datetime.datetime(1970, 1, 1, 0, 0)} out-of-range date: {'x': DatetimeMS(-4611686018427387904)}
DatetimeConversion.DATETIME_CLAMP
이 값은 결과 datetime
객체를 "클램핑"하여 객체가 datetime
범위( 999,000 마이크로초로 잘림) 내에 있도록 합니다.
다음 코드 예시에서는 datetime
범위보다 한 날짜 시간 일찍 인코딩 및 디코딩하고 datetime
범위보다 한 날짜 시간 나중에 인코딩 및 디코딩합니다. 결과 값은 허용된 범위의 시작과 끝에 있습니다.
from datetime import datetime from bson import encode, decode from bson.datetime_ms import DatetimeMS from bson.codec_options import CodecOptions, DatetimeConversion before = encode({"date": DatetimeMS(-(2**62))}) after = encode({"date": DatetimeMS(2**62)}) codec_clamp = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_CLAMP) before_decoded = decode(before, codec_options=codec_clamp) after_decoded = decode(after, codec_options=codec_clamp) print(f"datetime before the range: {before_decoded}") print(f"datetime after the range: {after_decoded}")
datetime before the range: {"date": datetime.datetime(1, 1, 1, 0, 0)} datetime after the range: {"date": datetime.datetime(9999, 12, 31, 23, 59, 59, 999000)}
API 문서
PyMongo 에서 날짜 및 시간 작업에 대한 자세한 내용은 다음 API 문서를 참조하세요.
datetime
docs.python.org에서pytz
pypi.org에서