1、直接上干货!
新建文件timestamp.h,内容如下:
#pragma once
/***************************************************
* created: 2024.11.17
* filename:
* file path:
* author: YZS
*
* purpose: 时间戳类
*****************************************************
* Release Note :****************************************************/
#include <string>
#include <stdint.h>#define INVALID_TIMESTAMP (0)namespace system{/** A system independent time type, it holds the the number of 100-nanosecond intervals since January 1, 1601 (UTC).* \sa system::getCurrentTime, system::timeDifference, INVALID_TIMESTAMP, TTimeParts*/typedef uint64_t TTimeStamp;/** The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).* \sa TTimeStamp, timestampToParts, buildTimestampFromParts*/struct TTimeParts{uint16_t year; /** The year */uint8_t month; /** Month (1-12) */uint8_t day; /** Day (1-31) */uint8_t hour; /** Hour (0-23) */uint8_t minute; /** Minute (0-59) */double second; /** Seconds (0.0000-59.9999) */uint8_t day_of_week; /** Day of week (1:Sunday, 7:Saturday) */int daylight_saving;};/** Builds a timestamp from the parts (Parts are in local time)* \sa timestampToParts, buildTimestampFromParts*/system::TTimeStamp buildTimestampFromPartsLocalTime(const system::TTimeParts& p);/** Gets the individual parts of a date/time (days, hours, minutes, seconds) - UTC time or local time* \sa buildTimestampFromParts*/void timestampToParts(TTimeStamp t, TTimeParts& p, bool localTime = false);/** Returns the current (UTC) system time.* \sa now,getCurrentLocalTime*/system::TTimeStamp getCurrentTime();/** A shortcut for system::getCurrentTime* \sa getCurrentTime, getCurrentLocalTime*/inline system::TTimeStamp now() {return getCurrentTime();}/** Returns the current (local) time.* \sa now,getCurrentTime*/system::TTimeStamp getCurrentLocalTime();/** Transform from standard "time_t" (actually a double number, it can contain fractions of seconds) to TTimeStamp.* \sa timestampTotime_t*/system::TTimeStamp time_tToTimestamp(const double t);/** Transform from standard "time_t" to TTimeStamp.* \sa timestampTotime_t*/system::TTimeStamp time_tToTimestamp(const time_t& t);/** Transform from TTimeStamp to standard "time_t" (actually a double number, it can contain fractions of seconds).* \sa time_tToTimestamp, secondsToTimestamp*/double timestampTotime_t(const system::TTimeStamp t);/** Transform from TTimeStamp to standard "time_t" (actually a double number, it can contain fractions of seconds).* This function is just an (inline) alias of timestampTotime_t(), with a more significant name.* \sa time_tToTimestamp, secondsToTimestamp*/inline double timestampToDouble(const system::TTimeStamp t) { return timestampTotime_t(t); }double timeDifference(const system::TTimeStamp t_first, const system::TTimeStamp t_later); //!< Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds \sa secondsToTimestamp/** Returns the current time, as a `double` (fractional version of time_t) instead of a `TTimeStamp`.* \sa now(), timestampTotime_t() */inline double now_double() {return system::timestampTotime_t(system::getCurrentTime());}system::TTimeStamp timestampAdd(const system::TTimeStamp tim, const double num_seconds); //!< Shifts a timestamp the given amount of seconds (>0: forwards in time, <0: backwards) \sa secondsToTimestamp/** Transform a time interval (in seconds) into TTimeStamp (e.g. which can be added to an existing valid timestamp)* \sa timeDifference*/system::TTimeStamp secondsToTimestamp(const double nSeconds);/** Returns a formated string with the given time difference (passed as the number of seconds), as a string [H]H:MM:SS.MILISECS* \sa unitsFormat*/std::wstring formatTimeInterval(const double timeSeconds);/** Convert a timestamp into this textual form (UTC time): YEAR/MONTH/DAY,HH:MM:SS.MMM* \sa dateTimeLocalToString*/std::wstring dateTimeToString(const system::TTimeStamp t);/** Convert a timestamp into this textual form (in local time): YEAR/MONTH/DAY,HH:MM:SS.MMM* \sa dateTimeToString*/std::wstring dateTimeLocalToString(const system::TTimeStamp t);/** Convert a timestamp into this textual form: YEAR/MONTH/DAY*/std::wstring dateToString(const system::TTimeStamp t);/** Returns the number of seconds ellapsed from midnight in the given timestamp*/double extractDayTimeFromTimestamp(const system::TTimeStamp t);/** Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM*/std::wstring timeToString(const system::TTimeStamp t);/** Convert a timestamp into this textual form (in local time): HH:MM:SS.MMMMMM*/std::wstring timeLocalToString(const system::TTimeStamp t, unsigned int secondFractionDigits = 6);/** This function implements time interval formatting: Given a time in seconds, it will return a string describing the interval with the most appropriate unit.* E.g.: 1.23 year, 3.50 days, 9.3 hours, 5.3 minutes, 3.34 sec, 178.1 ms, 87.1 us.* \sa unitsFormat*/std::wstring intervalFormat(const double seconds);} // End of namespace
timestamp.cpp文件内容如下:
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <iostream>#ifdef _WIN32
#include <conio.h>
#include <windows.h>
#include <process.h>
#include <tlhelp32.h>
#include <sys/utime.h>
#include <io.h>
#include <direct.h>
#else
#include <pthread.h>
#include <termios.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <utime.h>
#include <errno.h>
#endifusing namespace system;
using namespace std;system::TTimeStamp system::time_tToTimestamp(const time_t& t)
{return uint64_t(t) * UINT64_C(10000000) + UINT64_C(116444736) * UINT64_C(1000000000);
}system::TTimeStamp system::time_tToTimestamp(const double t)
{return uint64_t(t * 10000000.0) + UINT64_C(116444736) * UINT64_C(1000000000);
}double system::timestampTotime_t(const system::TTimeStamp t)
{return double(t - UINT64_C(116444736) * UINT64_C(1000000000)) / 10000000.0;
}std::wstring format(const wchar_t* fmt, ...)
{if (!fmt) return std::wstring();int result = -1, length = 2048;std::wstring buffer;while (result == -1){buffer.resize(length);va_list args; // This must be done WITHIN the loopva_start(args, fmt);result = vswprintf_s(&buffer[0], length, fmt, args);va_end(args);// Truncated?if (result >= length) result = -1;length *= 2;// Ok?if (result >= 0) {buffer.resize(result);}}return buffer;
}system::TTimeStamp system::getCurrentTime()
{
#ifdef _WIN32FILETIME t;GetSystemTimeAsFileTime(&t);return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elsetimespec tim;clock_gettime(CLOCK_REALTIME, &tim);return time_tToTimestamp(tim.tv_sec) + tim.tv_nsec / 100;
#endif
}void system::timestampToParts(TTimeStamp t, TTimeParts& p, bool localTime)
{const double T = system::timestampTotime_t(t);double sec_frac = T - floor(T);assert(sec_frac < 1.0);const time_t tt = time_t(T);struct tm* parts = localTime ? localtime(&tt) : gmtime(&tt);//ASSERTMSG_(parts, "Malformed timestamp");p.year = parts->tm_year + 1900;p.month = parts->tm_mon + 1;p.day = parts->tm_mday;p.day_of_week = parts->tm_wday + 1;p.daylight_saving = parts->tm_isdst;p.hour = parts->tm_hour;p.minute = parts->tm_min;p.second = parts->tm_sec + sec_frac;
}TTimeStamp system::buildTimestampFromPartsLocalTime(const TTimeParts& p)
{struct tm parts;parts.tm_year = p.year - 1900;parts.tm_mon = p.month - 1;parts.tm_mday = p.day;parts.tm_wday = p.day_of_week - 1;parts.tm_isdst = p.daylight_saving;parts.tm_hour = p.hour;parts.tm_min = p.minute;parts.tm_sec = int(p.second);double sec_frac = p.second - parts.tm_sec;time_t tt = mktime(&parts);return system::time_tToTimestamp(double(tt) + sec_frac);
}system::TTimeStamp system::getCurrentLocalTime()
{
#ifdef _WIN32FILETIME tt, t;GetSystemTimeAsFileTime(&tt);FileTimeToLocalFileTime(&tt, &t);return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
#elsetimespec tim;clock_gettime(CLOCK_REALTIME, &tim);time_t tt;struct tm* timeinfo;time(&tt);timeinfo = localtime(&tt);return time_tToTimestamp(mktime(timeinfo)) + tim.tv_nsec / 100;
#endif
}system::TTimeStamp system::timestampAdd(const system::TTimeStamp tim, const double num_seconds)
{return static_cast<system::TTimeStamp>(tim + static_cast<int64_t>(num_seconds * 10000000.0));
}double system::timeDifference(const system::TTimeStamp t1, const system::TTimeStamp t2)
{//PPF_STARTassert(t1 != INVALID_TIMESTAMP);assert(t2 != INVALID_TIMESTAMP);return (int64_t(t2) - int64_t(t1)) / 10000000.0;//PPF_END
}system::TTimeStamp system::secondsToTimestamp(const double nSeconds)
{return (system::TTimeStamp)(nSeconds * 10000000.0);
}std::wstring system::formatTimeInterval(const double t)
{double timeSeconds = (t < 0) ? (-t) : t;unsigned int nHours = (unsigned int)timeSeconds / 3600;unsigned int nMins = ((unsigned int)timeSeconds % 3600) / 60;unsigned int nSecs = (unsigned int)timeSeconds % 60;unsigned int milSecs = (unsigned int)(1000 * (timeSeconds - floor(timeSeconds)));return format(L"%02u:%02u:%02u.%03u",nHours,nMins,nSecs,milSecs);
}/*---------------------------------------------------------------Convert a timestamp into this textual form: YEAR/MONTH/DAY,HH:MM:SS.MMM---------------------------------------------------------------*/
std::wstring system::dateTimeToString(const system::TTimeStamp t)
{if (t == INVALID_TIMESTAMP) return std::wstring(L"INVALID_TIMESTAMP");uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));time_t auxTime = tmp / (uint64_t)10000000;unsigned int secFractions = (unsigned int)(1000000 * (tmp % 10000000) / 10000000.0);tm* ptm = gmtime(&auxTime);if (!ptm)return std::wstring(L"(Malformed timestamp)");return format(L"%u/%02u/%02u,%02u:%02u:%02u.%06u",1900 + ptm->tm_year,ptm->tm_mon + 1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,(unsigned int)ptm->tm_sec,secFractions);
}/*---------------------------------------------------------------Convert a timestamp into this textual form (in local time):YEAR/MONTH/DAY,HH:MM:SS.MMM---------------------------------------------------------------*/
std::wstring system::dateTimeLocalToString(const system::TTimeStamp t)
{if (t == INVALID_TIMESTAMP) return std::wstring(L"INVALID_TIMESTAMP");uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));time_t auxTime = tmp / (uint64_t)10000000;unsigned int secFractions = (unsigned int)(1000000 * (tmp % 10000000) / 10000000.0);tm* ptm = localtime(&auxTime);if (!ptm) return L"(Malformed timestamp)";return format(L"%u/%02u/%02u,%02u:%02u:%02u.%06u",1900 + ptm->tm_year,ptm->tm_mon + 1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,(unsigned int)ptm->tm_sec,secFractions);
}double system::extractDayTimeFromTimestamp(const system::TTimeStamp t)
{//PPF_STARTassert(t != INVALID_TIMESTAMP);#ifdef _WIN32SYSTEMTIME sysT;FileTimeToSystemTime((FILETIME*)&t, &sysT);return sysT.wHour * 3600.0 + sysT.wMinute * 60.0 + sysT.wSecond + sysT.wMilliseconds * 0.001;
#elsetime_t auxTime = (t - ((uint64_t)116444736 * 1000000000)) / (uint64_t)10000000;tm* ptm = gmtime(&auxTime);ASSERTMSG_(ptm, "Malformed timestamp");return ptm->tm_hour * 3600.0 + ptm->tm_min * 60.0 + ptm->tm_sec;
#endif//PPF_END
}/*---------------------------------------------------------------Convert a timestamp into this textual form: HH:MM:SS.MMM---------------------------------------------------------------*/
std::wstring system::timeLocalToString(const system::TTimeStamp t, unsigned int secondFractionDigits)
{if (t == INVALID_TIMESTAMP) return std::wstring(L"INVALID_TIMESTAMP");uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));const time_t auxTime = tmp / (uint64_t)10000000;const tm* ptm = localtime(&auxTime);unsigned int secFractions = (unsigned int)(1000000 * (tmp % 10000000) / 10000000.0);// We start with 10^{-6} second units: reduce if requested by user:const unsigned int user_secondFractionDigits = secondFractionDigits;while (secondFractionDigits++ < 6)secFractions = secFractions / 10;return format(L"%02u:%02u:%02u.%0*u",ptm->tm_hour,ptm->tm_min,(unsigned int)ptm->tm_sec,user_secondFractionDigits,secFractions);
}/*---------------------------------------------------------------Convert a timestamp into this textual form: HH:MM:SS.MMM---------------------------------------------------------------*/
std::wstring system::timeToString(const system::TTimeStamp t)
{if (t == INVALID_TIMESTAMP) return std::wstring(L"INVALID_TIMESTAMP");uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));time_t auxTime = tmp / (uint64_t)10000000;unsigned int secFractions = (unsigned int)(1000000 * (tmp % 10000000) / 10000000.0);tm* ptm = gmtime(&auxTime);if (!ptm)return std::wstring(L"(Malformed timestamp)");return format(L"%02u:%02u:%02u.%06u",ptm->tm_hour,ptm->tm_min,(unsigned int)ptm->tm_sec,secFractions);
}/*---------------------------------------------------------------Convert a timestamp into this textual form: YEAR/MONTH/DAY---------------------------------------------------------------*/
std::wstring system::dateToString(const system::TTimeStamp t)
{if (t == INVALID_TIMESTAMP) return std::wstring(L"INVALID_TIMESTAMP");uint64_t tmp = (t - ((uint64_t)116444736 * 1000000000));time_t auxTime = tmp / (uint64_t)10000000;tm* ptm = gmtime(&auxTime);if (!ptm)return std::wstring(L"(Malformed timestamp)");return format(L"%u/%02u/%02u",1900 + ptm->tm_year,ptm->tm_mon + 1,ptm->tm_mday);
}/** This function implements time interval formatting: Given a time in seconds, it will return a string describing the interval with the most appropriate unit.* E.g.: 1.23 year, 3.50 days, 9.3 hours, 5.3 minutes, 3.34 sec, 178.1 ms, 87.1 us.*/
std::wstring
system::intervalFormat(const double seconds)
{if (seconds >= 365 * 24 * 3600)return format(L"%.2f years", seconds / (365 * 24 * 3600));else if (seconds >= 24 * 3600)return format(L"%.2f days", seconds / (24 * 3600));else if (seconds >= 3600)return format(L"%.2f hours", seconds / 3600);else if (seconds >= 60)return format(L"%.2f minutes", seconds / 60);else if (seconds >= 1)return format(L"%.2f sec", seconds);else if (seconds >= 1e-3)return format(L"%.2f ms", seconds * 1e3);else if (seconds >= 1e-6)return format(L"%.2f us", seconds * 1e6);else return format(L"%.2f ns", seconds * 1e9);
}
直接愉快的加入到项目使用!