Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mdatetime.cc

00001 /***************************************************************************
00002  *   This file is part of the MagiC++ library.                             *
00003  *                                                                         *
00004  *   Copyright (C) 1998-2001 Marko Grönroos <magi@iki.fi>                  *
00005  *                                                                         *
00006  ***************************************************************************
00007  *                                                                         *
00008  *  This library is free software; you can redistribute it and/or          *
00009  *  modify it under the terms of the GNU Library General Public            *
00010  *  License as published by the Free Software Foundation; either           *
00011  *  version 2 of the License, or (at your option) any later version.       *
00012  *                                                                         *
00013  *  This library is distributed in the hope that it will be useful,        *
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
00016  *  Library General Public License for more details.                       *
00017  *                                                                         *
00018  *  You should have received a copy of the GNU Library General Public      *
00019  *  License along with this library; see the file COPYING.LIB.  If         *
00020  *  not, write to the Free Software Foundation, Inc., 59 Temple Place      *
00021  *  - Suite 330, Boston, MA 02111-1307, USA.                               *
00022  *                                                                         *
00023  ***************************************************************************/
00024 
00025 #include <stdio.h>
00026 #include <time.h>
00027 #include <ctype.h>
00028 #include <mmath.h>
00029 
00030 #include "magic/mdatetime.h"
00031 #include "magic/mclass.h"
00032 
00033 decl_module (datetime);
00034 
00035 impl_dynamic (DateTime, {"Object"});
00036 impl_dynamic (JulianDay, {"Object"});
00037 
00039 // Local functions
00040 
00041 #define sign(x) ((x)>0)? 1:(((x)<0)? -1:0)
00042 
00043 #define FERR 0.000000001
00044 
00045 FloatType torange (FloatType initial, FloatType rmin, FloatType rmax) {
00046     while (initial<rmin || initial>rmax) {
00047         if (initial<rmin)
00048             initial += rmax-rmin;
00049         if (initial>rmax)
00050             initial -= rmax-rmin;
00051     }
00052     return initial;
00053 }
00054 
00055 String Hours::toString () const {
00056     return format ("%dh %dm %2.4fs", hour(), min(), sec());
00057 }
00058 
00060 //                                                                           //
00061 //                 ___                   ----- o                             //
00062 //                 |  \   ___   |   ___    |            ___                  //
00063 //                 |   |  ___| -+- /   )   |   | |/|/| /   )                 //
00064 //                 |   | (   |  |  |---    |   | | | | |---                  //
00065 //                 |__/   \__|   \  \__    |   | | | |  \__                  //
00066 //                                                                           //
00068 
00069 void settimezone (DateTime* dt) {
00070     // apufunktio: Asetetaan timezone ja kesäaika
00071     time_t aika_s = time (0);
00072     struct tm* aika = localtime (&aika_s);
00073     dt->timezone = -timezone/3600;
00074     dt->dst = aika->tm_isdst;
00075     dt->utcdiff = dt->timezone + dt->dst;
00076 }
00077 
00078 DateTime::DateTime (int d, int mo, int y, int h, int mi, FloatType s) {
00079     make (d, mo, y, h, mi, s);
00080 }
00081 
00082 void DateTime::make (int d, int mo, int y, int h, int mi, FloatType s) {
00083     day = d;
00084     month = mo;
00085     year = y;
00086     hours = h + mi/60.0 + s/3600.0;
00087     settimezone (this);
00088 }
00089 
00090 void DateTime::make () {
00091     day = 0;
00092     month = 0;
00093     year = 0;
00094     hours = 0.0;
00095     settimezone (this);
00096 }
00097 
00098 void DateTime::make (const time_t& tt) {
00099     struct tm* time_tm = localtime (&tt);
00100     day     = time_tm->tm_mday;
00101     month   = time_tm->tm_mon+1;
00102     year    = time_tm->tm_year+1900;
00103     hours   = time_tm->tm_hour
00104             + time_tm->tm_min/60.0
00105             + time_tm->tm_sec/3600.0;
00106     settimezone (this);
00107 }
00108 
00109 void DateTime::makecurrent () {
00110     make (time (0));
00111 }
00112 
00113 int DateTime::daynumber () const {
00114     int leap=0;
00115     if ((year/4)*4==year && (year/100)*100!=year)
00116         leap=1;
00117 
00118     if (month <3)
00119         return int ((month-1)*(63-leap)/2)+day;
00120     return int ((month+1)*30.6001)-63+leap+day;
00121 }
00122 
00123 int DateTime::weekday () const {
00124     return 0;
00125 }
00126 
00127 void DateTime::make (const JulianDay& jd) {
00128     double  JD = jd+0.5;
00129     int     Z = int(JD);
00130     double  F = JD-Z;
00131     double  A, B, C, D, E, G;
00132 
00133     if (Z<2299161) 
00134         A = Z;
00135     else {
00136         double alpha = int ((Z-1867216.25)/36524.25);
00137         A = Z+1+alpha-int(alpha/4);
00138     }
00139     
00140     B = A+1524;
00141     C = int ((B-122.1)/365.25);
00142     D = int (365.25*C);
00143     E = int ((B-D)/30.6001);
00144     day = int(int (B-D-int (30.6001*E))+F);
00145     month = int ((E<14)? E-1 : E-13);
00146     year = int ((month>2)? C-4716 : C-4715);
00147 
00148     // Lasketaan vielä kellonaika
00149     hours = F*24;
00150 }
00151 
00152 DateTime& DateTime::operator= (const DateTime& o) {
00153     memcpy (this, &o, sizeof(DateTime));
00154     return *this;
00155 }
00156 
00157 int DateTime::setstrict (const String& str, const String& tformat) {
00158     int mins=0, secs=0;
00159 
00160     make ();
00161     
00162     if (str.length() != tformat.length())
00163         return 1;
00164     
00165     for (int i=0; i<str.length(); i++) {
00166         char num = str[i] - '0';
00167         char f = tformat[i];
00168         switch (f) {
00169           case 'Y': year = year*10 + num; break;
00170           case 'M': month = month*10 + num; break;
00171           case 'D': day = day*10 + num; break;
00172           case 'h': hours = hours*10 + num; break;
00173           case 'm': mins = mins*10 + num; break;
00174           case 's': secs = secs*10 + num; break;
00175         };
00176     }
00177 
00178     hours += mins/60.0 + secs/3600.0;
00179 
00180     return 0;
00181 }
00182 
00183 int DateTime::compare (const DateTime& other) const {
00184     if (year < other.year)      return -1;
00185     if (year > other.year)      return 1;
00186 
00187     if (month < other.month)    return -1;
00188     if (month > other.month)    return 1;
00189 
00190     if (day < other.day)        return -1;
00191     if (day > other.day)        return 1;
00192 
00193     if (hours < other.hours)    return -1;
00194     if (hours > other.hours)    return 1;
00195 
00196     return 0;
00197 }
00198 
00199 double DateTime::operator- (const DateTime& o) const {
00200     return FloatType(JulianDay (*this)) - FloatType(JulianDay (o));
00201 }
00202 
00203 DateTime DateTime::lt2GMT () const {
00204     DateTime result;
00205     result.make (day,month,year,0,0,0);
00206     result.hours = hours - Hours(utcdiff);
00207     result.corrange ();
00208     return result;
00209 }
00210 
00211 void DateTime::nextday () {
00212     day=day+1;
00213     if (day>28 && month==2)
00214         day = 1,
00215         month++;
00216     else
00217         if (day>30 && (month==4 || month==6 || month==9 || month==11))
00218             day = 1,
00219             month++;
00220         else
00221             if (day>31 && (month==1 || month==3 || month==5 || month==7
00222                            || month==8 || month==10 || month==12))
00223                 day = 1,
00224                 month++;
00225 }
00226 
00227 void DateTime::prevday () {
00228     day=day-1;
00229     if (day<1) {
00230         month--;
00231         if (month<1)
00232             year--,
00233             month=12;
00234         if (month==2)
00235             day=28;
00236         else
00237             if (month==4 || month==6 || month==9 || month==11)
00238                 day=30;
00239             else
00240                 if (month==1 || month==3 || month==5 || month==7
00241                     || month==8 || month==10 || month==12)
00242                     day=31;
00243     }
00244 }
00245 
00246 void DateTime::corrange () {
00247     while (hours<0)
00248         hours+=24,
00249         prevday();
00250     while (hours>24)
00251         hours-=24,
00252         nextday();
00253 }
00254 
00255 String DateTime::text () const {
00256     String res = format ("%02d.%02d.%04d %02d:%02d:%02.2g",
00257                          day, month, year, hour(), min(), sec());
00258     return res;
00259 }
00260 
00261 String DateTime::text_time () const {
00262     String res = format ("%02d:%02d:%02.2g", hour(), min(), sec());
00263     return res;
00264 }
00265 
00266 String DateTime::text_time (const String& form) const {
00267 
00268     struct tm* tms = to_tm ();
00269 
00270     //TRACE3 ("%d.%d.%d", tms->tm_mday, tms->tm_mon, tms->tm_year);
00271     char buffer [80];
00272     strftime (buffer, 80, (CONSTR) form, tms);
00273 
00274     delete tms;
00275 
00276     return buffer;
00277 }
00278 
00279 int DateTime::isduring (const TimePeriod& period) const {
00280     return operator> (period.start) && operator< (period.end);
00281 }
00282 
00283 typedef struct tm tmstr;
00284 
00285 struct tm* DateTime::to_tm () const {
00286     struct tm* result = (struct tm*) new tmstr;
00287     result->tm_sec  = int (sec ());
00288     result->tm_min  = min ();
00289     result->tm_hour = int (hours);
00290     result->tm_mday = day;
00291     result->tm_mon  = month-1;
00292     result->tm_year = year-1900;
00293     result->tm_wday = 0;
00294     result->tm_yday = 0;
00295     result->tm_isdst= dst;
00296     return result;
00297 }
00298 
00299 
00300 
00302 //                                                                           //
00303 //                  --       | o             ___                             //
00304 //                   |       |    ___    _   |  \   ___                      //
00305 //                   | |   | | |  ___| |/ \  |   |  ___| \   |               //
00306 //               |   | |   | | | (   | |   | |   | (   |  \  |               //
00307 //                \_/   \__! | |  \__| |   | |__/   \__|   \_/               //
00308 //                                                        \_/                //
00310 
00311 double _JD (int day, int month, int year) {
00312     ASSERT (month!=0);
00313 
00314     if (month<=2)
00315         year = year-1,
00316         month = month+12;
00317 
00318     double  b = 0.0; // If after Oct 15. 1582
00319     if (year > 1582 || (year==1582 && (month>10 || (month==10 && day>=15)))) {
00320         double a = int (year/100.0);
00321         b = 2 - a + int (a/4.0);
00322     }
00323 
00324     return int (365.25*(year+4716)) + int ((month+1)*30.6001) + day + b - 1524.5;
00325 }
00326 
00327 void JulianDay::make (const DateTime& dt) {
00328     mJD = _JD (dt.day,dt.month,dt.year) + dt.dectime();
00329 }
00330 

Generated at Tue Dec 4 19:53:24 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001