//# MVTime.h: Class to handle date/time type conversions and I/O //# Copyright (C) 1996,1997,1998,1999,2000,2001 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_MVTIME_H #define CASA_MVTIME_H //# Includes #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN //# Forward Declarations class String; class MVEpoch; class Time; //# Constants (SUN compiler does not accept non-simple default arguments) // // Class to handle date/time type conversions and I/O // // // // // //
  • Quantum //
  • MVAngle //
  • // ISO8601 standard on dates and time. // // // // From Measure, Value and Time // // // // An MVTime is a simple Double for date/time conversions and I/O. // Its internal value is in MJD. For high precision the // MVEpoch class should be used.
    // It can be constructed from a Double (in which case MJD are assumed), // or from a Quantity (Quantum). Quantities must be in // either angle or time units, or from a // MVEpoch
    // The OS/Time class can be used as both input // and output. An MVTime(Time) constructor exists, as well // as a Time getTime().
    // Construction from year, month, day is also supported. // Dates before 16 Oct 1582 are considered to be Julian, // rather than Gregorian // It has an automatic conversion to Double, so all standard mathematical // operations can operate on it.
    // The class has a number of special functions to obtain data: //
      //
    • Double day() will return value in days //
    • Double hour() will return value in hours //
    • Double minute() will return value in minutes //
    • Double second() will return value in seconds //
    • Quantity get() will return days //
    • Quantity get(Unit) will return in specified units // (angle(in which case it will be between -pi and +pi) or time) //
    • uInt weekday() will return day of week (1=Mon, 7=Sun) //
    • uInt month() will return month (1=Jan) //
    • Int year() will return year //
    • uInt monthday() will return day of the month //
    • uInt yearday() will return day of year (Jan01 = 1) //
    • uInt yearweek() will return week of year // (week containing Jan04 = 1, week start on Monday). // The week before the first week will be called 0, contrary // to standard practice (week 53/52 of previous year). //
    • Int ymd() will return yyyymmdd as a single number //
    • const String &dayName() will return name of day // (Sun, Mon, Tue, Wed, Thu, Fri, Sat) //
    • const String &monthName() will retrun name of Month // (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) //
    // Output formatting is done with the << statement, with the // following rules: //
      //
    • standard output is done in the following format: // hh:mm:ss.tt. The number of // digits presented will be based on the precision attached to the // current stream //
    • output can be formatted by using either the setFormat() // method for global angle format setting, or the output of // MVTime::Format() data for a once off change (see later). // Formats have a first argument which // determines the type (default, if not given, MVTime::TIME, other // possibility MVTime::ANGLE (as +ddd.mm.ss.tt..), // the second the number of digits wanted (default stream precision), // with a value: //
        //
      • <3 : hh:: only //
      • <5 : hh:mm: //
      • <7 : hh:mm:ss //
      • >6 : with precision-6 t's added //
      // comparable for angle. The added colons are // to enable input // checking of the format. Look at the 'clean' types to bypass them. // // The MVTime::YMD format implies TIME, and will // precede the time with 'yyyy/mm/dd/' (or use // MVTime::YMD_ONLY to include NO_TIME // modifier).
      // The MVTime::DMY format implies TIME, and will // precede the time with 'dd-Mon-yyyy/'.
      // The MVTime::FITS format implies TIME, and will // precede the time with 'ccyy-mm-ddT'.
      // The MVTime::ISO format implies FITS followed by a Z // for the UTC time zone. It uses a space instead of T as separator. // It also implies CLEAN. // The BOOST format implies DMY and USE_SPACE (space instead // of slash between date and time). //
      // The output format can be modified with modifiers (specify as // MVTime::TIME | MVTime::MOD (or + MVTime::MOD)). // For overloading/casting // problems with some compilers, the // use of modifiers necessitates either the presence of a precision // (i.e. (A|B, prec)), or an explicit cast: // ((MVTime::formatTypes)(A|B)), or make use of // the provided TIME[_CLEAN][_NO_H[M]] and // ANGLE[_CLEAN][_NO_D[M]]. // // // The modifiers can be: //
        //
      • MVTime::CLEAN to suppress leading or trailing // periods (or colons for TIME). Note that he result can not be // read automatically. //
      • MVTime::NO_H (or NO_D) to suppress // the output of hours (or degrees): useful for offsets //
      • MVTime::NO_HM (or NO_DM), to // suppress the degrees and minutes. //
      • MVTime::DAY will precede the output with // 'Day-' (e.g. Wed-). Space delimiter is used for USE_SPACE. //
      • MVTime::NO_TIME will suppress printing of time. //
      // Output in formats like 20' can be done via the standard // Quantum output (e.g. stream << time.get("'") ). //
    • Available formats: //
        //
      • MVTime::ANGLE in +ddd.mm.ss.ttt format //
      • MVTime::TIME in hh:mm:ss.ttt format //
      • MVTime::[ANGLE|TIME]_CLEAN format without superfluous periods //
      • MVTime::[ANGLE|TIME][_CLEAN]_NO_[D|H][M] in format with // leading zero fields left empty. //
      • MVTime::CLEAN modifier for suppressing superfluous periods //
      • MVTime::USE_SPACE to use a space instead of a slash // as delimiter between date and time. //
      • MVTime::USE_Z to follow the time by a Z for the UTC time zone. //
      • MVTime::NO_[D|H][M] modifier to suppress first field(s) //
      • MVTime::DIG2 modifier to get +dd.mm.ss.ttt in angle or // time format(i.e. in range -90 - +90 or -12 - +12) //
      • MVTime::LOCAL modifier to produce local time (as derived from // aipsrc time.tzoffset). In FITS mode the time zone will // be appended (as hh:mm). // The adding of the timezone is not part // of the FITS standard, but of the underlying ISO standard. It can // be used to export local times in standard format. //
      //
    // The default formatting can be overwritten by a // MVTime::setFormat(); statement; which returns an // MVTime::Format // structure, that can be used in a subsequent one to reset to previous. // The format set holds for all MVTime output on all streams.
    // Temporary formats (i.e. for one MVTime output only), can be set by // outputting a format (i.e. stream << MVTime::Format() << ... ). // A setFormat() will also // reset any lingering temporary format. // A setFormat(getFormat()) will reset without changing. Problems could // arise in parallel processors. // Input can be read if the values are in any of the above (non-clean) output // formats.
    // For other formatting practice, the output can be written to a String with // the string() member functions.
    // Note that using a temporary format is inherently thread-unsafe because // the format is kept in a static variable. Another thread may overwrite // the format just set. The only thread-safe way to format an MVTime is using // a print or string that accepts a Format object. // // Strings and input can be converted to an MVTime (or Quantity) by // Bool read(Quantity &out, const String &in) and // istream >> MVTime &. In the latter case the actual // reading is done by the String read, which reads between white-spaces.
    // The following input formats (note no blanks allowed) are supported // (+stands for an optional + or -; v for an unsigned integer; dv for a // floating number. [] indicate optional values. Separating codes are // case insensitive), numbers(like yyyy) can be of any length. // The separator between date and time part can be a slash (as shown below), // a hyphen, or one or more spaces. //
      //
    • today -- (UT) time now //
    • today/[time] -- time on today (0:0:0 if omitted) //
    • yyyy/mm/dd[/time] -- date + time. An omitted date (leading /) // will be today + time; an omitted month will // indicate use of day number in year (1 == 1/1) //
    • dd[-]MMM[-]yyyy[/time] -- date +time If yyyy <100: around 2000. // MMM can be at least first three characters // of month name; or a month number (1 == Jan). // Omitted month indicates day is day number. //
    • ccyy-mm-dd[Ttime[Z|+-hh[:mm]]] -- new FITS format the 'T' as time // separator. Time should be UTC. // The 'Z' separator (for UTC) is part of an // earlier FITS proposal, and will be recognised // for backward compatibility. // A signed hh or hh:mm can be present to // indicate time zone. This value will be // subtracted to give UTC. To recognise this // format, the year should be greater than 1000. // The time-zone information // is not part of the FITS standard, but of the // underlying ISO standard. //
    // The time can be expressed as described in // MVAngle // Examples of valid strings: // // ToDay note case independence // 1996/11/20 20 November 1996 0h UT // 1996/11/20/5:20 20 November 1996 at 5h20m // 20Nov96-5h20m same (again no case dependence) // 1996-11-20T5:20 same (FITS format, case dependent) // //
    // // // See synopsis // // // // To be able to format date/time-like values in user-required ways. // // // //
  • Nothing I know of // class MVTime { public: //# Enumerations // Format types enum formatTypes { ANGLE, TIME, CLEAN = 4, NO_D = 8, NO_DM = NO_D+16, YMD = TIME+32, DMY = TIME+64, DAY = 128, NO_TIME = 256, MJD = TIME+512, DIG2 = 1024, FITS = TIME+2048, LOCAL = 4096, USE_SPACE = 8192, ALPHA = 16384, USE_Z = 32768, ISO = FITS + USE_Z + USE_SPACE + CLEAN, BOOST = DMY + USE_SPACE, NO_H = NO_D, NO_HM = NO_DM, ANGLE_CLEAN = ANGLE + CLEAN, ANGLE_NO_D = ANGLE + NO_D, ANGLE_NO_DM = ANGLE + NO_DM, ANGLE_CLEAN_NO_D = ANGLE + CLEAN + NO_D, ANGLE_CLEAN_NO_DM = ANGLE + CLEAN + NO_DM, TIME_CLEAN = TIME + CLEAN, TIME_NO_H = TIME + NO_H, TIME_NO_HM = TIME + NO_HM, TIME_CLEAN_NO_H = TIME + CLEAN + NO_H, TIME_CLEAN_NO_HM = TIME + CLEAN + NO_HM, YMD_ONLY = YMD + NO_TIME, MOD_MASK = CLEAN + NO_DM + DAY + NO_TIME + DIG2 + LOCAL + USE_SPACE + USE_Z + ALPHA }; //# Local structure // Format structure class Format { public: friend class MVTime; Format(MVTime::formatTypes intyp = MVTime::TIME, uInt inprec = 0) : typ(intyp), prec(inprec) {;}; Format(uInt inprec) : typ(MVTime::TIME), prec(inprec) {;}; // Construct from type and precision (present due to overlaoding problems) Format(uInt intyp, uInt inprec) : typ((MVTime::formatTypes)intyp), prec(inprec) {;}; private: MVTime::formatTypes typ; uInt prec; }; //# Friends // Output a date/time friend ostream &operator<<(ostream &os, const MVTime &meas); // Input a date/time friend istream &operator>>(istream &is, MVTime &meas); // Set a temporary format friend ostream &operator<<(ostream &os, const MVTime::Format &form); //# Constructors // Default constructor: generate a zero value MVTime(); // Copy constructor MVTime(const MVTime &other); // Copy assignment MVTime &operator=(const MVTime &other); // Constructor from Double (in MJD) MVTime(Double d); // Constructor from Quantum : value can be an angle or time // //
  • AipsError if not a time or angle // MVTime(const Quantity &other); // Constructor from Time MVTime(const Time &other); // Constructor from MVEpoch; MVTime(const MVEpoch &other); // Constructor from yy, mm, dd, dd (all dd with fractions allowed) MVTime(Int yy, Int mm, Double dd, Double d=0.0); //# Destructor ~MVTime(); //# Operators // Conversion operator operator Double() const; //# General member functions // Make res time Quantity from string. The String version will accept // a time/angle Quantity as well. It returns False in case of an error. // chk=True means that the entire string should be consumed. // throwExcp=True means that an exception is thrown in case of an error. // static Bool read(Quantity &res, const String &in, Bool chk=True); static Bool read(Quantity &res, MUString &in, Bool chk=True); static Bool read(Quantity &res, const String &in, Bool chk, Bool throwExcp); static Bool read(Quantity &res, MUString &in, Bool chk, Bool throwExcp); // // Get value of date/time (MJD) in given units // Double day() const; Double hour() const; Double minute() const; Double second() const; Quantity get() const; Quantity get(const Unit &inunit) const; Time getTime() const; // // Get indicated part of the time/date // const String &dayName() const; static const String &dayName(uInt which); const String &monthName() const; static const String &monthName(uInt which); // Mon = 1; Sun = 7; uInt weekday() const; // Jan =1 uInt month() const; uInt monthday() const; Int year() const; Int ymd() const; uInt yearday() const; uInt yearweek() const; // // Output data. // // The first function below is thread-unsafe because it uses the result of // the setFormat function which changes a static class member. // The other functions are thread-safe because the format is directly given. // // String string() const; String string(MVTime::formatTypes intyp, uInt inprec = 0) const; String string(uInt intyp, uInt inprec) const; String string(uInt inprec) const; String string(const MVTime::Format &form) const; void print(ostream &oss, const MVTime::Format &form) const; // // Set default format // // It is thread-unsafe to print using the setFormat functions because they // change a static class member. The only thred-safe way to print a time is // to use the print function above. // // static Format setFormat(MVTime::formatTypes intyp, uInt inprec = 0); static Format setFormat(uInt intyp, uInt inprec); static Format setFormat(uInt inprec = 0); static Format setFormat(const Format &form); // // Get default format static Format getFormat(); // Get code belonging to string. 0 if not known static MVTime::formatTypes giveMe(const String &in); // Get time zone offset (in days) static Double timeZone(); private: //# Data // Value Double val; // Default format static MVTime::Format defaultFormat; // Temporary format // static MVTime::Format interimFormat; static Bool interimSet; // //# Member functions // Get the y,m,d values void ymd(Int &yyyy, Int &mm, Int &dd) const; }; // Global functions. // Output // ostream &operator<<(ostream &os, const MVTime &meas); ostream &operator>>(ostream &is, MVTime &meas); // Set a temporary format (thread-unsafe). ostream &operator<<(ostream &os, const MVTime::Format &form); // // is equal operator, uses operator Double which returns days inline Bool operator==(const MVTime &lh, const MVTime &rh) { return (lh.operator Double() == rh.operator Double());} } //# NAMESPACE CASACORE - END #endif