Files
tenmon/3rdparty/include/pcl/TimePoint.h
T
2022-04-12 08:17:18 +02:00

1211 lines
41 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ____ ______ __
// / __ \ / ____// /
// / /_/ // / / /
// / ____// /___ / /___ 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 <pcl/Defs.h>
#include <pcl/Math.h>
#include <pcl/String.h>
/*
* 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
* <table border="1" cellpadding="4" cellspacing="0">
* <tr>
* <td>\%Y</td>
* <td>The four-digit year.</td>
* </tr>
* <tr>
* <td>\%M</td>
* <td>Zero padded, two-digit month number, '01' through '12'.</td>
* </tr>
* <tr>
* <td>\%n</td>
* <td>The month number, '1' through '12'.</td>
* </tr>
* <tr>
* <td>\%N</td>
* <td>The English month name, 'January' through 'December'.</td>
* </tr>
* <tr>
* <td>\%D</td>
* <td>Zero padded, two-digit day of month, '01' through '31'.</td>
* </tr>
* <tr>
* <td>\%d</td>
* <td>The day of the month, '1' through '31'.</td>
* </tr>
* <tr>
* <td>\%h</td>
* <td>Zero padded, two digits of hour, '00' through '23'.</td>
* </tr>
* <tr>
* <td>\%m</td>
* <td>Zero padded, two digits of minute, '00' through '59'.</td>
* </tr>
* <tr>
* <td>\%s</td>
* <td>Zero padded, two digits of the seconds truncated to an integer,
* '00' through '59'.</td>
* </tr>
* <tr>
* <td>\%s&lt;p&gt;</td>
* <td>Zero padded representation of seconds rounded or truncated to
* &lt;p&gt; decimal digits, with &lt;p&gt; in [0,9]. Truncation
* instead of rounding will we used if the rounded value is equal to
* 60 seconds.</td>
* </tr>
* </table>\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
* <em>Julian day number</em>) 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 <em>Five Millennium Canon of Solar Eclipses</em>, by Fred
* Espenak and Jean Meeus (NASA/TP2006214141, 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 <em>Local Standard Time (LST) minus Universal Coordinated Time
* (UTC)</em>, 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 <class S>
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 <em>infinite past:</em> 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 <em>infinite past:</em> 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 <em>infinite past:</em> 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