timeClass.cpp 6.8 KB

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