본문으로 건너뛰기 C++ Calendar & Timezone | year_month_day

C++ Calendar & Timezone | year_month_day

C++ Calendar & Timezone | year_month_day

이 글의 핵심

C++20 calendar and timezone: year_month_day, zoned_time, weekday for date arithmetic, timezone conversion, and weekday calculation with practical examples.

Introduction

C++20 provides calendar and timezone in the standard library. With year_month_day, zoned_time, weekday, you can concisely implement date arithmetic, timezone conversion, and weekday calculation.

What You Will Learn

  • Represent and perform arithmetic with year_month_day
  • Convert timezones with zoned_time
  • Calculate weekdays with weekday
  • Learn commonly used date/time patterns in production

Table of Contents

  1. Basic Concepts
  2. Practical Implementation
  3. Advanced Usage
  4. Performance Comparison
  5. Real-World Cases
  6. Troubleshooting
  7. Conclusion

Basic Concepts

Main Types

TypeDescriptionExample
year_month_dayDate (year-month-day)2026y / March / 11
year_month_weekdayDate (year-month-weekday)2026y / March / Monday[1]
year_month_day_lastLast day of month2026y / February / last
zoned_timeTime with timezonezoned_time{"Asia/Seoul", now}
weekdayDay of weekMonday, Tuesday, …

Practical Implementation

1) year_month_day - Date Representation

Basic Usage

#include <chrono>
#include <iostream>
using namespace std::chrono;
int main() {
    // Create date
    year_month_day ymd1 = 2026y / March / 11;
    year_month_day ymd2{year{2026}, month{3}, day{11}};
    
    std::cout << ymd1 << std::endl;  // 2026-03-11
    
    // Access elements
    auto y = ymd1.year();
    auto m = ymd1.month();
    auto d = ymd1.day();
    
    std::cout << "Year: " << y << std::endl;  // 2026
    std::cout << "Month: " << m << std::endl;  // Mar
    std::cout << "Day: " << d << std::endl;  // 11
    
    return 0;
}

Date Arithmetic

using namespace std::chrono;
int main() {
    year_month_day today = 2026y / March / 11;
    
    // 1 month later
    auto nextMonth = sys_days{today} + months{1};
    std::cout << year_month_day{nextMonth} << std::endl;  // 2026-04-11
    
    // 10 days later
    auto future = sys_days{today} + days{10};
    std::cout << year_month_day{future} << std::endl;  // 2026-03-21
    
    // 1 year ago
    auto past = sys_days{today} - years{1};
    std::cout << year_month_day{past} << std::endl;  // 2025-03-11
    
    // Date difference
    auto diff = sys_days{today} - sys_days{past};
    std::cout << "Difference: " << diff.count() << " days" << std::endl;  // 365
    
    return 0;
}

2) weekday - Weekday Calculation

Basic Usage

using namespace std::chrono;
int main() {
    year_month_day ymd = 2026y / March / 11;
    auto dp = sys_days{ymd};
    auto wd = weekday{dp};
    
    std::cout << "Weekday: " << wd << std::endl;  // Wed
    
    // Check weekday
    if (wd == Wednesday) {
        std::cout << "Wednesday" << std::endl;
    }
    
    // Weekday index (0 = Sunday)
    std::cout << "Index: " << wd.c_encoding() << std::endl;  // 3
    
    return 0;
}

Find Specific Weekday

using namespace std::chrono;
int main() {
    // First Monday of March 2026
    year_month_weekday ymw = 2026y / March / Monday[1];
    year_month_day ymd{sys_days{ymw}};
    std::cout << "First Monday: " << ymd << std::endl;  // 2026-03-02
    
    // Last Friday of March 2026
    year_month_weekday_last ymwl = 2026y / March / Friday[last];
    year_month_day ymd2{sys_days{ymwl}};
    std::cout << "Last Friday: " << ymd2 << std::endl;  // 2026-03-27
    
    return 0;
}

3) zoned_time - Timezone Conversion

Basic Usage

#include <chrono>
#include <iostream>
using namespace std::chrono;
int main() {
    auto now = system_clock::now();
    
    // Seoul time
    zoned_time seoul{"Asia/Seoul", now};
    std::cout << "Seoul: " << seoul << std::endl;
    
    // New York time
    zoned_time ny{"America/New_York", now};
    std::cout << "New York: " << ny << std::endl;
    
    // UTC
    zoned_time utc{"UTC", now};
    std::cout << "UTC: " << utc << std::endl;
    
    return 0;
}

Timezone Information

using namespace std::chrono;
int main() {
    auto tz = locate_zone("Asia/Seoul");
    std::cout << "Timezone: " << tz->name() << std::endl;  // Asia/Seoul
    
    auto now = system_clock::now();
    auto info = tz->get_info(now);
    std::cout << "Offset: " << info.offset << std::endl;  // +09:00
    std::cout << "Abbreviation: " << info.abbrev << std::endl;  // KST
    
    return 0;
}

4) Validation

using namespace std::chrono;
int main() {
    // Invalid date
    year_month_day ymd1 = 2026y / February / 30;
    
    if (!ymd1.ok()) {
        std::cout << "Invalid date" << std::endl;
    }
    
    // Last day
    year_month_day_last ymdl = 2026y / February / last;
    auto lastDay = year_month_day{ymdl};
    std::cout << "Last day of February: " << lastDay << std::endl;  // 2026-02-28
    
    // Check leap year
    year y = 2024y;
    if (y.is_leap()) {
        std::cout << "2024 is a leap year" << std::endl;
    }
    
    return 0;
}

Advanced Usage

1) Date Calculator

#include <chrono>
#include <iostream>
using namespace std::chrono;
int main() {
    year_month_day birth = 1990y / January / 1;
    year_month_day today = 2026y / March / 11;
    
    auto days_lived = sys_days{today} - sys_days{birth};
    auto years_lived = days_lived.count() / 365;
    
    std::cout << "Birth: " << birth << std::endl;
    std::cout << "Today: " << today << std::endl;
    std::cout << "Days lived: " << days_lived.count() << " days" << std::endl;
    std::cout << "Age: approximately " << years_lived << " years" << std::endl;
    
    return 0;
}

2) Next Business Day Calculation

using namespace std::chrono;
year_month_day next_business_day(year_month_day date) {
    auto dp = sys_days{date};
    
    do {
        dp += days{1};
        auto wd = weekday{dp};
        
        if (wd != Saturday && wd != Sunday) {
            return year_month_day{dp};
        }
    } while (true);
}
int main() {
    year_month_day friday = 2026y / March / 13;  // Friday
    year_month_day next = next_business_day(friday);
    
    std::cout << "Friday: " << friday << std::endl;
    std::cout << "Next business day: " << next << std::endl;  // 2026-03-16 (Monday)
    
    return 0;
}

3) Meeting Time Conversion

using namespace std::chrono;
int main() {
    // Seoul time 2026-03-11 14:00
    auto seoul_tz = locate_zone("Asia/Seoul");
    auto local_time = local_days{2026y / March / 11} + hours{14};
    zoned_time seoul{seoul_tz, local_time};
    
    std::cout << "Seoul: " << seoul << std::endl;
    
    // Convert to New York time
    zoned_time ny{"America/New_York", seoul.get_sys_time()};
    std::cout << "New York: " << ny << std::endl;
    
    // Convert to London time
    zoned_time london{"Europe/London", seoul.get_sys_time()};
    std::cout << "London: " << london << std::endl;
    
    return 0;
}

Performance Comparison

C++20 chrono vs External Libraries

LibraryTimezone DBCompile TimeRuntime Performance
C++20 chronoSystemFastFast
date.h (Howard Hinnant)Built-inMediumFast
Boost.DateTimeBuilt-inSlowMedium
Conclusion: C++20 chrono is standard and performs excellently

Real-World Cases

Case 1: Reservation System - Timezone Conversion

#include <chrono>
#include <iostream>
#include <string>
using namespace std::chrono;
struct Reservation {
    std::string customer;
    zoned_time<std::chrono::seconds> time;
};
int main() {
    // Seoul customer reserves at 2026-03-11 14:00
    auto seoul_tz = locate_zone("Asia/Seoul");
    auto local_time = local_days{2026y / March / 11} + hours{14};
    zoned_time seoul{seoul_tz, local_time};
    
    Reservation res{"Kim", seoul};
    
    std::cout << "Reservation time (Seoul): " << res.time << std::endl;
    
    // Check from New York office
    zoned_time ny{"America/New_York", res.time.get_sys_time()};
    std::cout << "Reservation time (New York): " << ny << std::endl;
    
    return 0;
}

Troubleshooting

Problem 1: sys_days Conversion

Symptom: Compilation error when converting year_month_day to sys_days

using namespace std::chrono;
// ❌ Direct arithmetic
year_month_day ymd = 2026y / March / 11;
auto future = ymd + days{10};  // Error
// ✅ Convert to sys_days
auto future = sys_days{ymd} + days{10};
auto result = year_month_day{future};

Problem 2: Timezone Name

Symptom: runtime_error with incorrect timezone name

// ❌ Incorrect timezone name
try {
    auto tz = locate_zone("Seoul");  // Wrong
} catch (const std::runtime_error& e) {
    std::cout << "Error: " << e.what() << std::endl;
}
// ✅ Correct timezone name
auto tz = locate_zone("Asia/Seoul");
// Check timezone list
auto& db = get_tzdb();
for (const auto& zone : db.zones) {
    std::cout << zone.name() << std::endl;
}

Problem 3: End of Month Handling

Symptom: January 31 + 1 month = February 31 (invalid)

using namespace std::chrono;
year_month_day jan31 = 2026y / January / 31;
// ❌ Simple addition
auto feb31 = sys_days{jan31} + months{1};
auto ymd = year_month_day{feb31};
std::cout << ymd << std::endl;  // 2026-03-03 (overflow)
// ✅ End of month handling
year_month_day_last ymdl = jan31.year() / (jan31.month() + months{1}) / last;
auto feb_last = year_month_day{ymdl};
std::cout << feb_last << std::endl;  // 2026-02-28

Problem 4: DST (Daylight Saving Time) Handling

Symptom: 1-hour difference during timezone conversion

using namespace std::chrono;
int main() {
    // US DST starts: Second Sunday of March 02:00
    auto ny_tz = locate_zone("America/New_York");
    
    // Before DST
    auto before_dst = local_days{2026y / March / 8} + hours{1};
    zoned_time ny_before{ny_tz, before_dst};
    std::cout << "Before DST: " << ny_before << std::endl;
    
    // After DST
    auto after_dst = local_days{2026y / March / 9} + hours{1};
    zoned_time ny_after{ny_tz, after_dst};
    std::cout << "After DST: " << ny_after << std::endl;
    
    // Offset difference
    auto info_before = ny_tz->get_info(ny_before.get_sys_time());
    auto info_after = ny_tz->get_info(ny_after.get_sys_time());
    
    std::cout << "Offset before: " << info_before.offset << std::endl;  // -05:00
    std::cout << "Offset after: " << info_after.offset << std::endl;   // -04:00
    
    return 0;
}

Conclusion

C++20 calendar and timezone enable concise date/time handling in the standard library.

Key Summary

  1. year_month_day
    • Date representation and arithmetic
    • 2026y / March / 11
  2. weekday
    • Weekday calculation
    • weekday{sys_days{ymd}}
  3. zoned_time
    • Timezone conversion
    • zoned_time{"Asia/Seoul", now}
  4. Validation
    • ok() method
    • year_month_day_last

Selection Guide

SituationType
Date representationyear_month_day
Weekday calculationweekday
Timezone conversionzoned_time
End of monthyear_month_day_last
Find specific weekdayyear_month_weekday

Code Example Cheatsheet

// Create date
year_month_day ymd = 2026y / March / 11;
// Date arithmetic
auto future = sys_days{ymd} + days{10};
auto diff = sys_days{ymd1} - sys_days{ymd2};
// Weekday calculation
auto wd = weekday{sys_days{ymd}};
// Timezone conversion
zoned_time seoul{"Asia/Seoul", now};
zoned_time ny{"America/New_York", seoul.get_sys_time()};
// Validation
if (!ymd.ok()) { /* ... */ }
// End of month
year_month_day_last ymdl = 2026y / February / last;

Next Steps

References


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. C++20 calendar and timezone: year_month_day, zoned_time, weekday for date arithmetic, timezone conversion, and weekday.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, calendar, timezone, C++20, chrono, year_month_day.