Back to home page

EIC code displayed by LXR

 
 

    


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();  // plog style timestamp
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() // static
0040 {
0041     return Format(0, LOG_FMT, 3);
0042 }
0043 
0044 
0045 /**
0046 stamp::Format
0047 --------------
0048 
0049 Time string from uint64_t with the microseconds since UTC epoch,
0050 t=0 is special cased to give the current time
0051 
0052 wsubsec
0053     when 3 OR 6 enables subsec output of
0054     the corresponding width
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         // extract the sub second part from the duration since epoch
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 sstamp::FormatTimeStem
0086 ------------------------
0087 
0088  +----------------------+---------------------------------------------+
0089  |  _stem               |    return                                   |
0090  +======================+=============================================+
0091  | nullptr              |   time t formatted with DEFAULT_TIME_FMT    |
0092  +----------------------+---------------------------------------------+
0093  | string with "%"      |  time t formatted with _stem as the fmt     |
0094  +----------------------+---------------------------------------------+
0095  | any other string     |  return unchanged                           |
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 ) // static
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 sstamp::LooksLikeStampInt
0132 --------------------------
0133 
0134 Contemporary microsecond uint64_t timestamps since Sept 2001 look like below with 16 digits::
0135 
0136     1700224486350245
0137 
0138 ::
0139 
0140     In [20]: np.c_[np.array([0,int(1e15),1700224486350245,int(1e16),int(0x7ffffffffffffff) ]).view("datetime64[us]")]
0141     Out[20]:
0142     array([[ '1970-01-01T00:00:00.000000'],
0143            [ '2001-09-09T01:46:40.000000'],
0144            [ '2023-11-17T12:34:46.350245'],
0145            [ '2286-11-20T17:46:40.000000'],
0146            ['20237-04-25T10:45:03.423487']], dtype='datetime64[us]')
0147 
0148 */
0149 
0150 inline bool sstamp::LooksLikeStampInt(const char* str) // static
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 sstamp::sleep_us
0166 ------------------
0167 
0168 +--------------+--------------+
0169 | microseconds |   seconds    |
0170 +==============+==============+
0171 | 1,000,000    |  1           |
0172 +--------------+--------------+
0173 |   100,000    |  0.1         |
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