You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++ STL实现24小时时钟并处理时段判断逻辑?

基于C++ STL的「一天中的时间」处理方案(适配C++23)

核心思路

利用C++20/23 <chrono>库的强类型时间工具,替代原生int解决类型安全问题;通过duration的比较简化跨天区间判断;同时兼容系统时钟的time_point,实现单元测试与实际场景的无缝切换。

实现方案

1. 强类型TimeOfDay封装

封装一天内的时间,基于std::chrono::hours确保类型安全,同时支持从系统时间点构造:

#include <chrono>
#include <stdexcept>

class TimeOfDay {
public:
    // 从小时构造(限制0-23)
    constexpr explicit TimeOfDay(std::chrono::hours h) 
        : m_hours(h) {
        if (h < std::chrono::hours{0} || h >= std::chrono::hours{24}) {
            throw std::invalid_argument("TimeOfDay must be between 0 and 23 hours");
        }
    }

    // 从系统时间点转换为当地时间的小时
    explicit TimeOfDay(const std::chrono::system_clock::time_point& tp) {
        using namespace std::chrono;
        const auto local_tp = current_zone()->to_local(tp);
        const auto dp = floor<days>(local_tp);
        const auto time_since_midnight = local_tp - dp;
        m_hours = floor<hours>(time_since_midnight);
    }

    // 获取小时数
    constexpr std::chrono::hours hours() const noexcept {
        return m_hours;
    }

private:
    std::chrono::hours m_hours;
};

2. 简化时间区间判断

通过duration比较替代复杂的跨天逻辑,夜间判断直接取反早晨和傍晚的条件:

#include <string_view>

constexpr bool isMorning(const TimeOfDay& time) noexcept {
    using namespace std::chrono;
    const auto h = time.hours();
    return h >= hours{6} && h < hours{12}; // 覆盖6:00-11:59
}

constexpr bool isEvening(const TimeOfDay& time) noexcept {
    using namespace std::chrono;
    const auto h = time.hours();
    return h >= hours{18} && h < hours{22}; // 覆盖18:00-21:59
}

constexpr bool isNight(const TimeOfDay& time) noexcept {
    // 无需处理跨天逻辑,直接取反非夜间区间
    return !isMorning(time) && !isEvening(time);
}

constexpr std::string_view getGreetingFor(const TimeOfDay& time) noexcept {
    if (isMorning(time)) {
        return "Good morning "sv;
    }
    if (isEvening(time)) {
        return "Good evening "sv;
    }
    if (isNight(time)) {
        return "Good night "sv;
    }
    return "Hello "sv;
}

3. 单元测试与实际场景适配

  • 单元测试:直接构造指定小时的TimeOfDay,支持编译期断言:
// 编译期测试早晨场景
constexpr TimeOfDay morning{std::chrono::hours{8}};
static_assert(getGreetingFor(morning) == "Good morning "sv);

// 编译期测试傍晚场景
constexpr TimeOfDay evening{std::chrono::hours{19}};
static_assert(getGreetingFor(evening) == "Good evening "sv);

// 编译期测试夜间跨天场景
constexpr TimeOfDay night1{std::chrono::hours{23}};
constexpr TimeOfDay night2{std::chrono::hours{3}};
static_assert(getGreetingFor(night1) == "Good night "sv);
static_assert(getGreetingFor(night2) == "Good night "sv);
  • 实际场景:从系统时钟获取当前时间:
#include <iostream>

int main() {
    const TimeOfDay now{std::chrono::system_clock::now()};
    std::cout << getGreetingFor(now) << "User!\n";
    return 0;
}

关键优势

  • 类型安全:通过std::chrono::hours限制时间范围,避免非法值(如25小时)。
  • 逻辑简洁:夜间判断无需处理跨天区间,直接取反非夜间条件。
  • 原生兼容:支持从system_clock::time_point直接构造,自动转换为当地时间。
  • 编译期支持:核心判断逻辑可在编译期执行,提升单元测试效率。

内容的提问来源于stack exchange,提问作者ulfben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:55:26