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. |