muduo源碼筆記-base-Timestamp

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章