1. Timestamp.h 文件
Timestamp表示的是UTC時間,最小可表示微秒(us)。數據成員microSecondsSinceEpoch_使用int64_t(long long)表示對象,因此作者建議將此值按值傳遞,這樣可以直接存放在寄存器中,提高訪問速度。
#ifndef MUDUO_BASE_TIMESTAMP_H
#define MUDUO_BASE_TIMESTAMP_H
#include "muduo/base/copyable.h"
#include "muduo/base/Types.h"
#include <boost/operators.hpp>
namespace muduo
{
class Timestamp : public muduo::copyable,
public boost::equality_comparable<Timestamp>,
public boost::less_than_comparable<Timestamp>
{
public:
// 默認構造函數,
Timestamp()
: microSecondsSinceEpoch_(0) {}
// 使用特定時間的構造函數
explicit Timestamp(int64_t microSecondsSinceEpochArg)
: microSecondsSinceEpoch_(microSecondsSinceEpochArg) {}
// 交換兩個Timestamp的值
void swap(Timestamp& that)
{
std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_);
}
// 使用默認的複製構造函數、賦值運算符、析構函數
// 時間轉換爲字符串表示
// 實例:1584364560.458500
string toString() const;
// 時間轉換爲格式化的字符串表示
// 實例:20200316 13:16:00
string toFormattedString(bool showMicroseconds = true) const;
// 判斷時間是否有效
bool valid() const { return microSecondsSinceEpoch_ > 0; }
// 返回微秒,僅供內部使用
int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }
// 返回秒數(time_t表示的是秒數)
time_t secondsSinceEpoch() const
{ return static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); }
// 獲取當前時間
static Timestamp now();
static Timestamp invalid()
{
return Timestamp();
}
// 將time_t(秒)轉換爲Timestamp格式(微秒)
static Timestamp fromUnixTime(time_t t)
{
return fromUnixTime(t, 0);
}
static Timestamp fromUnixTime(time_t t, int microseconds)
{
return Timestamp(static_cast<int64_t>(t) * kMicroSecondsPerSecond + microseconds);
}
// 靜態成員變量,每秒多少微秒(10^6)
static const int kMicroSecondsPerSecond = 1000 * 1000;
private:
// 微秒數,使用int64_t表示,可以直接存放寄存器,優化讀取時間
int64_t microSecondsSinceEpoch_;
};
// 時間比較操作,由於繼承自less_than_comparable<Timestamp>
// 因此需要提供 operator< ,其他 >、<=、>=會自動實現
inline bool operator<(Timestamp lhs, Timestamp rhs)
{
return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch();
}
// 時間判等操作,由於繼承自boost::equality_comparable<Timestamp>
// 因此需要提供 operator==操作,!=會自動實現
inline bool operator==(Timestamp lhs, Timestamp rhs)
{
return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch();
}
// 計算兩個時間戳相差的秒數
inline double timeDifference(Timestamp high, Timestamp low)
{
int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
return static_cast<double>(diff) / Timestamp::kMicroSecondsPerSecond;
}
// 實現時間戳+秒數
inline Timestamp addTime(Timestamp timestamp, double seconds)
{
int64_t delta = static_cast<int64_t>(seconds * Timestamp::kMicroSecondsPerSecond);
return Timestamp(timestamp.microSecondsSinceEpoch() + delta);
}
} // namespace muduo
#endif // MUDUO_BASE_TIMESTAMP_H
2. Timestamp.cc
#include "muduo/base/Timestamp.h"
#include <sys/time.h> // time_t,gtime_r,gettimeofday
#include <stdio.h>
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
// 跨平臺的書寫方式,主要是爲了同時支持32位和64位操作系統。
// PRId64表示64位整數,在32位系統中表示long long int,在64位系統中表示long int
// 64位即lld,32位即ld
#include <inttypes.h> // PRId64
using namespace muduo;
static_assert(sizeof(Timestamp) == sizeof(int64_t),
"Timestamp is same size as int64_t");
// 時間轉換爲字符串表示
string Timestamp::toString() const
{
char buf[32] = {0};
int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;
snprintf(buf, sizeof(buf)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds);
return buf;
}
// 時間轉換爲格式化的字符串表示
string Timestamp::toFormattedString(bool showMicroseconds) const
{
char buf[64] = {0};
time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
// 注意:tm是從1900年起的
struct tm tm_time;
gmtime_r(&seconds, &tm_time);
if (showMicroseconds)
{
int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
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
{
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()
{
// timeval存了秒和微秒
struct timeval tv;
gettimeofday(&tv, NULL);
int64_t seconds = tv.tv_sec;
return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}