// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/TimePoint.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_TimePoint_h #define __PCL_TimePoint_h /// \file pcl/TimePoint.h #include #include #include /* * N.B.: Remove potentially conflicting names that may be defined by 3rd-party * packages used by some standard modules. */ #ifdef J2000 # undef J2000 #endif #ifdef J2100 # undef J2100 #endif #ifdef B1950 # undef B1950 #endif namespace pcl { // ---------------------------------------------------------------------------- /*! * \defgroup time_representation Time Representation and Utilities */ // ---------------------------------------------------------------------------- struct FileTime; /*! * \class TimePoint * \brief An instant in any timescale * * %TimePoint represents an instant, an infinitesimal point in time, in any * timescale. The internal representation of time consists of the separate * integer and fractional components of a Julian date. This guarantees a * numerical resolution better than one nanosecond, as well as fast time * relational and arithmetic operations. * * \ingroup time_representation * \sa ISO8601ConversionOptions, IsoString::ParseISO8601DateTime() */ class PCL_CLASS TimePoint { public: /*! * Default constructor. Yields an invalid %TimePoint object that cannot be * used until properly initialized. */ TimePoint() = default; /*! * Constructs a %TimePoint object for a given instant represented as a * Julian date. */ TimePoint( double jd ) : m_jdi( TruncInt( jd ) ) , m_jdf( Frac( jd ) ) { } /*! * Constructs a %TimePoint object from two separate Julian date components, * \a jd1 and \a jd2, where the resulting JD is jd1 + jd2. * * Specifying a JD in two parts greatly improves the accuracy of time * representation, by increasing the effective bit length used to store time * points. To maximize time resolution and calculation efficiency, * %TimePoint normalizes its internal representation as the separate integer * and fractional components of a JD. This guarantees a numerical resolution * better than one nanosecond. */ TimePoint( double jd1, double jd2 ) : m_jdi( TruncInt( jd1 ) + TruncInt( jd2 ) ) , m_jdf( Frac( jd1 ) + Frac( jd2 ) ) { Normalize(); } /*! * Constructs a %TimePoint object from separate date components. */ TimePoint( int year, int month, double days ) { CalendarTimeToJD( m_jdi, m_jdf, year, month, TruncInt( days ), Frac( days ) ); } /*! * Constructs a %TimePoint object from separate date components plus a day * fraction. */ TimePoint( int year, int month, int day, double dayFraction ) { CalendarTimeToJD( m_jdi, m_jdf, year, month, day, dayFraction ); } /*! * Constructs a %TimePoint object from separate date and time components. */ TimePoint( int year, int month, int day, int hour, int minute, double seconds ) { CalendarTimeToJD( m_jdi, m_jdf, year, month, day, (hour + (minute + seconds/60)/60)/24 ); } /*! * Constructs a %TimePoint object from an ISO 8601 extended date/time * representation specified as an 8-bit ISO/IEC-8859-1 string. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point represented by this object. In other * words, the newly constructed object will always transport a time point in * the UTC timescale. */ TimePoint( const IsoString& dateTime ) { int year, month, day; double dayf, tz; dateTime.ParseISO8601DateTime( year, month, day, dayf, tz ); CalendarTimeToJD( m_jdi, m_jdf, year, month, day, dayf - tz/24 ); } /*! * Constructs a %TimePoint object from an ISO 8601 extended date/time * representation specified as a UTF-16 string. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point represented by this object. In other * words, the newly constructed object will always transport a time point in * the UTC timescale. */ TimePoint( const String& dateTime ) { int year, month, day; double dayf, tz; dateTime.ParseISO8601DateTime( year, month, day, dayf, tz ); CalendarTimeToJD( m_jdi, m_jdf, year, month, day, dayf - tz/24 ); } /*! * Constructs a %TimePoint object from a time_t value. The specified \a time * value will be interpreted as UTC. */ TimePoint( time_t time ); /*! * Constructs a %TimePoint object from a FileTime object. * * \param fileTime Reference to a FileTime structure, from which date and * time elements will be obtained to construct a * %TimePoint object. The file time is expected to be * represented as UTC, which is coherent with most file * systems. */ TimePoint( const FileTime& fileTime ); /*! * Copy constructor. */ TimePoint( const TimePoint& ) = default; /*! * Copy assignment operator. Returns a reference to this object. */ TimePoint& operator =( const TimePoint& ) = default; /*! * Returns true iff this is a valid %TimePoint instance. An invalid * %TimePoint does not represent a valid time point, generates empy string * representations, and cannot be used until properly initialized. */ constexpr bool IsValid() const { return ((m_jdi > 0) ? m_jdi : -m_jdi) < 2147438065; } /*! * Extracts the individual date components. * * \param[out] year Reference to a variable that will receive the year * component of this time point. * * \param[out] month Reference to a variable that will receive the month * component of this time point, in the range [1,12]. * * \param[out] day Reference to a variable that will receive the day * component of this time point, in the range [1,31]. */ void GetCalendarTime( int& year, int& month, int& day ) const { double dum; JDToCalendarTime( year, month, day, dum, m_jdi, m_jdf ); } /*! * Extracts the individual date and day fraction components. * * \param[out] year Reference to a variable that will receive the year * component of this time point. * * \param[out] month Reference to a variable that will receive the month * component of this time point, in the range [1,12]. * * \param[out] day Reference to a variable that will receive the day * component of this time point, in the range [1,31]. * * \param[out] dayf Reference to a variable that will receive the day * fraction component of this time point, in the range * [0,1). */ void GetCalendarTime( int& year, int& month, int& day, double& dayf ) const { JDToCalendarTime( year, month, day, dayf, m_jdi, m_jdf ); } /*! * Extracts the individual date and time components. * * \param[out] year Reference to a variable that will receive the year * component of this time point. * * \param[out] month Reference to a variable that will receive the month * component of this time point, in the range [1,12]. * * \param[out] day Reference to a variable that will receive the day * component of this time point, in the range [1,31]. * * \param[out] hour Reference to a variable that will receive the hour * component of this time point, in the range [0,23]. * * \param[out] minute Reference to a variable that will receive the minute * component of this time point, in the range [0,59]. * * \param[out] seconds Reference to a variable that will receive the * seconds component of this time point, in the range * [0,60). */ void GetCalendarTime( int& year, int& month, int& day, int& hour, int& minute, double& seconds ) const { double dayf; JDToCalendarTime( year, month, day, dayf, m_jdi, m_jdf ); double h = Frac( dayf )*24; double m = Frac( h )*60; seconds = Frac( m )*60; minute = TruncInt( m ); hour = TruncInt( h ); } /*! * Returns the year component of this time point. */ int Year() const { int year, foo; double bar; JDToCalendarTime( year, foo, foo, bar, m_jdi, m_jdf ); return year; } /*! * Returns the month component of this time point in the range [1,12]. */ int Month() const { int foo, month; double bar; JDToCalendarTime( foo, month, foo, bar, m_jdi, m_jdf ); return month; } /*! * Returns the day component of this time point in the range [1,31]. */ int Day() const { int foo, day; double bar; JDToCalendarTime( foo, foo, day, bar, m_jdi, m_jdf ); return day; } /*! * Returns the day fraction component of this time point in the range [0,1). */ double DayFraction() const { int foobar; double dayf; JDToCalendarTime( foobar, foobar, foobar, dayf, m_jdi, m_jdf ); return dayf; } /*! * Returns an ISO 8601 extended date/time representation of this time point * as a UTF-16 string. * * \param options Optional settings to control the representation of date * and time in ISO 8601 extended format. * * \param tz Time zone offset in hours. The default value is zero. * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. * * \sa ISO8601ConversionOptions, String::ParseISO8601DateTime(), IsValid() */ String ToString( const ISO8601ConversionOptions& options = ISO8601ConversionOptions(), double tz = 0 ) const { return ToString( options, tz, (String*)0 ); } /*! * Returns an ISO 8601 extended date/time representation of this time point * as a UTF-16 string. * * \param timeItems Number of represented time items. Can be 0, 1, 2 or 3. * All items but the last one are represented as integer * values. The last item is represented as a floating * point value with the specified \a precision. * * \param precision Number of decimal digits for the last represented time * item. The default value is three decimal digits. * * \param tz Time zone offset in hours. The default value is zero. * * \param timeZone Whether to append a time zone specifier to the ISO 8601 * representation. The default value is true. * * \param zuluTime Whether to append the 'Z' special time zone specifier * for UTC time without offset, or the '+00:00' specifier * otherwise. The default value is true. * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. * * \sa ISO8601ConversionOptions, String::ParseISO8601DateTime(), IsValid() */ String ToString( unsigned timeItems, unsigned precision = 3, double tz = 0, bool timeZone = true, bool zuluTime = true ) const { return ToString( ISO8601ConversionOptions( timeItems, precision, timeZone, zuluTime ), tz ); } /*! * Returns an ISO 8601 extended date/time representation of this time point * as an 8-bit ISO/IEC-8859-1 string. * * \param options Optional settings to control the representation of date * and time in ISO 8601 extended format. * * \param tz Time zone offset in hours. The default value is zero. * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. * * \sa ISO8601ConversionOptions, IsoString::ParseISO8601DateTime(), IsValid() */ IsoString ToIsoString( const ISO8601ConversionOptions& options = ISO8601ConversionOptions(), double tz = 0 ) const { return ToString( options, tz, (IsoString*)0 ); } /*! * Returns an ISO 8601 extended date/time representation of this time point * as an 8-bit ISO/IEC-8859-1 string. * * \param timeItems Number of represented time items. Can be 0, 1, 2 or 3. * All items but the last one are represented as integer * values. The last item is represented as a floating * point value with the specified \a precision. * * \param precision Number of decimal digits for the last represented time * item. The default value is three decimal digits. * * \param tz Time zone offset in hours. The default value is zero. * * \param timeZone Whether to append a time zone specifier to the ISO 8601 * representation. The default value is true. * * \param zuluTime Whether to append the 'Z' special time zone specifier * for UTC time without offset, or the '+00:00' specifier * otherwise. The default value is true. * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. * * \sa ISO8601ConversionOptions, IsoString::ParseISO8601DateTime(), IsValid() */ IsoString ToIsoString( unsigned timeItems, unsigned precision = 3, double tz = 0, bool timeZone = true, bool zuluTime = true ) const { return ToIsoString( ISO8601ConversionOptions( timeItems, precision, timeZone, zuluTime ), tz ); } /*! * Returns a custom representation of this time point as a UTF-16 string. * * \param format A date and time format string. The following format * tokens will be replaced with formatted date and time * items, as described in the following table:\n * \n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
\%YThe four-digit year.
\%MZero padded, two-digit month number, '01' through '12'.
\%nThe month number, '1' through '12'.
\%NThe English month name, 'January' through 'December'.
\%DZero padded, two-digit day of month, '01' through '31'.
\%dThe day of the month, '1' through '31'.
\%hZero padded, two digits of hour, '00' through '23'.
\%mZero padded, two digits of minute, '00' through '59'.
\%sZero padded, two digits of the seconds truncated to an integer, * '00' through '59'.
\%s<p>Zero padded representation of seconds rounded or truncated to * <p> decimal digits, with <p> in [0,9]. Truncation * instead of rounding will we used if the rounded value is equal to * 60 seconds.
\n * Other characters in the format string will be included literally in * the result. To include a percent sign '\%', escape it by preceding it * with a backslash: "\\%". To include a backslash character, it must * also be escaped as two consecutive slashes: "\\\\". * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. * * Example: * * \code * TimePoint t = TimePoint::Now(); * std::cout << t.ToString( "%Y-%M-%D %h:%m:%s" ) << '\n' * << t.ToString( "%Y-%M-%D %h:%m:%s2" ) << '\n' * << t.ToString( "Today is: %N %d, %Y %h:%m:%s" ) << '\n'; * \endcode */ String ToString( const String& format ) const; /*! * Returns a custom representation of this time point as an 8-bit * ISO/IEC-8859-1 string. * * See ToString( const String& ) for detailed information on the format * string argument. * * If this is an invalid %TimePoint (for example, a default constructed * instance), this function returns an empty string. */ IsoString ToIsoString( const IsoString& format ) const; IsoString ToIsoString( const char* format ) const { return ToIsoString( IsoString( format ) ); } /*! * String conversion operator. Equivalent to ToString(). */ explicit operator String() const { return ToString(); } /*! * IsoString conversion operator. Equivalent to ToIsoString(). */ explicit operator IsoString() const { return ToIsoString(); } /*! * Returns the integer part of the Julian date (also referred to as * Julian day number) corresponding to this time point. */ constexpr int JDI() const { return m_jdi; } /*! * Returns the fractional part of the Julian date corresponding to this time * point. */ constexpr double JDF() const { return m_jdf; } /*! * Returns the Julian date corresponding to this time point. * * The time point representation returned by this member function only has * millisecond resolution. For higher resolution time point representations * up to one nanosecond, use the separate integer and fractional components * given by JDI() and JDF(). * * If this is an invalid %TimePoint (for example, a default constructed * instance), the value returned by this function is meaningless as a Julian * date. */ constexpr double JD() const { return m_jdi + m_jdf; } /*! * Returns the modified Julian date (MJD) corresponding to this time point. * * This function returns JD() - 2400000.5. Refer to the JD() member function * for more information. */ constexpr double MJD() const { return (m_jdi-2400000) + (m_jdf-0.5); } /*! * Returns the value of Delta T, or the difference TT-UT1, corresponding to * this time point. * * If possible, this member function returns an interpolated value from the * global Delta T database, which will be loaded and parsed upon the first * call to this function as a thread-safe procedure. See * EphemerisFile::DeltaTDataFilePath() and * EphemerisFile::OverrideDeltaTDataFilePath() for more information. * * Otherwise, if this time point falls outside the Delta T database time * span, this function will use the polynomial expressions for Delta T * included in Five Millennium Canon of Solar Eclipses, by Fred * Espenak and Jean Meeus (NASA/TP–2006–214141, Revision 1.0, 2007). * * The returned value is the difference TT-UT1 in seconds. */ double DeltaT() const; /*! * Returns the value of Delta AT, or the difference TAI-UTC, corresponding * to this time point, which is assumed to represent an instant in the UTC * timescale. * * If possible, this member function returns an interpolated value from the * global Delta AT database, which will be loaded and parsed upon the first * call to this function as a thread-safe procedure. See * EphemerisFile::DeltaATDataFilePath() and * EphemerisFile::OverrideDeltaATDataFilePath() for more information. * * UTC does not exist before 1960, so calling this function for a TimePoint * before that year is a conceptual error. For convenience, zero is returned * in such case instead of throwing an exception. * * The returned value is the difference TAI-UTC in seconds. */ double DeltaAT() const; /*! * Adds the specified number of \a days to this time point. Returns a * reference to this object. */ TimePoint& operator +=( double days ) { m_jdf += days; Normalize(); return *this; } /*! * Subtracts the specified number of \a days from this time point. Returns a * reference to this object. */ TimePoint& operator -=( double days ) { m_jdf -= days; Normalize(); return *this; } /*! * Returns the time interval in days elapsed since the specified time point * \a t. */ constexpr double DaysSince( const TimePoint& t ) const { return m_jdi-t.m_jdi + m_jdf-t.m_jdf; } /*! * Returns the time interval in Julian years (365.25 days) elapsed since the * specified time point \a t. */ constexpr double YearsSince( const TimePoint& t ) const { return DaysSince( t )/365.25; } /*! * Returns the time interval in Julian centuries (36525 days) elapsed since * the specified time point \a t. */ constexpr double CenturiesSince( const TimePoint& t ) const { return DaysSince( t )/36525; } /*! * Returns the time interval in seconds elapsed since the specified time * point \a t. */ constexpr double SecondsSince( const TimePoint& t ) const { return DaysSince( t )*86400; } /*! * Returns the time interval in days elapsed since the standard J2000 epoch * (JD 2451545.0 = 2000 January 1.5). */ constexpr double DaysSinceJ2000() const { return m_jdi-2451545 + m_jdf; } /*! * Returns the time interval in Julian years (365.25 days) elapsed since the * standard J2000 epoch (JD 2451545.0 = 2000 January 1.5). */ constexpr double YearsSinceJ2000() const { return DaysSinceJ2000()/365.25; } /*! * Returns the time interval in Julian centuries (36525 days) elapsed since * the standard J2000 epoch (JD 2451545.0 = 2000 January 1.5). */ constexpr double CenturiesSinceJ2000() const { return DaysSinceJ2000()/36525; } /*! * Returns the time interval in seconds elapsed since the standard J2000 * epoch (JD 2451545.0 = 2000 January 1.5). */ constexpr double SecondsSinceJ2000() const { return DaysSinceJ2000()*86400; } /*! * Returns the time interval in days elapsed since the standard UNIX epoch * (JD 2440587.5 = 1970 January 1.0). */ constexpr double DaysSinceUNIXEpoch() const { return m_jdi-2440587 + m_jdf-0.5; } /*! * Returns the time interval in Julian years (365.25 days) elapsed since the * standard UNIX epoch (JD 2440587.5 = 1970 January 1.0). */ constexpr double YearsSinceUNIXEpoch() const { return DaysSinceUNIXEpoch()/365.25; } /*! * Returns the time interval in Julian centuries (36525 days) elapsed since * the standard UNIX epoch (JD 2440587.5 = 1970 January 1.0). */ constexpr double CenturiesSinceUNIXEpoch() const { return DaysSinceUNIXEpoch()/36525; } /*! * Returns the time interval in seconds elapsed since the standard UNIX * epoch (JD 2440587.5 = 1970 January 1.0). */ constexpr double SecondsSinceUNIXEpoch() const { return DaysSinceUNIXEpoch()*86400; } /*! * Returns the time interval in milliseconds elapsed since the standard UNIX * epoch (JD 2440587.5 = 1970 January 1.0). */ constexpr double MillisecondsSinceUNIXEpoch() const { return DaysSinceUNIXEpoch()*86400000; } /*! * Returns the UTC offset for this time point on the host machine, or the * difference Local Standard Time (LST) minus Universal Coordinated Time * (UTC), in hours, at the date represented by this object. This * function takes into account daylight saving time when applicable. */ double SystemOffsetFromUTC() const; /*! * Returns this time point represented as Local Standard Time (LST), * assuming that this object represents a time point in the UTC timescale. */ TimePoint UTCToLocalTime() const { return TimePoint( m_jdi, m_jdf + SystemOffsetFromUTC()/24 ); } /*! * Returns this time point represented as UTC, assuming that this object * represents a time point in Local Standard Time (LST). */ TimePoint LocalTimeToUTC() const { return TimePoint( m_jdi, m_jdf - SystemOffsetFromUTC()/24 ); } /*! * Returns a %TimePoint object corresponding to the current date and time in * the UTC timescale. */ static TimePoint Now(); /*! * Returns a %TimePoint object corresponding to the standard J2000 epoch, * namely JD 2451545.0, corresponding to the midday of 2000 January 1. */ static TimePoint J2000() { TimePoint t; t.m_jdi = 2451545; t.m_jdf = 0; return t; } /*! * Returns a %TimePoint object corresponding to the standard J2100 epoch, * namely JD 2488070.0, corresponding to the midday of 2100 January 1. */ static TimePoint J2100() { TimePoint t; t.m_jdi = 2488070; t.m_jdf = 0; return t; } /*! * Returns a %TimePoint object corresponding to the B1950.0 epoch, namely * JD 2433282.42345905, corresponding to 1949 December 31.92345905. */ static TimePoint B1950() { TimePoint t; t.m_jdi = 2433282; t.m_jdf = 0.42345905; return t; } /*! * Returns a %TimePoint object corresponding to the standard UNIX epoch, * namely JD 2440587.5, corresponding to 1970 January 1.0. */ static TimePoint UNIXEpoch() { TimePoint t; t.m_jdi = 2440587; t.m_jdf = 0.5; return t; } /*! * Returns a %TimePoint object constructed from an ISO 8601 extended * date/time representation specified as an 8-bit ISO/IEC-8859-1 string. If * successful, stores the evaluated time zone offset, in hours, in the * specified variable \a tz. Otherwise this function throws the appropriate * Error exception. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point constructed by this function. In other * words, the newly constructed object will always transport a time point in * the UTC timescale without offset. * * \sa TryFromString( TimePoint&, double&, const IsoString& ), * IsoString::ParseISO8601DateTime() */ static TimePoint FromString( double& tz, const IsoString& dateTime ) { int year, month, day; double dayf; dateTime.ParseISO8601DateTime( year, month, day, dayf, tz ); return TimePoint( year, month, day, dayf - tz/24 ); } /*! * Returns a %TimePoint object constructed from an ISO 8601 extended * date/time representation specified as a UTF-16 string. If successful, * stores the evaluated time zone offset, in hours, in the specified * variable \a tz. Otherwise this function throws the appropriate Error * exception. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point constructed by this function. In other * words, the newly constructed object will always transport a time point in * the UTC timescale without offset. * * \sa TryFromString( TimePoint&, double&, const String& ), * String::ParseISO8601DateTime() */ static TimePoint FromString( double& tz, const String& dateTime ) { int year, month, day; double dayf; dateTime.ParseISO8601DateTime( year, month, day, dayf, tz ); return TimePoint( year, month, day, dayf - tz/24 ); } /*! * Returns a %TimePoint object constructed from an ISO 8601 extended * date/time representation specified as an 8-bit ISO/IEC-8859-1 string. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point constructed by this function. In other * words, the newly constructed object will always transport a time point in * the UTC timescale without offset. * * \sa TryFromString( TimePoint&, const IsoString& ), * IsoString::ParseISO8601DateTime() */ static TimePoint FromString( const IsoString& dateTime ) { return TimePoint( dateTime ); } /*! * Returns a %TimePoint object constructed from an ISO 8601 extended * date/time representation specified as a UTF-16 string. * * If the source representation specifies a nonzero time zone, it will be * subtracted from the time point constructed by this function. In other * words, the newly constructed object will always transport a time point in * the UTC timescale without offset. * * \sa TryFromString( TimePoint&, const String& ), * String::ParseISO8601DateTime() */ static TimePoint FromString( const String& dateTime ) { return TimePoint( dateTime ); } /*! * Attempts to evaluate the specified 8-bit string as a date and time * specification in ISO 8601 extended format. If successful, stores the * evaluated UTC time point in the specified variable \a t, and the * evaluated time zone offset, in hours, in the variable \a tz, then returns * \c true. * * If the specified string cannot be evaluated as a valid date and time in * ISO 8601 extended format, this function returns \c false and does not * change the passed variables \a t and \a tz. This function does not throw * any parsing exceptions. * * If the source string contains a time zone offset, it is subtracted from * the evaluated time point. In other words, the %TimePoint value stored in * \a t is always represented in the UTC timescale without any offset. * * \sa FromString( const IsoString& ), IsoString::TryParseISO8601DateTime() */ static bool TryFromString( TimePoint& t, double& tz, const IsoString& dateTime ) { int year, month, day; double dayf; if ( dateTime.TryParseISO8601DateTime( year, month, day, dayf, tz ) ) { t = TimePoint( year, month, day, dayf - tz/24 ); return true; } return false; } /*! * Attempts to evaluate the specified UTF-16 string as a date and time * specification in ISO 8601 extended format. If successful, stores the * evaluated UTC time point in the specified variable \a t, and the * evaluated time zone offset, in hours, in the variable \a tz, then returns * \c true. * * If the specified string cannot be evaluated as a valid date and time in * ISO 8601 extended format, this function returns \c false and does not * change the passed variables \a t and \a tz. This function does not throw * any parsing exceptions. * * If the source string contains a time zone offset, it is subtracted from * the evaluated time point. In other words, the %TimePoint value stored in * \a t is always represented in the UTC timescale without any offset. * * \sa FromString( const String& ), String::TryParseISO8601DateTime() */ static bool TryFromString( TimePoint& t, double& tz, const String& dateTime ) { int year, month, day; double dayf; if ( dateTime.TryParseISO8601DateTime( year, month, day, dayf, tz ) ) { t = TimePoint( year, month, day, dayf - tz/24 ); return true; } return false; } /*! * Attempts to evaluate the specified 8-bit string as a date and time * specification in ISO 8601 extended format. If successful, stores the * evaluated UTC time point in the specified variable \a t, then returns * \c true. * * If the specified string cannot be evaluated as a valid date and time in * ISO 8601 extended format, this function returns \c false and does not * change the passed variable \a t. This function does not throw any parsing * exceptions. * * If the source string contains a time zone offset, it is subtracted from * the evaluated time point. In other words, the %TimePoint value stored in * \a t is always represented in the UTC timescale without any offset. * * \sa FromString( const IsoString& ), IsoString::TryParseISO8601DateTime() */ static bool TryFromString( TimePoint& t, const IsoString& dateTime ) { double tz; return TryFromString( t, tz, dateTime ); } /*! * Attempts to evaluate the specified UTF-16 string as a date and time * specification in ISO 8601 extended format. If successful, stores the * evaluated UTC time point in the specified variable \a t, then returns * \c true. * * If the specified string cannot be evaluated as a valid date and time in * ISO 8601 extended format, this function returns \c false and does not * change the passed variable \a t. This function does not throw any parsing * exceptions. * * If the source string contains a time zone offset, it is subtracted from * the evaluated time point. In other words, the %TimePoint value stored in * \a t is always represented in the UTC timescale without any offset. * * \sa FromString( const String& ), String::TryParseISO8601DateTime() */ static bool TryFromString( TimePoint& t, const String& dateTime ) { double tz; return TryFromString( t, tz, dateTime ); } private: int32 m_jdi = int32_max; // invalid by default double m_jdf = 0.0; /*! * \internal * Ensures that the internal Julian date separate representation is optimal * in terms of time resolution by constraining JDF to [0,1). */ void Normalize() { if ( Abs( m_jdf ) >= 1 ) { m_jdi += TruncInt( m_jdf ); m_jdf = Frac( m_jdf ); } } template S ToString( const ISO8601ConversionOptions& options, double tz, S* ) const { if ( IsValid() ) { int year, month, day; double dayf; JDToCalendarTime( year, month, day, dayf, m_jdi, m_jdf ); return S::ToISO8601DateTime( year, month, day, dayf, tz, options ); } return S(); } }; /* * ### N.B.: TimePoint cannot have virtual member functions. * This is because sizeof( TimePoint ) _must_ be equal to * sizeof( uint32 ) + sizeof( uint64 ). */ struct PCL_AssertTimePointSize { struct TestData { uint32 x; uint64 y; }; static_assert( sizeof( TimePoint ) == sizeof( TestData ), "Invalid sizeof( TimePoint )" ); }; /*! * Returns true iff two %TimePoint objects, \a t1 and \a t2, represent the same * time point. * \ingroup time_representation */ inline constexpr bool operator ==( const TimePoint& t1, const TimePoint& t2 ) { return t1.JDI() == t2.JDI() && t1.JDF() == t2.JDF(); } /*! * Returns true iff a %TimePoint object \a t1 represents the specified time * point \a jd2, expressed as a Julian date. * \ingroup time_representation */ inline constexpr bool operator ==( const TimePoint& t1, double jd2 ) { return t1.JD() == jd2; } /*! * Returns true iff a %TimePoint object \a t2 represents the specified time * point \a jd1, expressed as a Julian date. This operator implements the * commutative property of scalar time point equality. * \ingroup time_representation */ inline constexpr bool operator ==( double jd1, const TimePoint& t2 ) { return t2.JD() == jd1; } /*! * Returns true iff a %TimePoint object \a t1 represents a time point that * precedes the time point represented by another object \a t2. * * Invalid %TimePoint instances are always in the infinite past: if * \a t1 is invalid, this function returns true; if \a t1 is valid and \a t2 is * not valid, this function returns false. * * \ingroup time_representation */ inline constexpr bool operator <( const TimePoint& t1, const TimePoint& t2 ) { return !t1.IsValid() || t2.IsValid() && ((t1.JDI() != t2.JDI()) ? t1.JDI() < t2.JDI() : t1.JDF() < t2.JDF()); } /*! * Returns true iff a %TimePoint object \a t1 represents a time point that * precedes another time point \a jd2, expressed as a Julian date. * * Invalid %TimePoint instances are always in the infinite past: if * \a t1 is invalid, this function returns true. * * \ingroup time_representation */ inline constexpr bool operator <( const TimePoint& t1, double jd2 ) { return !t1.IsValid() || t1.JD() < jd2; } /*! * Returns true iff a time point \a jd1, expressed as a Julian date, precedes * the time point represented by a %TimePoint object \a t2. * * Invalid %TimePoint instances are always in the infinite past: if * \a t2 is invalid, this function returns false. * * \ingroup time_representation */ inline constexpr bool operator <( double jd1, const TimePoint& t2 ) { return t2.IsValid() && t2.JD() < jd1; } /*! * Returns the time interval in days elapsed from the specified time point * \a t1 to another time point \a t2. The returned value is positive if \a t2 * precedes \a t1, negative if \a t1 precedes \a t2. * \ingroup time_representation */ inline constexpr double operator -( const TimePoint& t1, const TimePoint& t2 ) { return (t1.JDI() - t2.JDI()) + (t1.JDF() - t2.JDF()); } /*! * Returns the time point resulting after \a d days transcurred since a time * point \a t. * \ingroup time_representation */ inline TimePoint operator +( const TimePoint& t, double d ) { return TimePoint( t.JDI(), t.JDF()+d ); } /*! * Returns the time point resulting after \a d days transcurred since a time * point \a t. This operator implements the commutative property of scalar time * point addition. * \ingroup time_representation */ inline TimePoint operator +( double d, const TimePoint& t ) { return t + d; } /*! * Returns the time point \a d days before a time point \a t. Note that scalar * time point subtraction is not a commutative operation, so 'd-t' cannot be * used. * \ingroup time_representation */ inline TimePoint operator -( const TimePoint& t, double d ) { return TimePoint( t.JDI(), t.JDF()-d ); } // ---------------------------------------------------------------------------- } // pcl #endif // __PCL_TimePoint_h // ---------------------------------------------------------------------------- // EOF pcl/TimePoint.h - Released 2022-03-12T18:59:29Z