C++ duration | "Time Interval" Guide

C++ duration | "Time Interval" Guide

이 글의 핵심

std::chrono::duration: typed time intervals, unit conversions, and arithmetic—stop mixing raw milliseconds ints in C++11+.

What is duration?

std::chrono::duration is a type that represents a time interval. It serves as one of the fundamental units in the chrono library, alongside time_point, especially when converting units as discussed in Time Conversion.

#include <chrono>

std::chrono::seconds sec(10);
std::chrono::milliseconds ms(1000);
std::chrono::minutes min(1);

Basic Usage

using namespace std::chrono;

seconds s(10);
milliseconds ms(10000);

// Get value
auto count = s.count();  // 10

Practical Examples

Example 1: Time Conversion

using namespace std::chrono;

seconds s(10);

// Higher unit -> Lower unit (implicit)
milliseconds ms = s;  // OK: 10000ms

// Lower unit -> Higher unit (explicit)
seconds s2 = duration_cast<seconds>(ms);  // 10s

Example 2: Time Operations

using namespace std::chrono;

seconds s1(10);
seconds s2(5);

auto sum = s1 + s2;   // 15s
auto diff = s1 - s2;  // 5s
auto mul = s1 * 2;    // 20s
auto div = s1 / 2;    // 5s

if (s1 > s2) {
    std::cout << "s1 is longer" << std::endl;
}

Example 3: Literals

using namespace std::chrono_literals;

auto d1 = 10s;      // seconds
auto d2 = 500ms;    // milliseconds
auto d3 = 100us;    // microseconds
auto d4 = 1min;     // minutes
auto d5 = 2h;       // hours

auto total = 1h + 30min + 45s;

Example 4: Custom duration

using days = std::chrono::duration<int, std::ratio<86400>>;
using weeks = std::chrono::duration<int, std::ratio<604800>>;

days d(7);
weeks w = std::chrono::duration_cast<weeks>(d);  // 1 week

Example 5: Timeout Implementation

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::chrono;

class Timer {
    steady_clock::time_point start_;
    milliseconds timeout_;
    
public:
    Timer(milliseconds timeout) 
        : start_(steady_clock::now()), timeout_(timeout) {}
    
    bool expired() const {
        auto elapsed = steady_clock::now() - start_;
        return elapsed >= timeout_;
    }
    
    milliseconds remaining() const {
        auto elapsed = steady_clock::now() - start_;
        auto remaining = timeout_ - elapsed;
        return remaining > milliseconds::zero() ? remaining : milliseconds::zero();
    }
};

int main() {
    Timer timer(5s);  // 5 second timeout
    
    while (!timer.expired()) {
        std::cout << "Remaining: " << timer.remaining().count() << "ms\n";
        std::this_thread::sleep_for(1s);
    }
    
    std::cout << "Timeout!\n";
}

Example 6: Rate Limiting

#include <chrono>
#include <thread>

class RateLimiter {
    steady_clock::time_point last_call_;
    milliseconds min_interval_;
    
public:
    RateLimiter(milliseconds interval) 
        : last_call_(steady_clock::now()), min_interval_(interval) {}
    
    void wait_if_needed() {
        auto now = steady_clock::now();
        auto elapsed = now - last_call_;
        
        if (elapsed < min_interval_) {
            auto wait_time = min_interval_ - elapsed;
            std::this_thread::sleep_for(wait_time);
        }
        
        last_call_ = steady_clock::now();
    }
    
    void call() {
        wait_if_needed();
        // ... perform rate-limited operation ...
    }
};

int main() {
    RateLimiter limiter(100ms);  // Max 10 calls per second
    
    for (int i = 0; i < 5; ++i) {
        limiter.call();
        std::cout << "Call " << i << '\n';
    }
}

duration_cast

When converting between durations of different units, use duration_cast, floor, ceil, or round, as explained in the Time Conversion Guide.

using namespace std::chrono;

milliseconds ms(1500);

// Truncate
auto s = duration_cast<seconds>(ms);  // 1s

// Round (C++17)
auto s2 = round<seconds>(ms);  // 2s

// Ceiling
auto s3 = ceil<seconds>(ms);  // 2s

// Floor
auto s4 = floor<seconds>(ms);  // 1s

Common Issues

Issue 1: Precision Loss

using namespace std::chrono;

milliseconds ms(1500);
seconds s = duration_cast<seconds>(ms);  // 1s (500ms lost)

// ✅ Use rounding
auto s2 = round<seconds>(ms);  // 2s

Issue 2: Type Mismatch

void func(std::chrono::seconds s) {}

// ❌ Type mismatch
// func(1000);  // Error

// ✅ Explicit construction
func(std::chrono::seconds(10));

// ✅ Using literals
using namespace std::chrono_literals;
func(10s);

Issue 3: Negative duration

using namespace std::chrono;

seconds s1(5);
seconds s2(10);

auto diff = s1 - s2;  // -5s
std::cout << diff.count() << std::endl;  // -5

Issue 4: Zero duration

using namespace std::chrono;

seconds s = seconds::zero();  // 0s
milliseconds ms = milliseconds::zero();

if (s == seconds::zero()) {
    std::cout << "0 seconds" << std::endl;
}

Defined Time Units

// Standard units (C++11)
std::chrono::hours
std::chrono::minutes
std::chrono::seconds
std::chrono::milliseconds
std::chrono::microseconds
std::chrono::nanoseconds

// Added in C++20
std::chrono::days
std::chrono::weeks
std::chrono::months
std::chrono::years

Practical Patterns

Pattern 1: Configurable Timeout

class NetworkClient {
    milliseconds timeout_ = 30s;  // Default 30 seconds
    
public:
    void set_timeout(milliseconds timeout) {
        timeout_ = timeout;
    }
    
    bool connect() {
        auto start = steady_clock::now();
        
        while (true) {
            if (try_connect()) return true;
            
            auto elapsed = steady_clock::now() - start;
            if (elapsed > timeout_) {
                return false;  // Timeout
            }
            
            std::this_thread::sleep_for(100ms);
        }
    }
};

// Usage
NetworkClient client;
client.set_timeout(10s);  // 10 second timeout
client.connect();

Pattern 2: Retry with Backoff

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::chrono;

template<typename Func>
bool retry_with_backoff(Func f, int max_attempts = 5) {
    milliseconds backoff = 100ms;
    
    for (int attempt = 0; attempt < max_attempts; ++attempt) {
        if (f()) return true;
        
        std::cout << "Attempt " << attempt + 1 << " failed, "
                  << "waiting " << backoff.count() << "ms\n";
        
        std::this_thread::sleep_for(backoff);
        backoff *= 2;  // Exponential backoff
    }
    
    return false;
}

// Usage
bool result = retry_with_backoff([]() {
    return try_connect_to_server();
}, 5);

Pattern 3: Performance Measurement

#include <chrono>
#include <iostream>

template<typename Func>
auto measure_time(Func f) {
    auto start = steady_clock::now();
    f();
    auto end = steady_clock::now();
    return duration_cast<milliseconds>(end - start);
}

// Usage
auto elapsed = measure_time([]() {
    // ... some work ...
    std::this_thread::sleep_for(2s);
});

std::cout << "Elapsed: " << elapsed.count() << "ms\n";

Time Zones and Calendar

C++20 Time Zones

C++20 adds timezone support through std::chrono::time_zone and related types.

#include <chrono>
#include <iostream>

using namespace std::chrono;

int main() {
    // Current time in UTC
    auto now = system_clock::now();
    
    // Convert to local time
    auto local_time = zoned_time{current_zone(), now};
    std::cout << "Local: " << local_time << '\n';
    
    // Convert to specific timezone
    auto ny_time = zoned_time{"America/New_York", now};
    std::cout << "New York: " << ny_time << '\n';
    
    auto tokyo_time = zoned_time{"Asia/Tokyo", now};
    std::cout << "Tokyo: " << tokyo_time << '\n';
}

Calendar Operations

#include <chrono>
#include <iostream>

using namespace std::chrono;

int main() {
    // Current date
    auto today = floor<days>(system_clock::now());
    auto ymd = year_month_day{today};
    
    std::cout << "Today: " << ymd << '\n';
    
    // Add duration
    auto next_week = today + weeks{1};
    auto next_week_ymd = year_month_day{next_week};
    
    std::cout << "Next week: " << next_week_ymd << '\n';
    
    // Specific date
    auto christmas = year{2026}/December/25;
    auto christmas_tp = sys_days{christmas};
    
    auto days_until = duration_cast<days>(christmas_tp - today);
    std::cout << "Days until Christmas: " << days_until.count() << '\n';
}

FAQ

Q1: What is duration?

A: A time interval.

Q2: How to convert units?

A:

  • Higher -> Lower: Implicit
  • Lower -> Higher: duration_cast

Q3: Can I perform operations?

A: Yes, you can use +, -, *, /, and comparisons.

Q4: What about literals?

A: Use using namespace std::chrono_literals.

Q5: Precision loss?

A: duration_cast truncates. Use round/ceil/floor for alternatives.

Q6: How do I work with time zones?

A: Use C++20’s zoned_time and time_zone:

auto now = system_clock::now();
auto ny_time = zoned_time{"America/New_York", now};
auto tokyo_time = zoned_time{"Asia/Tokyo", now};

Q7: Can I use duration for dates?

A: C++20 adds days, weeks, months, and years for calendar operations. Use year_month_day for date arithmetic.

Q8: What’s the difference between duration and time_point?

A:

  • duration: Time interval (e.g., “5 seconds”)
  • time_point: Specific point in time (e.g., “2026-03-12 14:30:00”)

Q9: How do I implement a timeout?

A: Compare elapsed time with timeout duration:

auto start = steady_clock::now();
while (true) {
    if (steady_clock::now() - start > timeout) {
        break;  // Timeout
    }
}

Q10: What about negative durations?

A: Negative durations are valid and useful for representing time differences:

auto past = steady_clock::now() - 5s;
auto diff = past - steady_clock::now();  // Negative duration

Q11: Where can I learn more about duration?

A:

Related Posts: Time Conversion: duration_cast and time_point_cast, time_point: Representing Points in Time, Overview of chrono, Stopwatch and Benchmarking.

One-line summary: std::chrono::duration represents time intervals with type-safe unit conversions, arithmetic operations, and C++20 timezone support.

## 같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

- [C++ 시간 변환 | chrono duration_cast와 시계 변환](/blog/cpp-time-conversion/)
- [C++ time_point | "시간 지점" 가이드](/blog/cpp-time-point/)
- [C++ Chrono | "시간 라이브러리" 가이드](/blog/cpp-chrono/)
- [C++ 스톱워치와 벤치마크 | chrono으로 실행 시간 측정하기](/blog/cpp-stopwatch-benchmark/)

---

---

## 이 글에서 다루는 키워드 (관련 검색어)

C++, duration, chrono, time, C++11 등으로 검색하시면 이 글이 도움이 됩니다.