1// tTimer.cpp 
2// 
3// Simple timer class. Like a stopwatch. Supports keeping track of time in a number of different units. Accuracy is all 
4// up to you - you call the update function. This code does not access low-level timer hardware. 
5// 
6// Copyright (c) 2005, 2017, 2019, 2020 Tristan Grimmer. 
7// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
8// granted, provided that the above copyright notice and this permission notice appear in all copies. 
9// 
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
11// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
12// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
13// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
14// PERFORMANCE OF THIS SOFTWARE. 
15 
16#include <ctime> 
17#ifdef PLATFORM_WINDOWS 
18#include <Windows.h> 
19#else 
20#include <time.h> 
21#endif 
22#include "System/tTime.h" 
23#include "System/tPrint.h" 
24#include "System/tFile.h" 
25 
26 
27namespace tSystem 
28
29 static int64 HPCStartCount = tSystem::tGetHardwareTimerCount(); 
30 static int64 HPCFrequency = tSystem::tGetHardwareTimerFrequency(); 
31
32 
33 
34int64 tSystem::tGetHardwareTimerFrequency() 
35
36 if (!HPCFrequency
37
38 #if defined(PLATFORM_WINDOWS) 
39 int64 freq; 
40 QueryPerformanceFrequency((LargeInteger*)&freq); 
41 HPCFrequency = freq; 
42 #else 
43 HPCFrequency = 1000000000ll
44 #endif 
45
46 
47 return HPCFrequency
48
49 
50 
51int64 tSystem::tGetHardwareTimerCount() 
52
53 #if defined(PLATFORM_WINDOWS) 
54 int64 count; 
55 QueryPerformanceCounter((LargeInteger*)&count); 
56 return count; 
57 
58 #else 
59 struct timespec ts
60 int err = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); 
61 if (err
62 return 0
63 int64 nanoSecs = (1000000000ll * ts.tv_sec) + ts.tv_nsec
64 return nanoSecs
65 
66 #endif 
67
68 
69 
70std::time_t tSystem::tGetTimeUTC() 
71
72 std::time_t secondsSinceEpoch = time(nullptr); 
73 return secondsSinceEpoch
74
75 
76 
77std::time_t tSystem::tGetTimeGMT() 
78
79 return tGetTimeUTC(); 
80
81 
82 
83std::tm tSystem::tGetTimeLocal() 
84
85 std::time_t t = std::time(nullptr); 
86 return *std::localtime(&t); 
87
88 
89 
90std::tm tSystem::tConvertTimeToLocal(std::time_t tm
91
92 return *std::localtime(&tm); 
93
94 
95 
96tString tSystem::tConvertTimeToString(std::tm timePoint, tTimeFormat format
97
98 tString tstr(256); 
99 
100 switch (format
101
102 case tTimeFormat::Standard
103 // Eg. 2020-01-14 01:47:12 
104 strftime(tstr.Text(), 256, "%F %T", &timePoint); 
105 break
106 
107 case tTimeFormat::Extended
108 // Eg. Tuesday January 14 2020 - 01:36:34 
109 strftime(tstr.Text(), 256, "%A %B %d %G - %T", &timePoint); 
110 break
111 
112 case tTimeFormat::Short
113 // Eg. Tue Jan 14 14:38:58 2020 
114 strftime(tstr.Text(), 256, "%c", &timePoint); 
115 break
116
117 
118 return tstr
119
120 
121 
122void tSystem::tSleep(int milliSeconds
123
124 #if defined(PLATFORM_WINDOWS) 
125 ::Sleep(milliSeconds); 
126 
127 #else 
128 struct timespec ts
129 ts.tv_sec = milliSeconds / 1000
130 ts.tv_nsec = 1000000*(milliSeconds - (ts.tv_sec*1000)); 
131 nanosleep(&ts, nullptr); 
132 
133 #endif 
134
135 
136 
137float tSystem::tGetTime() 
138
139 #ifdef PLATFORM_WINDOWS 
140 int64 freq = tGetHardwareTimerFrequency(); 
141 
142 // This is organized like this to keep precision as high as possible. 
143 int64 elapsedCount = tGetHardwareTimerCount() - HPCStartCount; 
144 int64 wholeSeconds = elapsedCount / freq; 
145 int64 remainder = elapsedCount % freq; 
146 return float(wholeSeconds) + float(remainder)/float(freq); 
147  
148 #else 
149 int64 microSecs = (tGetHardwareTimerCount() - HPCStartCount) / 1000ll
150 return float(microSecs) / 1000000.0f
151 
152 #endif 
153
154 
155 
156double tSystem::tGetTimeDouble() 
157
158 #ifdef PLATFORM_WINDOWS 
159 int64 currCount = tGetHardwareTimerCount(); 
160 int64 freq = tGetHardwareTimerFrequency(); 
161 
162 // This is organized like this to keep precision as high as possible. 
163 int64 elapsedCount = currCount - HPCStartCount; 
164 int64 wholeSeconds = elapsedCount / freq; 
165 int64 remainder = elapsedCount % freq; 
166 return double(wholeSeconds) + double(remainder)/double(freq); 
167 
168 #else 
169 int64 nanoSecs = tGetHardwareTimerCount() - HPCStartCount
170 return double(nanoSecs) / 1000000000.0
171 
172 #endif 
173
174 
175 
176void tSystem::tTimer::Update(float timeElapsed, tUnit::tTime unit
177
178 if (!Running
179 return
180 
181 if (unit == tUnit::tTime::Unspecified
182 unit = UnitInternal
183 
184 Time += Convert(timeElapsed, unit, UnitInternal); 
185
186 
187 
188float tSystem::tTimer::GetTime(tUnit::tTime unit) const 
189
190 if (unit == tUnit::tTime::Unspecified
191 unit = UnitInternal
192 
193 return float(Convert(Time, UnitInternal, unit)); 
194
195 
196 
197void tSystem::tTimer::PrintHighPrecisionConversionTable(const char* outputFile
198
199 double inSeconds[int(tUnit::tTime::NumTimeUnits)] = 
200
201 5.39E-44, // PlankTime 
202 6.97E-24, // Chronon 
203 1.0E-18, // Atosecond 
204 1.0E-15, // Femtosecond 
205 1.0E-12, // Picosecond 
206 1.0E-9, // Nanosecond 
207 1.0E-6, // Microsecond 
208 1.0E-3, // Millisecond 
209 1.0/60.0, // Tick 
210 1.0, // Second 
211 0.3, // She 
212 3.0 + 1.0/3.0, // Helek 
213 60.0, // Minute 
214 3600.0, // Hour 
215 86400.0, // Day 
216 604800.0, // Week 
217 1209600.0, // Fortnight 
218 31536000.0, // Year 
219 31536000.0, // Annum 
220 3153600000.0, // Century 
221 31536000000.0, // Millennium 
222 7884000000000000.0, // GalacticYear 
223 }; 
224 
225 tFileHandle file = tSystem::tOpenFile(outputFile, "wt"); 
226 
227 tfPrintf(file, "// "); 
228 for (int n = 0; n < int(tUnit::tTime::NumTimeUnits); n++) 
229
230 int count = tfPrintf(file, "%s", tUnit::GetUnitName(tUnit::tTime(n))); 
231 for (int space = 0; space < (25-count); space++) 
232 tfPrintf(file, " "); 
233
234 tfPrintf(file, "\n"); 
235 
236 for (int from = 0; from < int(tUnit::tTime::NumTimeUnits); from++) 
237
238 int count = tfPrintf(file, "/* %s */ ", tUnit::GetUnitName(tUnit::tTime(from))); 
239 for (int space = 0; space < (21-count); space++) 
240 tfPrintf(file, " "); 
241 
242 tfPrintf(file, "{"); 
243 for (int to = 0; to < int(tUnit::tTime::NumTimeUnits); to++) 
244
245 // From -> to. t = f * t/f. 
246 tfPrintf(file, " %019.16E,", inSeconds[from]/inSeconds[to]); 
247
248 tfPrintf(file, " },\n"); 
249
250 tSystem::tCloseFile(file); 
251}; 
252 
253 
254// To keep error as low as possible while converting, we explicitly specify the conversions between all possible unit 
255// combinations. This is better than converting to a norm, and then to the destination. 
256const double tSystem::tTimer::UnitConversionTable[int(tUnit::tTime::NumTimeUnits)][int(tUnit::tTime::NumTimeUnits)] = 
257
258 // PlankTime Chronon Attosecond Femtosecond Picosecond Nanosecond Microsecond Millisecond Tick Second She Helek Minute Hour Day Week Fortnight Year Annum Century Millennium GalacticYear  
259 /* PlankTime */ { 1.0000000000000000E+000, 7.7331420373027263E-021, 5.3899999999999997E-026, 5.3899999999999996E-029, 5.3899999999999998E-032, 5.3899999999999992E-035, 5.3899999999999999E-038, 5.3899999999999998E-041, 3.2339999999999997E-042, 5.3899999999999995E-044, 1.7966666666666664E-043, 1.6169999999999997E-044, 8.9833333333333332E-046, 1.4972222222222221E-047, 6.2384259259259255E-049, 8.9120370370370367E-050, 4.4560185185185184E-050, 1.7091577879249111E-051, 1.7091577879249111E-051, 1.7091577879249112E-053, 1.7091577879249110E-054, 6.8366311516996447E-060, }, 
260 /* Chronon */ { 1.2931354359925789E+020, 1.0000000000000000E+000, 6.9699999999999993E-006, 6.9699999999999989E-009, 6.9699999999999996E-012, 6.9699999999999993E-015, 6.9700000000000007E-018, 6.9700000000000003E-021, 4.1820000000000000E-022, 6.9699999999999997E-024, 2.3233333333333334E-023, 2.0909999999999998E-024, 1.1616666666666666E-025, 1.9361111111111109E-027, 8.0671296296296291E-029, 1.1524470899470898E-029, 5.7622354497354492E-030, 2.2101725012683914E-031, 2.2101725012683914E-031, 2.2101725012683916E-033, 2.2101725012683915E-034, 8.8406900050735662E-040, }, 
261 /* Attosecond */ { 1.8552875695732842E+025, 1.4347202295552369E+005, 1.0000000000000000E+000, 1.0000000000000000E-003, 1.0000000000000002E-006, 1.0000000000000001E-009, 1.0000000000000002E-012, 1.0000000000000001E-015, 6.0000000000000001E-017, 1.0000000000000001E-018, 3.3333333333333337E-018, 2.9999999999999999E-019, 1.6666666666666668E-020, 2.7777777777777779E-022, 1.1574074074074075E-023, 1.6534391534391536E-024, 8.2671957671957680E-025, 3.1709791983764591E-026, 3.1709791983764591E-026, 3.1709791983764589E-028, 3.1709791983764589E-029, 1.2683916793505836E-034, }, 
262 /* Femtosecond */ { 1.8552875695732842E+028, 1.4347202295552370E+008, 1.0000000000000000E+003, 1.0000000000000000E+000, 1.0000000000000000E-003, 9.9999999999999995E-007, 1.0000000000000001E-009, 9.9999999999999998E-013, 6.0000000000000009E-014, 1.0000000000000001E-015, 3.3333333333333336E-015, 2.9999999999999999E-016, 1.6666666666666667E-017, 2.7777777777777778E-019, 1.1574074074074075E-020, 1.6534391534391535E-021, 8.2671957671957675E-022, 3.1709791983764592E-023, 3.1709791983764592E-023, 3.1709791983764591E-025, 3.1709791983764591E-026, 1.2683916793505836E-031, }, 
263 /* Picosecond */ { 1.8552875695732841E+031, 1.4347202295552368E+011, 9.9999999999999988E+005, 9.9999999999999989E+002, 1.0000000000000000E+000, 1.0000000000000000E-003, 9.9999999999999995E-007, 1.0000000000000001E-009, 6.0000000000000000E-011, 9.9999999999999998E-013, 3.3333333333333335E-012, 2.9999999999999998E-013, 1.6666666666666667E-014, 2.7777777777777775E-016, 1.1574074074074074E-017, 1.6534391534391534E-018, 8.2671957671957670E-019, 3.1709791983764586E-020, 3.1709791983764586E-020, 3.1709791983764587E-022, 3.1709791983764586E-023, 1.2683916793505833E-028, }, 
264 /* Nanosecond */ { 1.8552875695732840E+034, 1.4347202295552369E+014, 1.0000000000000000E+009, 1.0000000000000000E+006, 1.0000000000000001E+003, 1.0000000000000000E+000, 1.0000000000000000E-003, 9.9999999999999995E-007, 6.0000000000000008E-008, 1.0000000000000001E-009, 3.3333333333333338E-009, 3.0000000000000000E-010, 1.6666666666666667E-011, 2.7777777777777779E-013, 1.1574074074074075E-014, 1.6534391534391536E-015, 8.2671957671957678E-016, 3.1709791983764588E-017, 3.1709791983764588E-017, 3.1709791983764587E-019, 3.1709791983764586E-020, 1.2683916793505836E-025, }, 
265 /* Microsecond */ { 1.8552875695732838E+037, 1.4347202295552366E+017, 9.9999999999999988E+011, 9.9999999999999988E+008, 1.0000000000000000E+006, 9.9999999999999989E+002, 1.0000000000000000E+000, 1.0000000000000000E-003, 5.9999999999999995E-005, 9.9999999999999995E-007, 3.3333333333333333E-006, 2.9999999999999999E-007, 1.6666666666666667E-008, 2.7777777777777777E-010, 1.1574074074074074E-011, 1.6534391534391534E-012, 8.2671957671957671E-013, 3.1709791983764584E-014, 3.1709791983764584E-014, 3.1709791983764586E-016, 3.1709791983764588E-017, 1.2683916793505834E-022, }, 
266 /* Millisecond */ { 1.8552875695732840E+040, 1.4347202295552369E+020, 1.0000000000000000E+015, 1.0000000000000000E+012, 1.0000000000000000E+009, 1.0000000000000000E+006, 1.0000000000000001E+003, 1.0000000000000000E+000, 6.0000000000000005E-002, 1.0000000000000000E-003, 3.3333333333333335E-003, 2.9999999999999997E-004, 1.6666666666666667E-005, 2.7777777777777776E-007, 1.1574074074074074E-008, 1.6534391534391535E-009, 8.2671957671957675E-010, 3.1709791983764586E-011, 3.1709791983764586E-011, 3.1709791983764587E-013, 3.1709791983764590E-014, 1.2683916793505834E-019, }, 
267 /* Tick */ { 3.0921459492888067E+041, 2.3912003825920613E+021, 1.6666666666666666E+016, 1.6666666666666666E+013, 1.6666666666666666E+010, 1.6666666666666666E+007, 1.6666666666666668E+004, 1.6666666666666668E+001, 1.0000000000000000E+000, 1.6666666666666666E-002, 5.5555555555555559E-002, 5.0000000000000001E-003, 2.7777777777777778E-004, 4.6296296296296296E-006, 1.9290123456790122E-007, 2.7557319223985891E-008, 1.3778659611992945E-008, 5.2849653306274306E-010, 5.2849653306274306E-010, 5.2849653306274313E-012, 5.2849653306274313E-013, 2.1139861322509723E-018, }, 
268 /* Second */ { 1.8552875695732839E+043, 1.4347202295552367E+023, 9.9999999999999987E+017, 9.9999999999999987E+014, 1.0000000000000000E+012, 9.9999999999999988E+008, 1.0000000000000000E+006, 1.0000000000000000E+003, 6.0000000000000000E+001, 1.0000000000000000E+000, 3.3333333333333335E+000, 2.9999999999999999E-001, 1.6666666666666666E-002, 2.7777777777777778E-004, 1.1574074074074073E-005, 1.6534391534391535E-006, 8.2671957671957675E-007, 3.1709791983764586E-008, 3.1709791983764586E-008, 3.1709791983764586E-010, 3.1709791983764586E-011, 1.2683916793505835E-016, }, 
269 /* She */ { 5.5658627087198520E+042, 4.3041606886657104E+022, 2.9999999999999994E+017, 2.9999999999999994E+014, 3.0000000000000000E+011, 3.0000000000000000E+008, 3.0000000000000000E+005, 3.0000000000000000E+002, 1.8000000000000000E+001, 2.9999999999999999E-001, 1.0000000000000000E+000, 8.9999999999999997E-002, 5.0000000000000001E-003, 8.3333333333333331E-005, 3.4722222222222220E-006, 4.9603174603174601E-007, 2.4801587301587301E-007, 9.5129375951293758E-009, 9.5129375951293758E-009, 9.5129375951293758E-011, 9.5129375951293754E-012, 3.8051750380517500E-017, }, 
270 /* Helek */ { 6.1842918985776139E+043, 4.7824007651841229E+023, 3.3333333333333330E+018, 3.3333333333333330E+015, 3.3333333333333335E+012, 3.3333333333333335E+009, 3.3333333333333335E+006, 3.3333333333333335E+003, 2.0000000000000000E+002, 3.3333333333333335E+000, 1.1111111111111112E+001, 1.0000000000000000E+000, 5.5555555555555559E-002, 9.2592592592592596E-004, 3.8580246913580246E-005, 5.5114638447971785E-006, 2.7557319223985893E-006, 1.0569930661254863E-007, 1.0569930661254863E-007, 1.0569930661254863E-009, 1.0569930661254863E-010, 4.2279722645019450E-016, }, 
271 /* Minute */ { 1.1131725417439703E+045, 8.6083213773314209E+024, 5.9999999999999992E+019, 5.9999999999999992E+016, 6.0000000000000000E+013, 6.0000000000000000E+010, 6.0000000000000000E+007, 6.0000000000000000E+004, 3.6000000000000000E+003, 6.0000000000000000E+001, 2.0000000000000000E+002, 1.8000000000000000E+001, 1.0000000000000000E+000, 1.6666666666666666E-002, 6.9444444444444447E-004, 9.9206349206349206E-005, 4.9603174603174603E-005, 1.9025875190258751E-006, 1.9025875190258751E-006, 1.9025875190258752E-008, 1.9025875190258752E-009, 7.6103500761035007E-015, }, 
272 /* Hour */ { 6.6790352504638226E+046, 5.1649928263988526E+026, 3.6000000000000000E+021, 3.5999999999999995E+018, 3.6000000000000000E+015, 3.6000000000000000E+012, 3.6000000000000000E+009, 3.6000000000000000E+006, 2.1600000000000000E+005, 3.6000000000000000E+003, 1.2000000000000000E+004, 1.0800000000000000E+003, 6.0000000000000000E+001, 1.0000000000000000E+000, 4.1666666666666664E-002, 5.9523809523809521E-003, 2.9761904761904760E-003, 1.1415525114155251E-004, 1.1415525114155251E-004, 1.1415525114155251E-006, 1.1415525114155251E-007, 4.5662100456621005E-013, }, 
273 /* Day */ { 1.6029684601113173E+048, 1.2395982783357247E+028, 8.6400000000000000E+022, 8.6400000000000000E+019, 8.6400000000000000E+016, 8.6400000000000000E+013, 8.6400000000000000E+010, 8.6400000000000000E+007, 5.1840000000000000E+006, 8.6400000000000000E+004, 2.8800000000000000E+005, 2.5920000000000000E+004, 1.4400000000000000E+003, 2.4000000000000000E+001, 1.0000000000000000E+000, 1.4285714285714285E-001, 7.1428571428571425E-002, 2.7397260273972603E-003, 2.7397260273972603E-003, 2.7397260273972603E-005, 2.7397260273972604E-006, 1.0958904109589040E-011, }, 
274 /* Week */ { 1.1220779220779221E+049, 8.6771879483500723E+028, 6.0479999999999997E+023, 6.0480000000000000E+020, 6.0480000000000000E+017, 6.0480000000000000E+014, 6.0480000000000000E+011, 6.0480000000000000E+008, 3.6288000000000000E+007, 6.0480000000000000E+005, 2.0160000000000000E+006, 1.8144000000000000E+005, 1.0080000000000000E+004, 1.6800000000000000E+002, 7.0000000000000000E+000, 1.0000000000000000E+000, 5.0000000000000000E-001, 1.9178082191780823E-002, 1.9178082191780823E-002, 1.9178082191780821E-004, 1.9178082191780822E-005, 7.6712328767123292E-011, }, 
275 /* Fortnight */ { 2.2441558441558443E+049, 1.7354375896700145E+029, 1.2095999999999999E+024, 1.2096000000000000E+021, 1.2096000000000000E+018, 1.2096000000000000E+015, 1.2096000000000000E+012, 1.2096000000000000E+009, 7.2576000000000000E+007, 1.2096000000000000E+006, 4.0320000000000000E+006, 3.6288000000000000E+005, 2.0160000000000000E+004, 3.3600000000000000E+002, 1.4000000000000000E+001, 2.0000000000000000E+000, 1.0000000000000000E+000, 3.8356164383561646E-002, 3.8356164383561646E-002, 3.8356164383561642E-004, 3.8356164383561644E-005, 1.5342465753424658E-010, }, 
276 /* Year */ { 5.8508348794063083E+050, 4.5245337159253948E+030, 3.1535999999999997E+025, 3.1535999999999996E+022, 3.1536000000000000E+019, 3.1536000000000000E+016, 3.1536000000000000E+013, 3.1536000000000000E+010, 1.8921600000000000E+009, 3.1536000000000000E+007, 1.0512000000000000E+008, 9.4608000000000000E+006, 5.2560000000000000E+005, 8.7600000000000000E+003, 3.6500000000000000E+002, 5.2142857142857146E+001, 2.6071428571428573E+001, 1.0000000000000000E+000, 1.0000000000000000E+000, 1.0000000000000000E-002, 1.0000000000000000E-003, 4.0000000000000002E-009, }, 
277 /* Annum */ { 5.8508348794063083E+050, 4.5245337159253948E+030, 3.1535999999999997E+025, 3.1535999999999996E+022, 3.1536000000000000E+019, 3.1536000000000000E+016, 3.1536000000000000E+013, 3.1536000000000000E+010, 1.8921600000000000E+009, 3.1536000000000000E+007, 1.0512000000000000E+008, 9.4608000000000000E+006, 5.2560000000000000E+005, 8.7600000000000000E+003, 3.6500000000000000E+002, 5.2142857142857146E+001, 2.6071428571428573E+001, 1.0000000000000000E+000, 1.0000000000000000E+000, 1.0000000000000000E-002, 1.0000000000000000E-003, 4.0000000000000002E-009, }, 
278 /* Century */ { 5.8508348794063081E+052, 4.5245337159253946E+032, 3.1536000000000000E+027, 3.1535999999999999E+024, 3.1536000000000000E+021, 3.1536000000000000E+018, 3.1536000000000000E+015, 3.1536000000000000E+012, 1.8921600000000000E+011, 3.1536000000000000E+009, 1.0512000000000000E+010, 9.4608000000000000E+008, 5.2560000000000000E+007, 8.7600000000000000E+005, 3.6500000000000000E+004, 5.2142857142857147E+003, 2.6071428571428573E+003, 1.0000000000000000E+002, 1.0000000000000000E+002, 1.0000000000000000E+000, 1.0000000000000001E-001, 3.9999999999999998E-007, }, 
279 /* Millennium */ { 5.8508348794063081E+053, 4.5245337159253946E+033, 3.1535999999999999E+028, 3.1535999999999997E+025, 3.1536000000000000E+022, 3.1536000000000000E+019, 3.1536000000000000E+016, 3.1536000000000000E+013, 1.8921600000000000E+012, 3.1536000000000000E+010, 1.0512000000000000E+011, 9.4608000000000000E+009, 5.2560000000000000E+008, 8.7600000000000000E+006, 3.6500000000000000E+005, 5.2142857142857145E+004, 2.6071428571428572E+004, 1.0000000000000000E+003, 1.0000000000000000E+003, 1.0000000000000000E+001, 1.0000000000000000E+000, 3.9999999999999998E-006, }, 
280 /* GalacticYear */ { 1.4627087198515771E+059, 1.1311334289813487E+039, 7.8839999999999993E+033, 7.8839999999999996E+030, 7.8839999999999997E+027, 7.8839999999999993E+024, 7.8840000000000000E+021, 7.8840000000000000E+018, 4.7304000000000000E+017, 7.8840000000000000E+015, 2.6280000000000000E+016, 2.3652000000000000E+015, 1.3140000000000000E+014, 2.1900000000000000E+012, 9.1250000000000000E+010, 1.3035714285714285E+010, 6.5178571428571424E+009, 2.5000000000000000E+008, 2.5000000000000000E+008, 2.5000000000000000E+006, 2.5000000000000000E+005, 1.0000000000000000E+000, } 
281}; 
282 
283 
284double tSystem::tTimer::Convert(double time, tUnit::tTime unitFrom, tUnit::tTime unitTo
285
286 tAssert((unitFrom != tUnit::tTime::Unspecified) && (unitTo != tUnit::tTime::Unspecified)); 
287 if (unitFrom == unitTo
288 return time
289 
290 return (UnitConversionTable[int(unitFrom)][int(unitTo)])*time
291
292