casa
$Rev:20696$
|
00001 //# MVTime.h: Class to handle date/time type conversions and I/O 00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: MVTime.h 21051 2011-04-20 11:46:29Z gervandiepen $ 00027 00028 #ifndef CASA_MVTIME_H 00029 #define CASA_MVTIME_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <casa/Quanta/Quantum.h> 00035 #include <casa/iosfwd.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 //# Forward Declarations 00040 class String; 00041 class MVEpoch; 00042 class Time; 00043 00044 //# Constants (SUN compiler does not accept non-simple default arguments) 00045 00046 // <summary> 00047 // Class to handle date/time type conversions and I/O 00048 // </summary> 00049 00050 // <use visibility=export> 00051 00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tMeasure" demos=""> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 // <li> <linkto class=Quantum>Quantum</linkto> 00057 // <li> <linkto class=MVAngle>MVAngle</linkto> 00058 // <li> <a href="http://mcps.k12.md.us/departments/year2000/Technology/ISO_std.html"> 00059 // ISO8601 standard</a> on dates and time. 00060 // </prerequisite> 00061 // 00062 // <etymology> 00063 // From Measure, Value and Time 00064 // </etymology> 00065 // 00066 // <synopsis> 00067 // An MVTime is a simple Double for date/time conversions and I/O. 00068 // Its internal value is in MJD. For high precision the 00069 // <linkto class=MVEpoch>MVEpoch</linkto> class should be used.<br> 00070 // It can be constructed from a Double (in which case MJD are assumed), 00071 // or from a Quantity (<src>Quantum<Double></src>). Quantities must be in 00072 // either angle or time units, or from a 00073 // <linkto class=MVEpoch>MVEpoch</linkto><br> 00074 // The <linkto class=Time>OS/Time class</linkto> can be used as both input 00075 // and output. An <src>MVTime(Time)</src> constructor exists, as well 00076 // as a <src>Time getTime()</src>.<br> 00077 // Construction from year, month, day is also supported. 00078 // <note role=caution> Dates before 16 Oct 1582 are considered to be Julian, 00079 // rather than Gregorian</note> 00080 // It has an automatic conversion to Double, so all standard mathematical 00081 // operations can operate on it.<br> 00082 // The class has a number of special functions to obtain data: 00083 // <ul> 00084 // <li> <src>Double day()</src> will return value in days 00085 // <li> <src>Double hour()</src> will return value in hours 00086 // <li> <src>Double minute()</src> will return value in minutes 00087 // <li> <src>Double second()</src> will return value in seconds 00088 // <li> <src>Quantity get()</src> will return days 00089 // <li> <src>Quantity get(Unit)</src> will return in specified units 00090 // (angle(in which case it will be between -pi and +pi) or time) 00091 // <li> <src>uInt weekday()</src> will return day of week (1=Mon, 7=Sun) 00092 // <li> <src>uInt month()</src> will return month (1=Jan) 00093 // <li> <src>Int year()</src> will return year 00094 // <li> <src>uInt monthday()</src> will return day of the month 00095 // <li> <src>uInt yearday()</src> will return day of year (Jan01 = 1) 00096 // <li> <src>uInt yearweek()</src> will return week of year 00097 // (week containing Jan04 = 1, week start on Monday). 00098 // The week before the first week will be called 0, contrary 00099 // to standard practice (week 53/52 of previous year). 00100 // <li> <src>Int ymd()</src> will return yyyymmdd as a single number 00101 // <li> <src>const String &dayName()</src> will return name of day 00102 // (Sun, Mon, Tue, Wed, Thu, Fri, Sat) 00103 // <li> <src>const String &monthName()</src> will retrun name of Month 00104 // (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) 00105 // </ul> 00106 // Output formatting is done with the <src><<</src> statement, with the 00107 // following rules: 00108 // <ul> 00109 // <li> standard output is done in the following format: 00110 // <src>hh:mm:ss.tt</src>. The number of 00111 // digits presented will be based on the precision attached to the 00112 // current stream 00113 // <li> output can be formatted by using either the <src>setFormat()</src> 00114 // method for global angle format setting, or the output of 00115 // <src>MVTime::Format()</src> data for a once off change (see later). 00116 // Formats have a first argument which 00117 // determines the type (default, if not given, MVTime::TIME, other 00118 // possibility MVTime::ANGLE (as +ddd.mm.ss.tt..), 00119 // the second the number of digits wanted (default stream precision), 00120 // with a value: 00121 // <ul> 00122 // <li> <3 : hh:: only 00123 // <li> <5 : hh:mm: 00124 // <li> <7 : hh:mm:ss 00125 // <li> >6 : with precision-6 t's added 00126 // </ul> 00127 // comparable for angle. <note role=tip> The added colons are 00128 // to enable input 00129 // checking of the format. Look at the 'clean' types to bypass them. 00130 // </note> 00131 // The <src>MVTime::YMD</src> format implies TIME, and will 00132 // precede the time with 'yyyy/mm/dd/' (or use 00133 // <src>MVTime::YMD_ONLY</src> to include <src>NO_TIME</src> 00134 // modifier).<br> 00135 // The <src>MVTime::DMY</src> format implies TIME, and will 00136 // precede the time with 'dd-Mon-yyyy/'.<br> 00137 // The <src>MVTime::FITS</src> format implies TIME, and will 00138 // precede the time with 'ccyy-mm-ddT'. 00139 // <br> 00140 // The output format can be modified with modifiers (specify as 00141 // MVTime::TIME | MVTime::MOD (or + MVTime::MOD)). 00142 // <note role=caution> For overloading/casting 00143 // problems with some compilers, the 00144 // use of modifiers necessitates either the presence of a precision 00145 // (i.e. <src>(A|B, prec)</src>), or an explicit cast: 00146 // <src>((MVTime::formatTypes)(A|B))</src>, or make use of 00147 // the provided <src>TIME[_CLEAN][_NO_H[M]]</src> and 00148 // <src>ANGLE[_CLEAN][_NO_D[M]]</src>.</note> 00149 // The modifiers can be: 00150 // <ul> 00151 // <li> <src>MVTime::CLEAN</src> to suppress leading or trailing 00152 // periods (or colons for TIME). Note that he result can not be 00153 // read automatically. 00154 // <li> <src>MVTime::NO_H</src> (or <src>NO_D</src>) to suppress 00155 // the output of hours (or degrees): useful for offsets 00156 // <li> <src>MVTime::NO_HM</src> (or <src>NO_DM</src>), to 00157 // suppress the degrees and minutes. 00158 // <li> <src>MVTime::DAY</src> will precede the output with 00159 // 'Day-' (e.g. Wed-) 00160 // <li> <src>MVTime::NO_TIME</src> will suppress printing of time. 00161 // </ul> 00162 // Output in formats like <src>20'</src> can be done via the standard 00163 // Quantum output (e.g. <src> stream << time.get("'") </src>). 00164 // <li> Available formats: 00165 // <ul> 00166 // <li> MVTime::ANGLE in +ddd.mm.ss.ttt format 00167 // <li> MVTime::TIME in hh:mm:ss.ttt format 00168 // <li> MVTime::[ANGLE|TIME]_CLEAN format without superfluous periods 00169 // <li> MVTime::[ANGLE|TIME][_CLEAN]_NO_[D|H][M] in format with 00170 // leading zero fields left empty. 00171 // <li> MVTime::CLEAN modifier for suppressing superfluous periods 00172 // <li> MVTime::NO_[D|H][M] modifier to suppress first field(s) 00173 // <li> MVTime::DIG2 modifier to get +dd.mm.ss.ttt in angle or 00174 // time format(i.e. in range -90 - +90 or -12 - +12) 00175 // <li> MVTime::LOCAL modifier to produce local time (as derived from 00176 // aipsrc time.tzoffset). In FITS mode the time zone will 00177 // be appended (as <src><sign>hh:mm</src>). 00178 // <note role=caution>The adding of the timezone is not part 00179 // of the FITS standard, but of the underlying ISO standard. It can 00180 // be used to export local times in standard format.</note> 00181 // </ul> 00182 // </ul> 00183 // The default formatting can be overwritten by a 00184 // <src> MVTime::setFormat(); </src> statement; which returns an 00185 // MVTime::Format 00186 // structure, that can be used in a subsequent one to reset to previous. 00187 // The format set holds for all MVTime output on all streams.<br> 00188 // Temporary formats (i.e. for one MVTime output only), can be set by 00189 // outputting a format (i.e. <src> stream << MVTime::Format() << ... </src>). 00190 // <note role=caution> A setFormat() will also 00191 // reset any lingering temporary format. 00192 // A setFormat(getFormat()) will reset without changing. Problems could 00193 // arise in parallel processors. </note> 00194 // Input can be read if the values are in any of the above (non-clean) output 00195 // formats. <br> 00196 // For other formatting practice, the output can be written to a String with 00197 // the string() member functions.<br> 00198 // Note that using a temporary format is inherently thread-unsafe because 00199 // the format is kept in a static variable. Another thread may overwrite 00200 // the format just set. The only thread-safe way to format an MVTime is using 00201 // a <src>print</src> or <src>string</src> that accepts a Format object. 00202 // 00203 // Strings and input can be converted to an MVTime (or Quantity) by 00204 // <src>Bool read(Quantity &out, const String &in)</src> and 00205 // <src> istream >> MVTime &</src>. In the latter case the actual 00206 // reading is done by the String read, which reads between white-spaces.<br> 00207 // The following input formats (note no blanks allowed) are supported 00208 // (+stands for an optional + or -; v for an unsigned integer; dv for a 00209 // floating number. [] indicate optional values. Separating codes are 00210 // case insensitive), numbers(like yyyy) can be of any length: 00211 // <ul> 00212 // <li> today -- (UT) time now 00213 // <li> today/[time] -- time on today (0:0:0 if omitted) 00214 // <li> yyyy/mm/dd[/time] -- date + time. An omitted date (leading /) 00215 // will be today + time; an omitted month will 00216 // indicate use of day number in year (1 == 1/1) 00217 // <li> dd[-]MMM[-]yyyy[/time] -- date +time If yyyy <100: around 2000. 00218 // MMM can be at least first three characters 00219 // of month name; or a month number (1 == Jan). 00220 // Omitted month indicates day is day number. 00221 // <li> ccyy-mm-dd[Ttime[Z|+-hh[:mm]]] -- new FITS format the 'T' as time 00222 // separator. Time should be UTC. 00223 // The 'Z' separator (for UTC) is part of an 00224 // earlier FITS proposal, and will be recognised 00225 // for backward compatibility. 00226 // A signed hh or hh:mm can be present to 00227 // indicate time zone. This value will be 00228 // subtracted to give UTC. To recognise this 00229 // format, the year should be greater than 1000. 00230 // <note role=caution> The time-zone information 00231 // is not part of the FITS standard, but of the 00232 // underlying ISO standard.</note> 00233 // </ul> 00234 // The time can be expressed as described in 00235 // <linkto class=MVAngle>MVAngle</linkto> 00236 // Examples of valid strings: 00237 // <srcblock> 00238 // ToDay note case independence 00239 // 1996/11/20 20 November 1996 0h UT 00240 // 1996/11/20/5:20 20 November 1996 at 5h20m 00241 // 20Nov96-5h20m same (again no case dependence) 00242 // 1996-11-20T5:20 same (FITS format, case dependent) 00243 // </srcblock> 00244 // </synopsis> 00245 // 00246 // <example> 00247 // See synopsis 00248 // </example> 00249 // 00250 // <motivation> 00251 // To be able to format date/time-like values in user-required ways. 00252 // </motivation> 00253 // 00254 // <todo asof="1996/11/15"> 00255 // <li> Nothing I know of 00256 // </todo> 00257 00258 class MVTime { 00259 00260 public: 00261 00262 //# Enumerations 00263 // Format types 00264 enum formatTypes { 00265 ANGLE, 00266 TIME, 00267 CLEAN = 4, 00268 NO_D = 8, 00269 NO_DM = NO_D+16, 00270 YMD = TIME+32, 00271 DMY = TIME+64, 00272 DAY = 128, 00273 NO_TIME = 256, 00274 MJD = TIME+512, 00275 DIG2 = 1024, 00276 FITS = TIME+2048, 00277 LOCAL = 4096, 00278 NO_H = NO_D, 00279 NO_HM = NO_DM, 00280 ANGLE_CLEAN = ANGLE + CLEAN, 00281 ANGLE_NO_D = ANGLE + NO_D, 00282 ANGLE_NO_DM = ANGLE + NO_DM, 00283 ANGLE_CLEAN_NO_D = ANGLE + CLEAN + NO_D, 00284 ANGLE_CLEAN_NO_DM = ANGLE + CLEAN + NO_DM, 00285 TIME_CLEAN = TIME + CLEAN, 00286 TIME_NO_H = TIME + NO_H, 00287 TIME_NO_HM = TIME + NO_HM, 00288 TIME_CLEAN_NO_H = TIME + CLEAN + NO_H, 00289 TIME_CLEAN_NO_HM = TIME + CLEAN + NO_HM, 00290 YMD_ONLY = YMD + NO_TIME, 00291 MOD_MASK = CLEAN + NO_DM + DAY + NO_TIME + DIG2 + LOCAL 00292 }; 00293 00294 //# Local structure 00295 // Format structure 00296 class Format { 00297 public: 00298 friend class MVTime; 00299 Format(MVTime::formatTypes intyp = MVTime::TIME, 00300 uInt inprec = 0) : 00301 typ(intyp), prec(inprec) {;}; 00302 Format(uInt inprec) : 00303 typ(MVTime::TIME), prec(inprec) {;}; 00304 // Construct from type and precision (present due to overlaoding problems) 00305 Format(uInt intyp, uInt inprec) : 00306 typ((MVTime::formatTypes)intyp), prec(inprec) {;}; 00307 Format(const Format &other) : 00308 typ(other.typ), prec(other.prec) {;}; 00309 private: 00310 MVTime::formatTypes typ; 00311 uInt prec; 00312 }; 00313 00314 //# Friends 00315 // Output a date/time 00316 friend ostream &operator<<(ostream &os, const MVTime &meas); 00317 // Input a date/time 00318 friend istream &operator>>(istream &is, MVTime &meas); 00319 // Set a temporary format 00320 friend ostream &operator<<(ostream &os, const MVTime::Format &form); 00321 00322 //# Constructors 00323 // Default constructor: generate a zero value 00324 MVTime(); 00325 // Copy constructor 00326 MVTime(const MVTime &other); 00327 // Copy assignment 00328 MVTime &operator=(const MVTime &other); 00329 // Constructor from Double (in MJD) 00330 MVTime(Double d); 00331 // Constructor from Quantum : value can be an angle or time 00332 // <thrown> 00333 // <li> AipsError if not a time or angle 00334 // </thrown> 00335 MVTime(const Quantity &other); 00336 // Constructor from Time 00337 MVTime(const Time &other); 00338 // Constructor from MVEpoch; 00339 MVTime(const MVEpoch &other); 00340 // Constructor from yy, mm, dd, dd (all dd with fractions allowed) 00341 MVTime(Int yy, Int mm, Double dd, Double d=0.0); 00342 00343 //# Destructor 00344 ~MVTime(); 00345 00346 //# Operators 00347 // Conversion operator 00348 operator Double() const; 00349 00350 //# General member functions 00351 // Make res time Quantity from string. The String version will accept 00352 // a time/angle Quantity as well. The chk checks for eos 00353 // <group> 00354 static Bool read(Quantity &res, const String &in); 00355 static Bool read(Quantity &res, MUString &in); 00356 static Bool read(Quantity &res, const String &in, Bool chk); 00357 static Bool read(Quantity &res, MUString &in, Bool chk); 00358 // </group> 00359 // Get value of date/time (MJD) in given units 00360 // <group> 00361 Double day() const; 00362 Double hour() const; 00363 Double minute() const; 00364 Double second() const; 00365 Quantity get() const; 00366 Quantity get(const Unit &inunit) const; 00367 Time getTime() const; 00368 // </group> 00369 // Get indicated part of the time/date 00370 // <group> 00371 const String &dayName() const; 00372 static const String &dayName(uInt which); 00373 const String &monthName() const; 00374 static const String &monthName(uInt which); 00375 // Mon = 1; Sun = 7; 00376 uInt weekday() const; 00377 // Jan =1 00378 uInt month() const; 00379 uInt monthday() const; 00380 Int year() const; 00381 Int ymd() const; 00382 uInt yearday() const; 00383 uInt yearweek() const; 00384 // </group> 00385 // Output data. 00386 // <note role=warning> 00387 // The first function below is thread-unsafe because it uses the result of 00388 // the setFormat function which changes a static class member. 00389 // The other functions are thread-safe because the format is directly given. 00390 // </note> 00391 // <group> 00392 String string() const; 00393 String string(MVTime::formatTypes intyp, uInt inprec = 0) const; 00394 String string(uInt intyp, uInt inprec) const; 00395 String string(uInt inprec) const; 00396 String string(const MVTime::Format &form) const; 00397 void print(ostream &oss, const MVTime::Format &form) const; 00398 // </group> 00399 // Set default format 00400 // <note role=warning> 00401 // It is thread-unsafe to print using the setFormat functions because they 00402 // change a static class member. The only thred-safe way to print a time is 00403 // to use the print function above. 00404 // </note> 00405 // <group> 00406 static Format setFormat(MVTime::formatTypes intyp, 00407 uInt inprec = 0); 00408 static Format setFormat(uInt intyp, uInt inprec); 00409 static Format setFormat(uInt inprec = 0); 00410 static Format setFormat(const Format &form); 00411 // </group> 00412 // Get default format 00413 static Format getFormat(); 00414 // Get code belonging to string. 0 if not known 00415 static MVTime::formatTypes giveMe(const String &in); 00416 // Get time zone offset (in days) 00417 static Double timeZone(); 00418 00419 private: 00420 //# Data 00421 // Value 00422 Double val; 00423 // Default format 00424 static MVTime::Format defaultFormat; 00425 // Temporary format 00426 // <group> 00427 static MVTime::Format interimFormat; 00428 static Bool interimSet; 00429 // </group> 00430 00431 //# Member functions 00432 // Get the y,m,d values 00433 void ymd(Int &yyyy, Int &mm, Int &dd) const; 00434 }; 00435 00436 // Global functions. 00437 // Output 00438 // <group> 00439 ostream &operator<<(ostream &os, const MVTime &meas); 00440 ostream &operator>>(ostream &is, MVTime &meas); 00441 // Set a temporary format (thread-unsafe). 00442 ostream &operator<<(ostream &os, const MVTime::Format &form); 00443 // </group> 00444 00445 // is equal operator, uses operator Double which returns days 00446 inline Bool operator==(const MVTime &lh, const MVTime &rh) 00447 { return (lh.operator Double() == rh.operator Double());} 00448 00449 00450 00451 } //# NAMESPACE CASA - END 00452 00453 #endif