timeClass.cpp

Engine/source/core/util/timeClass.cpp

More...

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