Time、

#ifndef TIMESTAMP_HPP
#define TIMESTAMP_HPP

#include <cstdint>
#include <string>
#include <ctime>
#include <sys/time.h>
#include <utility>
#include <iomanip>
#include <sstream>

/**
 * @brief 高精度不可变时间戳类(微秒级)
 */
class Timestamp
{
public:
    /// 构造无效时间戳
    Timestamp() noexcept : microSecondsSinceEpoch_(0) {}

    /// 构造指定时间戳(微秒)
    explicit Timestamp(int64_t microSecondsSinceEpochArg) noexcept
        : microSecondsSinceEpoch_(microSecondsSinceEpochArg) {}

    /// 交换
    void swap(Timestamp& that) noexcept {
        std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_);
    }

    /// 转字符串(秒.微秒,形如:1502851234.123456)
    std::string toString() const;

    /// 转格式化字符串(支持是否显示微秒)
    std::string toFormattedString(bool showMicroseconds = true) const;

    /// 是否有效
    bool valid() const noexcept { return microSecondsSinceEpoch_ > 0; }

    /// 微秒时间戳
    int64_t microSecondsSinceEpoch() const noexcept { return microSecondsSinceEpoch_; }
    /// 秒级时间戳
    time_t secondsSinceEpoch() const noexcept {
        return static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
    }

    /// 当前时间
    static Timestamp now();
    /// 无效时间戳
    static Timestamp invalid() { return Timestamp(); }

    /// Unix秒转Timestamp(可带微秒)
    static Timestamp fromUnixTime(time_t t, int microseconds = 0) {
        return Timestamp(static_cast<int64_t>(t) * kMicroSecondsPerSecond + microseconds);
    }

    static const int kMicroSecondsPerSecond = 1000 * 1000;

    // 友元操作符
    friend bool operator<(const Timestamp& lhs, const Timestamp& rhs) noexcept;
    friend bool operator==(const Timestamp& lhs, const Timestamp& rhs) noexcept;

private:
    int64_t microSecondsSinceEpoch_;
};

// 运算符重载
inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) noexcept {
    return lhs.microSecondsSinceEpoch_ < rhs.microSecondsSinceEpoch_;
}
inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) noexcept {
    return lhs.microSecondsSinceEpoch_ == rhs.microSecondsSinceEpoch_;
}

// 时间差(秒,double,精度足够)
inline double timeDifference(const Timestamp& high, const Timestamp& low) noexcept {
    int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
    return static_cast<double>(diff) / Timestamp::kMicroSecondsPerSecond;
}

// 时间加法
inline Timestamp addTime(const Timestamp& timestamp, double seconds) {
    int64_t delta = static_cast<int64_t>(seconds * Timestamp::kMicroSecondsPerSecond);
    return Timestamp(timestamp.microSecondsSinceEpoch() + delta);
}


#endif // TIMESTAMP_HPP
#include "Timestamp.hpp"
#include <gtest/gtest.h>
#include <thread>
#include <chrono>



// ----------- 单元测试主体 --------------

/**
 * @brief 构造函数与有效性测试
 * - 测试默认构造的无效性
 * - 测试带参构造的有效性
 */
TEST(TimestampTest, ConstructionAndValidity) {
    // 默认无效
    Timestamp t1;
    EXPECT_FALSE(t1.valid()) << "默认构造的时间戳应无效";

    // 有参有效
    Timestamp t2(123456789);
    EXPECT_TRUE(t2.valid()) << "大于0的时间戳应有效";
    EXPECT_EQ(t2.microSecondsSinceEpoch(), 123456789);
}

/**
 * @brief 静态工厂与取值测试
 * - 测试fromUnixTime接口
 * - 测试invalid工厂方法
 */
TEST(TimestampTest, StaticFactoryAndAccess) {
    time_t sec = 1000;
    int usec = 200;
    Timestamp t = Timestamp::fromUnixTime(sec, usec);
    EXPECT_EQ(t.secondsSinceEpoch(), sec);
    EXPECT_EQ(t.microSecondsSinceEpoch(), sec * Timestamp::kMicroSecondsPerSecond + usec);

    Timestamp inv = Timestamp::invalid();
    EXPECT_FALSE(inv.valid()) << "invalid()方法应生成无效时间戳";
}

/**
 * @brief toString 与 toFormattedString 输出格式测试
 * - 测试格式化字符串
 * - 测试微秒显示与不显示
 */
TEST(TimestampTest, StringFormat) {
    time_t sec = 1609459200; // 2021-01-01 00:00:00 UTC
    int usec = 123456;
    Timestamp t = Timestamp::fromUnixTime(sec, usec);

    std::string s = t.toString();
    EXPECT_NE(s.find("."), std::string::npos) << "应包含小数点";

    std::string formattedWith = t.toFormattedString(true);
    std::string formattedWithout = t.toFormattedString(false);

    EXPECT_NE(formattedWith.find("."), std::string::npos) << "showMicroseconds=true 应包含小数点";
    EXPECT_EQ(formattedWithout.find("."), std::string::npos) << "showMicroseconds=false 不应包含小数点";

    // 核心时间字段应匹配
    EXPECT_NE(formattedWith.find("20210101 00:00:00"), std::string::npos);
}

/**
 * @brief now() 当前时间与递增性测试
 * - 测试now生成的时间戳有效
 * - 测试连续now严格递增
 */
TEST(TimestampTest, NowAndIncrement) {
    Timestamp t1 = Timestamp::now();
    EXPECT_TRUE(t1.valid());

    // 休眠一段时间
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    Timestamp t2 = Timestamp::now();

    EXPECT_LT(t1, t2) << "后获取的时间戳应更大";
    EXPECT_GT(timeDifference(t2, t1), 0.0) << "时间差应为正数";
}

/**
 * @brief 比较与等值性测试
 * - 测试等于/小于/大于操作
 */
TEST(TimestampTest, ComparisonOperators) {
    Timestamp t1(1000000);
    Timestamp t2(2000000);

    EXPECT_TRUE(t1 < t2);
    EXPECT_FALSE(t2 < t1);
    EXPECT_TRUE(t1 == t1);
    EXPECT_FALSE(t1 == t2);
}

/**
 * @brief 时间差与加法操作测试
 * - 测试timeDifference函数
 * - 测试addTime正确性
 */
TEST(TimestampTest, TimeDifferenceAndAdd) {
    Timestamp base(1000000); // 1秒
    Timestamp later = addTime(base, 2.5); // 加2.5秒

    EXPECT_EQ(later.microSecondsSinceEpoch(), 1000000 + static_cast<int64_t>(2.5 * Timestamp::kMicroSecondsPerSecond));

    double diff = timeDifference(later, base);
    EXPECT_NEAR(diff, 2.5, 1e-9);
}

/**
 * @brief 边界条件与异常输入测试
 * - 测试负数与极小值
 */
TEST(TimestampTest, EdgeCase) {
    Timestamp tneg(-1234567);
    EXPECT_FALSE(tneg.valid()) << "负数时间戳应无效";

    Timestamp tzero(0);
    EXPECT_FALSE(tzero.valid()) << "0时间戳应无效";
}

/**
 * @brief swap操作测试
 * - 检查swap函数正确交换对象
 */
TEST(TimestampTest, SwapTest) {
    Timestamp t1(1111);
    Timestamp t2(2222);
    t1.swap(t2);
    EXPECT_EQ(t1.microSecondsSinceEpoch(), 2222);
    EXPECT_EQ(t2.microSecondsSinceEpoch(), 1111);
}
#include "Timestamp.hpp"
#include <sys/time.h>
#include <cstdio>

std::string Timestamp::toString() const {
    char buf[32] = {0};
    int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
    int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;
    std::snprintf(buf, sizeof(buf), "%lld.%06lld",
                  static_cast<long long>(seconds),
                  static_cast<long long>(microseconds));
    return buf;
}

std::string Timestamp::toFormattedString(bool showMicroseconds) const {
    char buf[64] = {0};
    time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
    struct tm tm_time;
    gmtime_r(&seconds, &tm_time); // POSIX
    if (showMicroseconds) {
        int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
        std::snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",
            tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
            tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
            microseconds);
    } else {
        std::snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d",
            tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
            tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
    }
    return buf;
}

Timestamp Timestamp::now() {
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    int64_t seconds = tv.tv_sec;
    return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值