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 |   |
27 | namespace tSystem  |
28 | {  |
29 | static int64 HPCStartCount = tSystem::tGetHardwareTimerCount();  |
30 | static int64 HPCFrequency = tSystem::tGetHardwareTimerFrequency();  |
31 | }  |
32 |   |
33 |   |
34 | int64 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 |   |
51 | int64 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 |   |
70 | std::time_t tSystem::tGetTimeUTC()  |
71 | {  |
72 | std::time_t secondsSinceEpoch = time(nullptr);  |
73 | return secondsSinceEpoch;  |
74 | }  |
75 |   |
76 |   |
77 | std::time_t tSystem::tGetTimeGMT()  |
78 | {  |
79 | return tGetTimeUTC();  |
80 | }  |
81 |   |
82 |   |
83 | std::tm tSystem::tGetTimeLocal()  |
84 | {  |
85 | std::time_t t = std::time(nullptr);  |
86 | return *std::localtime(&t);  |
87 | }  |
88 |   |
89 |   |
90 | std::tm tSystem::tConvertTimeToLocal(std::time_t tm)  |
91 | {  |
92 | return *std::localtime(&tm);  |
93 | }  |
94 |   |
95 |   |
96 | tString 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 |   |
122 | void 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 |   |
137 | float 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 |   |
156 | double 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 |   |
176 | void 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 |   |
188 | float 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 |   |
197 | void 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.  |
256 | const 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 |   |
284 | double 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 | |