[C++20 새기능 소개] 개선된 <chrono>

C++20에서는 날짜와 시간 처리를 더욱 간편하고 정확하게 할 수 있도록 <chrono> 라이브러리에 새로운 기능들이 추가되었습니다. 이번 글에서는 캘린더와 시간대 지원을 중심으로, 이전 버전과 비교하여 어떻게 개선되었는지 알아보겠습니다.

<chrono> 라이브러리의 개선 사항이란 무엇인가요?

C++20에서는 <chrono> 라이브러리가 대폭 확장되어 캘린더 날짜, 시간대, 서식화 등의 기능을 제공합니다. 이를 통해 날짜와 시간을 더욱 직관적이고 정확하게 처리할 수 있으며, 표준화된 방식으로 시간대를 다룰 수 있게 되었습니다.

이전 버전에서는 어떻게 했나요?

C++11부터 도입된 <chrono> 라이브러리는 시간 간격을 표현하는 duration과 시간점을 나타내는 time_point 등을 제공했습니다. 그러나 날짜나 시간대를 직접적으로 처리하는 기능은 부족하여, 다음과 같은 문제점이 있었습니다.

  • 날짜 계산의 어려움: 날짜를 다루기 위해서는 std::tm 구조체나 서드파티 라이브러리를 사용해야 했습니다.
  • 시간대 처리의 복잡성: 표준 라이브러리에서 시간대를 지원하지 않아, 로컬 시간과 UTC 간의 변환이 어려웠습니다.
  • 서식화의 제한: 날짜와 시간을 문자열로 변환하는 기능이 제한적이었습니다.

예제: 이전 방식으로 날짜 처리

#include <iostream>
#include <ctime>

int main() {
    std::time_t t = std::time(nullptr);
    std::tm* localTime = std::localtime(&t);

    std::cout << "현재 시간: "
              << localTime->tm_year + 1900 << "-"
              << localTime->tm_mon + 1 << "-"
              << localTime->tm_mday << " "
              << localTime->tm_hour << ":"
              << localTime->tm_min << ":"
              << localTime->tm_sec << "\n";

    return 0;
}
  • 문제점:
    • std::tm 구조체를 사용하여 날짜와 시간을 직접 구성해야 합니다.
    • 월과 년도를 수동으로 조정해야 합니다.
    • 코드가 장황하고 오류가 발생하기 쉽습니다.

C++20의 <chrono> 라이브러리를 사용한 개선

C++20에서는 <chrono> 라이브러리에 캘린더 날짜, 시간대, 서식화 기능이 추가되어 날짜와 시간을 더욱 편리하게 다룰 수 있습니다.

예제: C++20 방식으로 날짜 처리

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;

    auto now = system_clock::now();
    auto today = floor<days>(now);
    year_month_day ymd = today;

    std::cout << "오늘 날짜: " << ymd << "\n";

    return 0;
}
  • year_month_day 타입을 사용하여 날짜를 표현합니다.
  • 연산자 오버로딩을 통해 날짜를 출력할 수 있습니다.
  • 코드가 간결하고 직관적입니다.

어떻게 좋아졌나요?

  • 직관적인 날짜 표현: year, month, day 등의 타입을 제공하여 날짜를 명확하게 표현할 수 있습니다.
  • 시간대 지원: 표준 라이브러리에서 시간대를 지원하여 로컬 시간과 UTC 간의 변환이 쉬워졌습니다.
  • 서식화 기능 강화: std::format과 함께 사용하여 날짜와 시간을 손쉽게 문자열로 변환할 수 있습니다.
  • 정확한 시간 계산: 윤년 계산 등 복잡한 날짜 계산을 표준 라이브러리에서 지원하므로, 정확한 계산이 가능합니다.

상세한 예제와 비교

1. 날짜 계산

이전 방식

// 특정 날짜에서 30일 후의 날짜 계산
std::tm date = {0, 0, 0, 1, 0, 121}; // 2021-01-01
std::time_t t = std::mktime(&date);
t += 30 * 24 * 60 * 60; // 30일 추가

std::tm* newDate = std::localtime(&t);
std::cout << "새 날짜: "
          << newDate->tm_year + 1900 << "-"
          << newDate->tm_mon + 1 << "-"
          << newDate->tm_mday << "\n";
  • 문제점:
    • 윤년이나 월별 일 수를 고려하지 않으므로 정확하지 않을 수 있습니다.

C++20 방식

using namespace std::chrono;

year_month_day date{2021y, January, 1};
year_month_day newDate = date + days{30};

std::cout << "새 날짜: " << newDate << "\n";
// 출력: 2021-01-31
  • 윤년과 월별 일 수를 자동으로 고려하여 정확한 날짜 계산이 가능합니다.

2. 시간대 처리

이전 방식

  • 표준 라이브러리에서 직접적인 시간대 처리가 불가능하여, 서드파티 라이브러리나 OS 종속적인 코드를 사용해야 했습니다.

C++20 방식

#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono;

    auto now = system_clock::now();

    // 시스템 시간대 가져오기
    auto loc_tz = current_zone();
    zoned_time local_time{loc_tz, now};

    // UTC 시간으로 변환
    zoned_time utc_time{"UTC", now};

    std::cout << "로컬 시간: " << local_time << "\n";
    std::cout << "UTC 시간: " << utc_time << "\n";

    return 0;
}
  • zoned_time과 current_zone()을 사용하여 시간대를 쉽게 다룰 수 있습니다.
  • 로컬 시간과 UTC 시간 간의 변환이 간단해집니다.

3. 날짜와 시간의 서식화

C++20 방식

#include <iostream>
#include <chrono>
#include <format>

int main() {
    using namespace std::chrono;

    auto now = system_clock::now();
    zoned_time local_time{current_zone(), now};

    std::string formatted = std::format("{:%Y-%m-%d %H:%M:%S %Z}", local_time);
    std::cout << "현재 시간: " << formatted << "\n";

    return 0;
}
  • std::format과 {:%Y-%m-%d %H:%M:%S %Z} 서식을 사용하여 날짜와 시간을 원하는 형식으로 출력할 수 있습니다.
  • %Z는 시간대 정보를 출력합니다.

주의 사항

  • 컴파일러 지원: C++20 기능이므로, 이를 지원하는 컴파일러와 표준 라이브러리가 필요합니다.
  • 시간대 데이터베이스: 시간대 정보를 사용하려면 시스템에 IANA 시간대 데이터베이스가 설치되어 있어야 합니다.
  • 네임스페이스 사용: std::chrono 내의 여러 타입과 리터럴을 사용할 때는 using namespace std::chrono;를 통해 네임스페이스를 포함해야 코드가 간결해집니다.

요약

C++20에서의 <chrono> 라이브러리 개선으로 날짜와 시간 처리가 이전보다 훨씬 편리해졌습니다. 직관적인 날짜 타입과 시간대 지원, 그리고 강력한 서식화 기능을 통해 개발자는 복잡한 날짜 계산이나 시간 변환을 쉽게 수행할 수 있습니다. 이는 코드의 정확성과 가독성을 높여주며, 표준화된 방식으로 날짜와 시간을 처리할 수 있게 해줍니다.

 

참고 자료:

 

반응형