File indexing completed on 2026-04-09 07:49:47
0001 #pragma once
0002
0003 #include <chrono>
0004 #include <thread>
0005 #include <string>
0006 #include <sstream>
0007 #include <iomanip>
0008 #include <cstring>
0009
0010 struct sstamp
0011 {
0012 static int64_t Now();
0013
0014 static std::string FormatLog();
0015 static std::string Format(int64_t t=0, const char* fmt="%FT%T.", int wsubsec=3);
0016
0017 static constexpr const char* LOG_FMT = "%Y-%m-%d %H:%M:%S" ;
0018 static constexpr const char* DEFAULT_TIME_FMT = "%Y%m%d_%H%M%S_" ;
0019 static std::string FormatTimeStem(const char* _stem=nullptr, int64_t t=0, int wsubsec=0);
0020
0021 static std::string FormatInt(int64_t t, int wid );
0022 static bool LooksLikeStampInt(const char* str);
0023 static void sleep(int seconds);
0024 static void sleep_us(int microseconds);
0025
0026 static int64_t age_seconds(int64_t t);
0027 static int64_t age_days(int64_t t);
0028 };
0029
0030 inline int64_t sstamp::Now()
0031 {
0032 using Clock = std::chrono::system_clock;
0033 using Unit = std::chrono::microseconds ;
0034 std::chrono::time_point<Clock> t0 = Clock::now();
0035 return std::chrono::duration_cast<Unit>(t0.time_since_epoch()).count() ;
0036 }
0037
0038
0039 inline std::string sstamp::FormatLog()
0040 {
0041 return Format(0, LOG_FMT, 3);
0042 }
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 inline std::string sstamp::Format(int64_t t, const char* fmt, int wsubsec)
0060 {
0061 if(t == 0) t = Now() ;
0062 using Clock = std::chrono::system_clock;
0063 using Unit = std::chrono::microseconds ;
0064 std::chrono::time_point<Clock> tp{Unit{t}} ;
0065 std::time_t tt = Clock::to_time_t(tp);
0066
0067 std::stringstream ss ;
0068 ss << std::put_time(std::localtime(&tt), fmt ) ;
0069
0070 if(wsubsec == 3 || wsubsec == 6)
0071 {
0072
0073 auto subsec = std::chrono::duration_cast<Unit>(tp.time_since_epoch()) % std::chrono::seconds{1};
0074 auto count = subsec.count() ;
0075 if( wsubsec == 3 ) count /= 1000 ;
0076
0077 ss << "." << std::setfill('0') << std::setw(wsubsec) << count ;
0078 }
0079 std::string str = ss.str();
0080 return str ;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 inline std::string sstamp::FormatTimeStem(const char* _stem, int64_t t, int wsubsec)
0102 {
0103 std::string stem ;
0104 if(_stem == nullptr)
0105 {
0106 stem = Format(t, DEFAULT_TIME_FMT, wsubsec );
0107 }
0108 else if( strstr(_stem,"%") )
0109 {
0110 stem = Format(t, _stem, wsubsec );
0111 }
0112 else
0113 {
0114 stem = _stem ;
0115 }
0116 return stem ;
0117 }
0118
0119
0120
0121 inline std::string sstamp::FormatInt(int64_t t, int wid )
0122 {
0123 std::stringstream ss ;
0124 if( t > -1 ) ss << std::setw(wid) << t ;
0125 else ss << std::setw(wid) << "" ;
0126 std::string str = ss.str();
0127 return str ;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 inline bool sstamp::LooksLikeStampInt(const char* str)
0151 {
0152 int length = strlen(str) ;
0153 int digits = 0 ;
0154 for(int i=0 ; i < length ; i++) if(str[i] >= '0' && str[i] <= '9') digits += 1 ;
0155 return length == 16 && digits == length ;
0156 }
0157
0158 inline void sstamp::sleep(int seconds)
0159 {
0160 std::chrono::seconds dura(seconds);
0161 std::this_thread::sleep_for( dura );
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 inline void sstamp::sleep_us(int us)
0179 {
0180 std::chrono::microseconds dura(us);
0181 std::this_thread::sleep_for( dura );
0182 }
0183
0184 inline int64_t sstamp::age_seconds(int64_t t)
0185 {
0186 int64_t now = Now();
0187 int64_t duration = now - t ;
0188 int64_t age_sec = duration/1000000 ;
0189 return age_sec ;
0190 }
0191 inline int64_t sstamp::age_days(int64_t t)
0192 {
0193 int64_t age_sec = age_seconds(t);
0194 return age_sec/(24*60*60) ;
0195 }
0196
0197
0198
0199