【日志系统-时间戳】
时间戳
相关api函数说明
struct timezone {int tz_minuteswest; int tz_dsttime; /* 夏令时标志 */
};struct timeval tv
{tv_sec; //秒ev_usec; //微秒
}
tz_minuteswest:表示本地时间与格林威治标准时间(GMT)之间的时间差,以分钟为单位。
tz_dsttime: 0-不使用夏令时。1-使用夏令时。2-操作系统自动处理
int gettimeofday(struct timeval *tv, struct timezone *tz);
gettimeofday 函数获取到的时间戳是以 1970 年 1 月 1 日 00:00:00 UTC为起始时间,到当前时刻所经过的秒数和微秒数。
tv:一个指向timeval结构体指针,用于存储获取到的当前时间(秒和微秒)
tz:一个指向timezon结构体的指针,如果不需要获取失去信息,nullptr
struct tm *gmtime_r(const time_t *timep, struct tm *result)
将一个表示秒数的时间戳转换为格林威治标准时间的结构化时间的函数调用。
struct tm {int tm_sec; // 秒,范围从0到60(包括闰秒)int tm_min; // 分,范围从0到59int tm_hour; // 小时,范围从0到23int tm_mday; // 一个月中的第几天,范围从1到31int tm_mon; // 月份,范围从0到11(0表示一月,11表示十二月)int tm_year; // 从1900年开始的年数,例如,2023年表示为123int tm_wday; // 一周中的第几天,范围从0到6(0表示星期日,6表示星期六)int tm_yday; // 一年中的第几天,范围从0到365(0表示1月1日,365表示12月31日)int tm_isdst; // 夏令时标志,如果是夏令时,值为正;如果不是,值为0;如果不确定,值为负
};
与 gmtime
的区别
gmtime
:返回指向静态分配的struct tm
的指针,非线程安全(多线程调用可能覆盖结果)。gmtime_r
:通过用户提供的struct tm
缓冲区存储结果,线程安全。
成员变量
static const int kMinPerSec = 1000 * 1000; // 微秒/秒private:unit64_t micr_
用于存储微妙级别
主要方法:
- now()获取当前时间,精度更高(比time())
static Timestamp Now() //获取当前系统时间的时间戳{ struct timeval tv;gettimeofday(&tv, nullptr);return Timestamp(tv.tv_sec * kMinPerSec + tv.tv_usec);}
Now():静态工厂方法,无需创建对象即可调用,直接通过类名访问(如 Timestamp::Now()
)。
返回一个表示当前时间的新 Timestamp
对象。
适合一次性获取时间点,创建新对象。
const Timestamp&now() //更新当前时间{*this=Now();return *this;}
now():实例方法,必须通过对象调用,用于修改当前对象的时间值。
适合重复使用同一个对象,避免频繁创建新对象(例如在循环中定期更新时间)。
- toString(),toFromattedString() 获取可打印字符串
// 将时间戳转换为 秒.微秒 格式std::string toString() const{time_t sec = micr_ / kMinPerSec;time_t mic = micr_ % kMinPerSec;std::ostringstream oss;oss << sec << "." << std::setfill('0') << std::setw(6) << mic;return oss.str();}
// 转换为格式化字符串 YYYY/MM/DD-HH:MM:SS[.微秒Z]std::string toFormattedString(bool showmicro = false) const{std::ostringstream oss;time_t sec = micr_ / kMinPerSec;time_t mic = micr_ % kMinPerSec;struct tm dtm;gmtime_r(&sec, &dtm); // 使用UTC时间而非本地时间oss << std::put_time(&dtm, "%Y/%m/%d-%H:%M:%S");if (showmicro) {oss << "." << std::setfill('0') << std::setw(6) << mic << "Z";}return oss.str(); }
// 转换为用作文件名的字符串 YYYYMMDDHHMMSS.微秒Zstd::string toFormattedFile() const{const int slen = 32;char buff[slen] = {};time_t sec = micr_ / kMinPerSec;time_t mic = micr_ % kMinPerSec;struct tm dtm = {};gmtime_r(&sec, &dtm);int pos = sprintf(buff, "%04d%02d%02d%02d%02d%02d",dtm.tm_year + 1900, // 年份需要加上1900dtm.tm_mon + 1, // 月份从0开始,需要加1dtm.tm_mday,dtm.tm_hour,dtm.tm_min,dtm.tm_sec);// 添加微秒部分sprintf(buff + pos, ".%06ldZ", mic);return std::string(buff);}