1211 lines
41 KiB
C++
1211 lines
41 KiB
C++
// ____ ______ __
|
||
// / __ \ / ____// /
|
||
// / /_/ // / / /
|
||
// / ____// /___ / /___ 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<p></td>
|
||
* <td>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.</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/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 <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
|