std::chrono::zoned_time
std::chrono::zoned_time (시간대와 시점의 결합 클래스)
시간대(time zone)와 std::chrono::time_point를 논리적으로 짝지어 나타내는 클래스예요. 특정 시간대에서 그 시점이 어떤 시각인지를 표현해요. C++20의 chrono 시간대 지원의 핵심이에요.
출처: cppreference
본문
<chrono> 헤더에 정의돼 있고, 시간대와 해상도가 Duration인 std::chrono::time_point의 논리적 짝을 나타내요.
template<
class Duration,
class TimeZonePtr = const std::chrono::time_zone*
> class zoned_time;
using zoned_seconds = std::chrono::zoned_time<std::chrono::seconds>;
zoned_time의 불변식(invariant)은 항상 유효한 시간대를 가리키고, 그 시간대에서 존재하고 모호하지 않은 시점을 나타낸다는 것이에요. 이 불변식과 일관되게 zoned_time은 이동 생성자나 이동 대입 연산자가 없어요. zoned_time을 이동하려 하면 복사가 수행돼요.
Duration이 std::chrono::duration의 특수화가 아니면 프로그램은 ill-formed예요.
템플릿 인자 TimeZonePtr 덕분에 사용자가 자신만의 시간대 포인터 타입을 제공하고, std::chrono::zoned_traits를 통해 zoned_time의 동작을 더 커스터마이즈할 수 있어요. 커스텀 시간대 타입은 std::chrono::time_zone이 지원하는 모든 연산을 지원할 필요 없고, 실제로 zoned_time에서 호출되는 함수들이 쓰는 것만 지원하면 돼요.
TimeZonePtr는 MoveConstructible이어야 해요. Move-only TimeZonePtr는 허용되지만 쓰기 어려워요. zoned_time이 이동 불가능해지고 저장된 TimeZonePtr에 접근할 수 없기 때문이에요.
- 멤버 타입
duration=std::common_type_t<Duration, std::chrono::seconds>.
멤버 함수:
- 생성자:
zoned_time을 만들 수 있어요. operator=:zoned_time에 값을 대입해요.get_time_zone: 시간대 포인터의 복사본을 얻어요.operator local_time,get_local_time: 저장된 시점을local_time으로 얻어요.operator sys_time,get_sys_time: 저장된 시점을sys_time으로 얻어요.get_info: 저장된 시점에서 시간대에 대한 정보를 얻어요.
비멤버 함수:
operator==(C++20): 두zoned_time값을 비교해요.operator<<(C++20):zoned_time을 스트림에 출력해요.
헬퍼 클래스:
std::formatter<std::chrono::zoned_time>(C++20):zoned_time포맷 지원.std::hash<std::chrono::zoned_time>(C++26): 해시 지원.
헬퍼 특수화로 std::enable_nonlocking_formatter_optimization<chrono::zoned_time<Duration, const chrono::time_zone*>> = true (C++23)가 있어요. std::print와 std::println에서 chrono::zoned_time 객체를 효율적으로 출력하도록 해요.
예제를 보면 여러 시간대의 현재 시각을 출력할 수 있어요.
#include <chrono>
#include <iomanip>
#include <iostream>
#include <string_view>
int main()
{
constexpr std::string_view locations[] =
{
"Africa/Casablanca", "America/Argentina/Buenos_Aires",
"America/Barbados", "America/Indiana/Petersburg",
"Asia/Tokyo", "Australia/Darwin",
};
for (const auto location : locations)
try
{
// 'location'이 시간대 DB에 없으면 예외를 던질 수 있어요
const std::chrono::zoned_time zt{location, std::chrono::system_clock::now()};
std::cout << location << " - Zoned Time: " << zt << '\n';
}
catch (std::runtime_error& ex)
{
std::cout << "Error: " << ex.what() << '\n';
}
}
가능한 출력:
Africa/Casablanca - Zoned Time: 2023-06-29 20:58:34.697449319 +01
America/Argentina/Buenos_Aires - Zoned Time: 2023-06-29 16:58:34.709957354 -03
Asia/Tokyo - Zoned Time: 2023-06-30 04:58:34.710172815 JST
시간대 이름으로 zoned_time을 만들면 해당 시간대에서의 시각(오프셋·약어 포함)을 얻을 수 있어요.