Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Date.h

Go to the documentation of this file.
00001 /* SimData: Data Infrastructure for Simulations
00002  * Copyright (C) 2002, 2003 Mark Rose <tm2@stm.lbl.gov>
00003  * 
00004  * This file is part of SimData.
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00021 
00055 #ifndef __SIMDATA_DATE_H__
00056 #define __SIMDATA_DATE_H__
00057 
00058 #include <SimData/Archive.h>
00059 #include <SimData/Exception.h>
00060 #include <SimData/BaseType.h>
00061 
00062 
00063 
00064 NAMESPACE_SIMDATA
00065 
00066 
00067 #define SIMDATA_F1p0_60p0      0.016666666666666667L
00068 #define SIMDATA_F1p0_24p0      0.041666666666666667L
00069 #define SIMDATA_F1p0_36525p0   0.000027378507871321L
00070 #define SIMDATA_F1p0_86400p0   0.000011574074074074L
00071 
00072 
00073 typedef double radian_t;
00074 typedef double degree_t;
00075 
00076 
00078 // 'fast' timing routines (1-2 msec accuracy)
00079 
00080 typedef double timing_t;
00081 
00084 void tstart(void);
00085 
00088 void tend(void);
00089 
00095 double tval();
00096 
00102 timing_t get_realtime();
00103 
00104 
00106 // end of timing routines
00107 
00108 
00109 
00110 // TODO: please merge these with global type definitions
00111 typedef int sint32;
00112 typedef short sint16;
00113 typedef unsigned char uint08;
00114 
00115 
00118 SIMDATA_EXCEPTION(InvalidDate);
00119 
00131 class SIMDATA_EXPORT Date {
00132 public:
00133         typedef sint32 julian_t;
00134         typedef uint08 day_t;
00135         typedef uint08 weekday_t;
00136         typedef uint08 month_t;
00137         typedef sint16 year_t;
00138 
00139         typedef enum {
00140                 MONDAY       = 1,
00141                 TUESDAY      = 2,
00142                 WEDNESDAY    = 3,
00143                 THURSDAY     = 4,
00144                 FRIDAY       = 5,
00145                 SATURDAY     = 6,
00146                 SUNDAY       = 7
00147         } WEEKDAY;
00148 
00149         typedef enum {
00150                 JANUARY   = 1,
00151                 FEBRUARY  = 2,
00152                 MARCH     = 3,
00153                 APRIL     = 4,
00154                 MAY       = 5,
00155                 JUNE      = 6,
00156                 JULY      = 7,
00157                 AUGUST    = 8,
00158                 SEPTEMBER = 9,
00159                 OCTOBER   = 10,
00160                 NOVEMBER  = 11,
00161                 DECEMBER  = 12
00162         } MONTH;
00163 
00166         Date() {
00167                 m_julian = 0;
00168                 _updateYMD();
00169         }
00170 
00173         Date(year_t year, month_t month, day_t day);
00174         
00177         Date(julian_t julian) {
00178                 m_julian = julian;
00179                 _updateYMD();
00180         }
00181 
00184         Date(const Date &d) {
00185                 *this = d;
00186         }
00187 
00188 #ifndef SWIG
00189 
00191         const Date &operator=(const Date &d) {
00192                 m_year = d.m_year;
00193                 m_month = d.m_month;
00194                 m_day = d.m_day;
00195                 m_julian = d.m_julian;
00196                 return *this;
00197         }
00198 #endif // SWIG
00199 
00202         static bool validYMD(year_t year, month_t month, day_t day) {
00203                 if (month < 1 || month > 12 || day < 1) return false;
00204                 return (day <= (isLeap(year) ? 
00205                            days_in_months[1][month] : days_in_months[0][month]));
00206         }
00207 
00210         bool isLeap() const {
00211                 return isLeap(m_year);
00212         }
00213 
00216         static bool isLeap(year_t year) {
00217                 return ( (((year % 4) == 0) && ((year % 100) != 0)) || (year % 400) == 0 );
00218         }
00219         
00222         weekday_t getWeekday() const {
00223                 return ((m_julian) % 7) + 1;
00224         }
00225 
00228         month_t getMonth() const {
00229                 return m_month;
00230         }
00231         
00234         month_t getDay() const {
00235                 return m_day;
00236         }
00237         
00240         year_t getYear() const {
00241                 return m_year;
00242         }
00243 
00246         julian_t getJulian() const {
00247                 return m_julian;
00248         }
00249 
00252         const char *getMonthName() const;
00253 
00256         const char *getMonthShortName() const;
00257         
00260         const char *getWeekdayName() const;
00261         
00264         const char *getWeekdayShortName() const;
00265 
00268         void setJulian(julian_t j) {
00269                 *this = Date(j);
00270         }
00271 
00274         int getDayOfYear() const {
00275                 int index;
00276                 index = isLeap() ? 1 : 0;
00277                 return (days_in_year[index][m_month] + m_day);
00278         }
00279 
00282         int getMondayWeekOfYear() const;
00283 
00286         int getSundayWeekOfYear() const;
00287         
00290         bool isFirstOfMonth() const {
00291                 return (m_day == 1);
00292         }
00293 
00296         bool isLastOfMonth() const {
00297                 int index = isLeap() ? 1 : 0;
00298                 return m_day == days_in_months[index][m_month];
00299         }
00300         
00303         void addDays(int ndays) {
00304                 m_julian += ndays;
00305                 _updateYMD();
00306         }
00307         
00310         void subtractDays(int ndays) {
00311                 m_julian -= ndays;
00312                 _updateYMD();
00313         }
00314 
00319         void addMonths(int nmonths);
00320         
00325         void subtractMonths(int nmonths);
00326 
00331         void addYears(int nyears);
00332 
00337         void subtractYears(int nyears);
00338 
00341         static int getDaysInMonth(month_t month, year_t year);
00342 
00345         static int getWeeksInYear(year_t year);
00346         
00349         static int getSundayWeeksInYear(year_t year);
00350 
00355         static int compare(const Date &a, const Date &b);
00356         
00362         virtual int compare(const Date &other) const { 
00363                 return compare(*this, other); 
00364         }
00365 
00368         void convert(struct tm *tm) const;
00369 
00372         std::string formatString(const char *format) const;
00373 
00378         virtual std::string asString() const {
00379                 return formatString("%Y/%m/%d");
00380         }
00381 
00384         virtual std::string typeString() const { return "type::Date"; }
00385         
00386 private:
00387         static const day_t days_in_months[2][13];
00388         static const int days_in_year[2][14];
00389 
00390         julian_t m_julian;
00391         day_t m_day;
00392         month_t m_month;
00393         year_t m_year;
00394 
00395         void _updateJulian();
00396         void _updateYMD();
00397 
00398         bool validYMD() const {
00399                 return validYMD(m_year, m_month, m_day);
00400         }
00401 };
00402 
00403 
00404 
00424 class SIMDATA_EXPORT Zulu {
00425 
00426 public:
00427         typedef double time_t;
00428 
00433         Zulu() {
00434                 m_time = 0;
00435                 m_tz = 0;
00436         }
00437         
00445         Zulu(int hour, int minute, time_t second, int tz=0) {
00446                 m_time = hour*3600.0 + minute*60.0 + second;
00447                 m_tz = tz;
00448         }
00449         
00455         Zulu(time_t second, int tz=0) {
00456                 m_time = second;
00457                 m_tz = tz;
00458         }
00459         
00462         Zulu(const Zulu &z) {
00463                 *this = z;
00464         }
00465         
00466 #ifndef SWIG
00467 
00469         const Zulu &operator=(const Zulu &z) {
00470                 m_time = z.m_time;
00471                 m_tz = z.m_tz;
00472                 return *this;
00473         }
00474 #endif // SWIG
00475 
00480         void setTZ(int tz) {
00481                 m_tz = tz;
00482         }
00483 
00486         int getTZ() const {
00487                 return m_tz;
00488         }
00489         
00496         int reduce();
00497         
00502         time_t getTime(bool local=false) const { 
00503                 return m_time + (local ? (m_tz * 3600.0) : 0.0);
00504         }
00505         
00508         bool overflow() const {
00509                 return m_time >= 86400.0f;
00510         }
00511         
00516         int getHour(bool local=false) const {
00517                 int adjust = local ? m_tz : 0;
00518                 return ((((int)m_time) / 3600) + adjust) % 24;
00519         }
00520         
00523         int getMinute() const {
00524                 return (((int)m_time) / 60) % 60;
00525         }
00526         
00529         int getSecond() const {
00530                 return ((int)m_time) % 60;
00531         }
00532 
00537         int rollover() {
00538                 int days = 0;
00539                 if (overflow()) {
00540                         days = (int) (m_time * 0.00001157407407407407);
00541                         if (m_time < 0.0) days--;
00542                         m_time -= days * 86400.0f;
00543                 }
00544                 return days;
00545         }
00546         
00552         int addTime(time_t dt) {
00553                 m_time += dt;
00554                 return rollover();
00555         }
00556         
00562         int setTime(time_t t, bool local=false) {
00563                 if (local) t -= m_tz * 3600.0;
00564                 m_time = t;
00565                 return rollover();
00566         }
00567 
00573         void convert(struct tm *tm, bool local=false) const;
00574         
00580         std::string formatString(const char *format, bool local=false) const;
00581         
00582         
00585         virtual std::string asString() const {
00586                 return formatString("%H:%M:%Sz");
00587         }
00588 
00591         virtual std::string typeString() const { return "type::Zulu"; }
00592 
00593 private:
00594         time_t m_time;
00595         int m_tz;
00596 };
00597 
00598 
00599 
00604 class SIMDATA_EXPORT DateZulu: public Date, public Zulu {
00605 
00606 
00607 public:
00608 
00613         DateZulu(): Date(), Zulu() {}
00614 
00624         DateZulu(year_t year, month_t month, day_t day, int hour, int minute, time_t second):
00625                 Date(year, month, day),
00626                 Zulu(hour, minute, second) {
00627                 addDays(reduce());
00628         }
00629 
00637         DateZulu(julian_t julian, int hour, int minute, time_t second):
00638                 Date(julian),
00639                 Zulu(hour, minute, second) {
00640                 addDays(reduce());
00641         }
00642 
00645         DateZulu(const DateZulu &dz): Date(dz), Zulu(dz) { }
00646 
00647 #ifndef SWIG
00648 
00650         const DateZulu &operator=(const DateZulu &dz) {
00651                 Date::operator=(dz);
00652                 Zulu::operator=(dz);
00653                 return *this;
00654         }
00655 #endif // SWIG
00656                 
00657         
00664         void convert(struct tm *tm, bool local=false) const;
00665 
00674         std::string formatString(const char *format, bool local=false) const;
00675 
00681         virtual std::string asString() const {
00682                 return formatString("%Y/%m/%d %H:%M:%Sz");
00683         }
00684 
00687         virtual std::string typeString() const { return "type::DateZulu"; }
00688         
00694         int addTime(time_t dt) {
00695                 int days = Zulu::addTime(dt);
00696                 addDays(days);
00697                 return days;
00698         }
00699 
00705         int setTime(time_t t) {
00706                 int days = Zulu::setTime(t);
00707                 addDays(days);
00708                 return days;
00709         }
00710 
00718         double getJulianDate() const {
00719                 double j = getJulian();
00720                 double t = getTime() * SIMDATA_F1p0_86400p0 + 0.5;
00721                 return j + t;
00722         }
00723 
00730         double getAccurateMST(radian_t longitude=0.0L) const;
00731 
00739         double getMST(radian_t longitude=0.0L) const;
00740 
00741 };
00742 
00743 
00744 
00750 typedef DateZulu::time_t SimTime;
00751 
00752 
00758 class SIMDATA_EXPORT SimDate: public DateZulu, public BaseType {
00759 
00760         SimTime reference;
00761         SimTime pause_time;
00762         SimTime last_update;
00763         bool paused;
00764 
00765 public:
00766         
00771         SimDate(): DateZulu(), BaseType() {
00772                 paused = false;
00773                 last_update = get_realtime();
00774                 setReferenceTime(getTime());
00775         }
00776 
00786         SimDate(year_t year, month_t month, day_t day, int hour, int minute, time_t second):
00787                 DateZulu(year, month, day, hour, minute, second),
00788                 BaseType() {
00789                 paused = false;
00790                 last_update = get_realtime();
00791                 setReferenceTime(getTime());
00792         }
00793                 
00801         SimDate(julian_t julian, int hour, int minute, time_t second):
00802                 DateZulu(julian, hour, minute, second),
00803                 BaseType() {
00804                 paused = false;
00805                 last_update = get_realtime();
00806                 setReferenceTime(getTime());
00807         }
00808                 
00814         SimDate(const SimDate &d): DateZulu(d), BaseType(d) {
00815                 paused = false;
00816                 last_update = get_realtime();
00817                 setReferenceTime(getTime());
00818         }
00819         
00820 #ifndef SWIG
00821 
00823         const SimDate &operator=(const SimDate &d);
00824 #endif // SWIG  
00825 
00830         virtual std::string asString() const {
00831                 return formatString("%Y/%m/%d %H:%M:%Sz");
00832         }
00833 
00836         virtual std::string typeString() const { return "type::SimDate"; }
00837         
00845         static SimTime interval(SimTime a, SimTime b) {
00846                 a -= b;
00847                 if (a < 0.0) return a + 86400.0;
00848                 return a;
00849         }
00850 
00856         static SimTime getSystemTime() {
00857                 return get_realtime();
00858         }
00859 
00871         double update();
00872 
00878         virtual int compare(const SimDate &other) const { 
00879                 int date_comp = Date::compare(*this, other); 
00880                 if (date_comp != 0) return date_comp;
00881                 if (getTime() > other.getTime()) return 1;
00882                 if (getTime() < other.getTime()) return -1;
00883                 return 0;
00884         }
00885 
00891         void setReferenceTime(SimTime target) {
00892                 reference = get_realtime() - target;
00893         }
00894 
00900         void pause() {
00901                 paused = true;
00902                 pause_time = get_realtime();
00903         }
00904 
00910         void unpause() {
00911                 paused = false;
00912                 setReferenceTime(pause_time - reference);
00913         }
00914 
00917         bool isPaused() const {
00918                 return paused;
00919         }
00920 
00925         int addTime(time_t dt) {
00926                 int days = DateZulu::addTime(dt);
00927                 if (days != 0) {
00928                         reference += days * 86400.0;
00929                 }
00930                 return days;
00931         }
00932 
00937         int setTime(time_t t) {
00938                 int days = DateZulu::setTime(t);
00939                 if (days != 0) {
00940                         reference += days * 86400.0;
00941                 }
00942                 return days;
00943         }
00944 
00947         virtual void serialize(Archive&);
00948 
00957         virtual void parseXML(const char* cdata);
00958         
00959 }; 
00960 
00961 NAMESPACE_SIMDATA_END
00962 
00963 #endif // __SIMDATA_DATE_H__
00964 

SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage.

Generated on Tue Oct 14 12:06:38 2003, using Doxygen 1.2.18.

[SF.net]