ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
time.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10#if !defined(HPP_ALIB_TIME_TIME)
11# include "alib/time/time.hpp"
12#endif
13
14#if !defined (HPP_ALIB_TIME_TICKSCONVERTER)
16#endif
17
18#endif // !defined(ALIB_DOX)
19
20using namespace std::chrono;
21
22#if ALIB_BOXING
23 ALIB_BOXING_VTABLE_DEFINE( alib::Ticks , vt_time_ticks )
24 ALIB_BOXING_VTABLE_DEFINE( alib::Ticks::Duration , vt_time_ticks_duration )
25 ALIB_BOXING_VTABLE_DEFINE( alib::DateTime , vt_time_datetime )
26 ALIB_BOXING_VTABLE_DEFINE( alib::DateTime::Duration , vt_time_datetime_duration )
27#endif
28
29namespace alib {
30
31/**
32 * This namespace of \alib provides types for calendrical date and time processing as well as
33 * for non-calendrical steady and monotonic time measurement.
34 *
35 * Besides this reference documentation, further information is provided with
36 * \ref alib_mod_time "ALib Module Time - Programmer's Manual".
37 */
38namespace time {
39
40// #################################################################################################
41// Module Bootstrap/Termination
42// #################################################################################################
43#if !defined(ALIB_DOX)
44namespace
45{
46 Ticks* creationTime= nullptr;
47}
48#endif
49
51{
52 // create a ticks object that marks the time of creation of this non-camp module
53 if( !creationTime )
54 creationTime= new Ticks();
55
58 ALIB_BOXING_BOOTSTRAP_VTABLE_DBG_REGISTER( vt_time_ticks_duration )
60 ALIB_BOXING_BOOTSTRAP_VTABLE_DBG_REGISTER( vt_time_datetime_duration ) )
61}
62
64{
65 if( creationTime )
66 {
67 delete creationTime;
68 creationTime= nullptr;
69 }
70}
71
73{
74 return *creationTime;
75}
76
77
78// #################################################################################################
79// TickConverter
80// #################################################################################################
81void TickConverter::SyncClocks( int qtyRepeats )
82{
83 Ticks::TTimePoint steadyClock;
84 DateTime::TTimePoint systemClock;
85 uint64_t lastDiff= 0;
86 for( int i= 0 ; i < qtyRepeats ; ++i )
87 {
88 systemClock= system_clock::now();
89 steadyClock= steady_clock::now();
90
91 auto systemCount= systemClock.time_since_epoch().count();
92 auto steadyCount= steadyClock.time_since_epoch().count();
93
94 // This can not be optimized, because:
95 // a) we have to use an unsigned integer, and
96 // b) we have to take into account which clock was measured first and which last. If
97 // interrupted between the calls, the difference either shrinks or increases.
98 if( systemCount < steadyCount )
99 {
100 uint64_t diff= static_cast<uint64_t >( steadyCount - systemCount );
101 if( lastDiff == 0 || diff < lastDiff )
102 {
103 steadyClockSyncTime= steadyClock;
104 systemClockSyncTime= systemClock;
105 lastDiff= diff;
106 }
107 }
108 else
109 {
110 uint64_t diff= static_cast<uint64_t >( systemCount - steadyCount );
111 if( lastDiff == 0 || diff > lastDiff )
112 {
113 steadyClockSyncTime= steadyClock;
114 systemClockSyncTime= systemClock;
115 lastDiff= diff;
116 }
117 }
118 }
119}
120
121
122
123// #################################################################################################
124// Windows OS specific: file time, system time
125// #################################################################################################
126#if defined( _WIN32 ) && !defined(ALIB_DOX)
127
128// filetime_duration has the same layout as FILETIME; 100ns intervals
129using filetime_duration = duration<int64_t, std::ratio<1, 10000000> >;
130
131// January 1, 1601 (NT epoch) - January 1, 1970 (Unix epoch):
132constexpr duration<int64_t> nt_to_unix_epoch{INT64_C(-11644473600)};
133
134FILETIME DateTime::ToFileTime() const
135{
136 const auto asDuration = duration_cast<filetime_duration>( stamp.time_since_epoch() );
137 const auto withNtEpoch= asDuration - nt_to_unix_epoch;
138 const auto rawCount = withNtEpoch.count();
139
140 FILETIME result;
141 result.dwLowDateTime = static_cast<DWORD>(rawCount); // discards upper bits
142 result.dwHighDateTime = static_cast<DWORD>(rawCount >> 32);
143 return result;
144
145}
146
147ULARGE_INTEGER DateTime::ToFileTimeLI() const
148{
149 FILETIME ft= ToFileTime();
150 ULARGE_INTEGER result;
151 result.HighPart= ft.dwHighDateTime;
152 result.LowPart= ft.dwLowDateTime;
153 return result;
154}
155
156DateTime DateTime::FromFileTime( const FILETIME& fileTime )
157{
158 const filetime_duration ftDuration { static_cast<int64_t>( (static_cast<uint64_t>( fileTime.dwHighDateTime) << 32)
159 | fileTime.dwLowDateTime ) };
160 return DateTime( TTimePoint(ftDuration + nt_to_unix_epoch));
161}
162
163DateTime DateTime::FromFileTime( const ULARGE_INTEGER& ft )
164{
165 FILETIME fileTime;
166 fileTime.dwLowDateTime = ft.LowPart;
167 fileTime.dwHighDateTime = ft.HighPart;
168 return FromFileTime( fileTime );
169}
170
171SYSTEMTIME DateTime::ToSystemTime( lang::Timezone timezone ) const
172{
173 FILETIME ft= ToFileTime();
174 SYSTEMTIME result;
175 if ( timezone == lang::Timezone::UTC )
176 FileTimeToSystemTime( &ft, &result );
177 else
178 {
179 SYSTEMTIME utc;
180 FileTimeToSystemTime( &ft, &utc );
181 SystemTimeToTzSpecificLocalTime( NULL, &utc, &result );
182 }
183 return result;
184}
185
186DateTime DateTime::FromSystemTime( const SYSTEMTIME& st, lang::Timezone timezone )
187{
188 FILETIME ft;
189 if ( timezone == lang::Timezone::UTC )
190 SystemTimeToFileTime( &st, &ft );
191 else
192 {
193 SYSTEMTIME utc;
194 TzSpecificLocalTimeToSystemTime( NULL, &st, &utc);
195 SystemTimeToFileTime( &utc, &ft );
196 }
197 return DateTime::FromFileTime( ft );
198}
199#endif // defined( _WIN32 ) && !defined(ALIB_DOX)
200}} // namespace [alib::time]
ALIB_API ULARGE_INTEGER ToFileTimeLI() const
static ALIB_API DateTime FromFileTime(const FILETIME &fileTime)
static ALIB_API DateTime FromSystemTime(const SYSTEMTIME &systemTime, lang::Timezone timezone=lang::Timezone::Local)
ALIB_API SYSTEMTIME ToSystemTime(lang::Timezone timezone=lang::Timezone::Local) const
ALIB_API FILETIME ToFileTime() const
Ticks::TTimePoint steadyClockSyncTime
ALIB_API void SyncClocks(int qtyRepeats=5)
Definition time.cpp:81
DateTime::TTimePoint systemClockSyncTime
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
Definition vtable.inl:490
#define ALIB_IF_BOXING(...)
Definition alib.hpp:215
#define ALIB_BOXING_BOOTSTRAP_VTABLE_DBG_REGISTER(Identifier)
Definition vtable.inl:506
@ UTC
Denotes UTC (coordinated universal time).
void Bootstrap()
Definition time.cpp:50
Ticks & CreationTime()
Definition time.cpp:72
void Shutdown()
Definition time.cpp:63
Definition alib.cpp:57
time::Ticks Ticks
Type alias in namespace alib.
Definition ticks.hpp:114
time::DateTime DateTime
Type alias in namespace alib.
Definition datetime.hpp:226