casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MVTime.h
Go to the documentation of this file.
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