timeClass.cpp
Engine/source/core/util/timeClass.cpp
Namespaces:
namespace
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include <time.h> 25 26#include "core/util/timeClass.h" 27 28namespace Torque 29{ 30 31//Micro 0.000001 10-6 32//Milli 0.001 10-3 33 34static S8 _DaysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 35static S8 _DaysInMonthLeap[13]= {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 36static S32 _DayNumber[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; 37static S32 _DayNumberLeap[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; 38 39 40/**---------------------------------------------------------------------------- 41* PRIVATE Test to see if a year is a leap year. 42* 43* @param year Year to test for leap year 44* @return true if year is a leap year 45*/ 46inline bool Time::_isLeapYear(S32 year) const 47{ 48 return ((year & 3) == 0) && ( ((year % 100) != 0) || ((year % 400) == 0) ); 49} 50 51 52/**---------------------------------------------------------------------------- 53* PRIVATE Determine the number of days in any given month/year 54* 55* @param month Month to be tested 56* @param year Year to be tested 57* @return Number of days in month/year 58*/ 59S32 Time::_daysInMonth(S32 month, S32 year) const 60{ 61 if (_isLeapYear(year)) 62 return _DaysInMonthLeap[month]; 63 else 64 return _DaysInMonth[month]; 65} 66 67 68//----------------------------------------------------------------------------- 69void Time::getCurrentDateTime(DateTime &dateTime) 70{ 71 time_t long_time; 72 73 time( &long_time ); 74 75 struct tm *systime = localtime( &long_time ); 76 77 dateTime.year = systime->tm_year; 78 dateTime.month = systime->tm_mon; 79 dateTime.day = systime->tm_mday; 80 dateTime.hour = systime->tm_hour; 81 dateTime.minute = systime->tm_min; 82 dateTime.second = systime->tm_sec; 83 dateTime.microsecond = 0; 84} 85 86Time Time::getCurrentTime() 87{ 88 return Torque::UnixTimeToTime( time( NULL ) ); 89} 90 91bool Time::set(S32 year, S32 month, S32 day, S32 hour, S32 minute, S32 second, S32 microsecond) 92{ 93 second += microsecond / 100000; 94 microsecond %= 100000; 95 minute += second / 60; 96 second %= 60; 97 hour += minute / 60; 98 minute %= 60; 99 S32 carryDays = hour / 24; 100 hour %= 24; 101 102 bool leapYear = _isLeapYear(year); 103 104 year -= 1; // all the next operations need (year-1) so do it ahead of time 105 S32 gregorian = 365 * year // number of days since the epoch 106 + (year/4) // add Julian leap year days 107 - (year/100) // subtract century leap years 108 + (year/400) // add gregorian 400 year leap adjustment 109 + ((367*month-362)/12) // days in prior months 110 + day // add days 111 + carryDays; // add days from time overflow/underflow 112 113 // make days in this year adjustment if leap year 114 if (leapYear) 115 { 116 if (month > 2) 117 gregorian -= 1; 118 } 119 else 120 { 121 if (month > 2) 122 gregorian -= 2; 123 } 124 125 _time = S64(gregorian) * OneDay; 126 _time += S64((hour * OneHour) + 127 (minute * OneMinute) + 128 (second * OneSecond) + 129 microsecond); 130 131 return true; 132} 133 134 135//----------------------------------------------------------------------------- 136void Time::get(S32 *pyear, S32 *pmonth, S32 *pday, S32 *phour, S32 *pminute, S32 *psecond, S32 *pmicrosecond) const 137{ 138 // extract date if requested 139 if (pyear || pmonth || pday) 140 { 141 S32 gregorian = (S32)(_time / OneDay); 142 143 S32 prior = gregorian - 1; // prior days 144 S32 years400 = prior / 146097L; // number of 400 year cycles 145 S32 days400 = prior % 146097L; // days NOT in years400 146 S32 years100 = days400 / 36524L; // number 100 year cycles not checked 147 S32 days100 = days400 % 36524L; // days NOT already included 148 S32 years4 = days100 / 1461L; // number 4 year cycles not checked 149 S32 days4 = days100 % 1461L; // days NOT already included 150 S32 year1 = days4 / 365L; // number years not already checked 151 S32 day1 = days4 % 365L; // days NOT already included 152 S32 day; 153 S32 year = (400 * years400) + (100 * years100) + (4 * years4) + year1; 154 155 // December 31 of leap year 156 if (years100 == 4 || year1 == 4) 157 { 158 day = 366; 159 } 160 else 161 { 162 year += 1; 163 day = day1 + 1; 164 } 165 166 const S32 *dayNumber = _isLeapYear(year) ? _DayNumberLeap : _DayNumber; 167 168 // find month and day in month given computed year and day number, 169 S32 month = 1; 170 while(day >= dayNumber[month]) 171 month++; 172 173 day -= dayNumber[month-1]; 174 175 if(pyear) 176 *pyear = year; 177 if(pmonth) 178 *pmonth = month; 179 if(pday) 180 *pday = day; 181 } 182 183 // extract time 184 if (phour) 185 *phour = (S32)((_time % OneDay) / OneHour); 186 187 S32 time = (S32)(_time % OneHour); 188 189 if (pminute) 190 *pminute = time / (S32)OneMinute; 191 time %= OneMinute; 192 193 if (psecond) 194 *psecond = time / (S32)OneSecond; 195 if (pmicrosecond) 196 *pmicrosecond = time % OneSecond; 197} 198 199} // Namespace 200