C++ Calendar & Timezone | year_month_day·zoned_time Complete Guide
이 글의 핵심
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
- Basic Concepts
- Practical Implementation
- Advanced Usage
- Performance Comparison
- Real-World Cases
- Troubleshooting
- Conclusion
Basic Concepts
Main Types
| Type | Description | Example |
|---|---|---|
| year_month_day | Date (year-month-day) | 2026y / March / 11 |
| year_month_weekday | Date (year-month-weekday) | 2026y / March / Monday[1] |
| year_month_day_last | Last day of month | 2026y / February / last |
| zoned_time | Time with timezone | zoned_time{"Asia/Seoul", now} |
| weekday | Day of week | Monday, 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
| Library | Timezone DB | Compile Time | Runtime Performance |
|---|---|---|---|
| C++20 chrono | System | Fast | Fast |
| date.h (Howard Hinnant) | Built-in | Medium | Fast |
| Boost.DateTime | Built-in | Slow | Medium |
| 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
- year_month_day
- Date representation and arithmetic
2026y / March / 11
- weekday
- Weekday calculation
weekday{sys_days{ymd}}
- zoned_time
- Timezone conversion
zoned_time{"Asia/Seoul", now}
- Validation
ok()methodyear_month_day_last
Selection Guide
| Situation | Type |
|---|---|
| Date representation | year_month_day |
| Weekday calculation | weekday |
| Timezone conversion | zoned_time |
| End of month | year_month_day_last |
| Find specific weekday | year_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
- Date Parsing: C++ Date Parsing
- duration: C++ duration
- time_point: C++ time_point
References
- “C++20 The Complete Guide” - Nicolai M. Josuttis
- cppreference: https://en.cppreference.com/w/cpp/chrono
- IANA Time Zone Database: https://www.iana.org/time-zones One-line summary: C++20 calendar and timezone concisely implement date arithmetic and timezone conversion in the standard library with year_month_day, zoned_time, and weekday.