| 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 | |