时间模块
2025/12/19大约 2 分钟
时间模块
说明:本文档旨在帮助理解模块功能,具体API和行为请查阅源代码。
模块概述
Time模块提供了全面的时间处理功能,包括日期、时间、日期时间、儒略日、简约儒略日、时长以及时间系统转换等功能。该模块是天体力学和航天动力学计算的基础组件,支持各种时间表示形式之间的转换和操作。
核心概念
时间表示类型
模块定义了以下主要时间表示类型:
Date (日期)
- 表示年、月、日信息
- 支持闰年判断、月份天数计算、年中日计算等功能
Time (时间)
- 表示时、分、秒信息
- 支持时间规范化、总秒数计算等功能
DateTime (日期时间)
- 组合日期和时间信息
- 支持本地时间与UTC时间转换、日期时间规范化等功能
JulianDate (儒略日)
- 用于天文学的时间表示方法
- 支持日期时间与儒略日之间的转换
ModJulianDate (简约儒略日)
- 儒略日的简化形式
- 基于JulianDate类,提供更简洁的表示方式
时长类型
- ShortDuration: 短时长,使用double表示秒数
- LongDuration: 长时长,使用整数秒和小数秒分离表示
- DaySecDuration: 整数天 + 小数秒时长,适合长时间跨度表示
时间系统
模块支持以下时间系统之间的转换:
- TAI (原子时): 国际原子时
- TT (地球时): 地球动力学时,用于天体力学计算
- GPS (GPS时): 全球定位系统时间
- UTC (协调世界时): 世界协调时间
用法示例
1. 日期时间创建与规范化
#include <AstCore/DateTime.hpp>
#include <iostream>
int main() {
AST_USING_NAMESPACE
// 创建日期时间对象
DateTime dttm;
dttm.year() = 2023;
dttm.month() = 12;
dttm.day() = 31;
dttm.hour() = 23;
dttm.minute() = 59;
dttm.second() = 60.5; // 包含小数秒
// 规范化日期时间
std::cout << "规范化前:" << dttm.year() << "-" << dttm.month() << "-" << dttm.day()
<< " " << dttm.hour() << ":" << dttm.minute() << ":" << dttm.second() << std::endl;
aDateTimeNormalizeUTC(dttm);
std::cout << "规范化后:" << dttm.year() << "-" << dttm.month() << "-" << dttm.day()
<< " " << dttm.hour() << ":" << dttm.minute() << ":" << dttm.second() << std::endl;
}2. 儒略日转换
#include <AstCore/JulianDate.hpp>
#include <AstCore/DateTime.hpp>
#include <iostream>
int main() {
AST_USING_NAMESPACE
// 创建日期时间对象
DateTime dttm;
dttm.year() = 2023;
dttm.month() = 1;
dttm.day() = 1;
dttm.hour() = 0;
dttm.minute() = 0;
dttm.second() = 0;
std::cout << "原始日期时间:" << dttm.year() << "-" << dttm.month() << "-" << dttm.day()
<< " " << dttm.hour() << ":" << dttm.minute() << ":" << dttm.second() << std::endl;
// 转换为儒略日
JulianDate jd;
aDateTimeToJD(dttm, jd);
std::cout << "儒略日:" << jd.impreciseDay() << std::endl;
// 转换回日期时间
DateTime dttm2;
aJDToDateTime(jd, dttm2);
std::cout << "转换回日期时间:" << dttm2.year() << "-" << dttm2.month() << "-" << dttm2.day()
<< " " << dttm2.hour() << ":" << dttm2.minute() << ":" << dttm2.second() << std::endl;
}3. 时间系统转换
#include <AstCore/TimeSystem.hpp>
#include <AstCore/DateTime.hpp>
#include <AstCore/JulianDate.hpp>
#include <iostream>
int main() {
AST_USING_NAMESPACE
// 创建日期时间对象
DateTime dttm;
dttm.year() = 2023;
dttm.month() = 1;
dttm.day() = 1;
dttm.hour() = 0;
dttm.minute() = 0;
dttm.second() = 0;
std::cout << "UTC 日期时间:" << dttm.year() << "-" << dttm.month() << "-" << dttm.day()
<< " " << dttm.hour() << ":" << dttm.minute() << ":" << dttm.second() << std::endl;
// 转换为儒略日
JulianDate utc_jd;
aDateTimeToJD(dttm, utc_jd);
std::cout << "UTC 儒略日:" << utc_jd.impreciseDay() << std::endl;
// 转换为TAI时间
JulianDate tai_jd;
aUTCToTAI(utc_jd, tai_jd);
std::cout << "TAI 儒略日:" << tai_jd.impreciseDay() << std::endl;
// 转换为TT时间
JulianDate tt_jd;
aUTCToTT(utc_jd, tt_jd);
std::cout << "TT 儒略日:" << tt_jd.impreciseDay() << std::endl;
}依赖关系
AstGlobal.h: 项目全局定义AstUtil/StringView.hpp: 字符串处理支持AstCore/Constants.h: 常数定义
注意事项
- 所有时间参数默认使用秒(s)
- 角度参数默认使用弧度(rad)
- 部分转换函数考虑了闰秒,部分则不考虑,请查看函数文档
- 使用单个double表示的时间精度有限,长时间跨度建议使用DaySecDuration或LongDuration
- 日期时间规范化函数有多个版本(本地时间、UTC时间、北京时间),请根据需要选择
- 儒略日和简约儒略日之间的转换有精确和不精确两种版本
API参考
///
/// @file Date.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
#include <string>
AST_NAMESPACE_BEGIN
/*!
@ingroup Core
@defgroup Time 时间转换
@brief 提供儒略日、日期时间等时间表示,以及不同时间系统之间的转换功能
@{
*/
/*!
@addtogroup Time 时间模块
@{
*/
class Date;
/// @brief 获取月份的完整英文名称
/// @param month 月份,从1开始计数(1表示一月)
AST_CORE_CAPI const char* aMoonFullName(int month);
/// @brief 获取月份的简写英文名称
/// @param month 月份,从1开始计数(1表示一月)
AST_CORE_CAPI const char* aMoonShortName(int month);
/// @brief 获取星期几的完整英文名称
/// @param wday 星期几,从0开始计数(0表示星期日)
AST_CORE_CAPI const char* aWeekDayFullName(int wday);
/// @brief 获取星期几的简写英文名称
/// @param wday 星期几,从0开始计数(0表示星期日)
AST_CORE_CAPI const char* aWeekDayShortName(int wday);
/// @brief 判断是否为闰年
AST_CORE_CAPI bool aIsLeapYear(int year);
/// @brief 获取某年某月的天数,根据年份判断
/// @param month 月份,从1开始计数(1表示一月)
/// @param year 年份
AST_CORE_CAPI int aDaysInMonthByYear(int month, int year);
/// @brief 获取某年某月的天数,根据是否为闰年判断
/// @param month 月份,从1开始计数(1表示一月)
/// @param isLeapYear 是否为闰年
AST_CORE_CAPI int aDaysInMonthByLeap(int month, bool isLeapYear);
/// @brief 获取日期是这一年的第几天,从1开始计数
AST_CORE_CAPI int aDayOfYear(const Date& date);
/// @brief 获取日期是这一周的第几天
/// @param date 日期对象
/// @return 星期几,从0开始计数(0表示星期日)
AST_CORE_CAPI int aDayOfWeek(const Date& date);
/// @brief 将年份和一年中的天数转换为日期
AST_CORE_CAPI void aYDToDate(int year, int days, Date& date);
/// @brief 将日期转换为年份和一年中的天数
AST_CORE_CAPI void aDateToYD(const Date& date, int& year, int& days);
/// @brief 规范化日期对象
AST_CORE_CAPI void aDateNormalize(Date& date);
/// @brief 将日期转换为当天中午12点的儒略日数
AST_CORE_CAPI int aDateToJDAtNoon(const Date& date);
/// @brief 将当天中午12点的儒略日数转换为当天日期
AST_CORE_CAPI void aJDToDateAtNoon(int jd, Date& date);
/// @brief 将日期转换为当天00:00的儒略日数
AST_CORE_CAPI ImpreciseJD aDateToJD(const Date& date);
/// @brief 将儒略日数转换为当天日期
/// @param jd 当天00:00的儒略日数
/// @param date 日期对象
/// @param secInDay 可选参数,用于返回当天00:00后的秒数
AST_CORE_CAPI void aJDToDate(ImpreciseJD jd, Date& date, double* secInDay=nullptr);
/// @brief 将日期转换为当天00:00的简约儒略日
AST_CORE_CAPI int aDateToMJD(const Date& date);
/// @brief 将当天00:00的简约儒略日转换为当天日期
AST_CORE_CAPI void aMJDToDate(int mjd, Date& date);
/// @brief 将日期转换为字符串表示
AST_CORE_API std::string aDateToString(const Date& date);
/// @brief 日期
class Date
{
public:
/// @brief 月份,从1开始计数(1表示一月)
enum EMonth{
eJAN = 1, eFEB, eMAR, eAPR, eMAY, eJUN,
eJUL = 7, eAUG, eSEP, eOCT, eNOV, eDEC
};
/// @brief 星期几,从0开始计数(0表示星期日)
enum EWeekDay{
eSUN = 0, eMON, eTUE, eWED, eTHU, eFRI, eSAT
};
public:
/// @brief 根据儒略日数创建日期对象
static Date FromJDAtNoon(int jd){
Date date;
aJDToDateAtNoon(jd, date);
return date;
}
/// @brief 根据年份、月份、日期创建日期对象
static Date FromYMD(int year, int month, int day){
return {year, month, day};
}
/// @brief 根据年份、一年中的天数创建日期对象
static Date FromYD(int year, int days){
Date date;
aYDToDate(year, days, date);
return date;
}
public:
int year() const{return year_;}
int& year(){return year_;}
int month() const{return month_;}
int& month(){return month_;}
int day() const{return day_;}
int& day(){return day_;}
void setYear(int year){year_ = year;}
void setMonth(int month){month_ = month;}
void setDay(int day){day_ = day;}
public:
/// @brief 获取月份的完整英文名称
const char* monthFullName() const{
return aMoonFullName(month_);
}
/// @brief 获取月份的简写英文名称
const char* monthShortName() const{
return aMoonShortName(month_);
}
/// @brief 获取星期几的完整英文名称
const char* weekDayFullName() const{
return aWeekDayFullName(dayOfWeek());
}
/// @brief 获取星期几的简写英文名称
const char* weekDayShortName() const{
return aWeekDayShortName(dayOfWeek());
}
/// @brief 获取日期是这一周的第几天
int dayOfWeek() const{
return aDayOfWeek(*this);
}
/// @brief 获取日期是这一年的第几天,从1开始计数
/// @return 第几天
int dayOfYear() const{
return aDayOfYear(*this);
}
/// @brief 判断是否为闰年
bool isLeapYear() const{
return aIsLeapYear(year_);
}
/// @brief 获取该月的天数
int dayInMonth() const{
return aDaysInMonthByYear(month_, year_);
}
/// @brief 将日期转换为儒略日数
int toJDAtNoon() const{
return aDateToJDAtNoon(*this);
}
/// @brief 将日期转换为当天00:00的儒略日数
double toJD() const{
return aDateToJD(*this);
}
/// @brief 将日期转换为当天00:00的简约儒略日数
double toMJD() const{
return aDateToMJD(*this);
}
/// @brief 将当天中午12点的儒略日数转换为日期
void fromJDAtNoon(int jd){
aJDToDateAtNoon(jd, *this);
}
/// @brief 将年份、月份、日期转换为日期
void fromYMD(int year, int month, int day){
year_ = year;
month_ = month;
day_ = day;
}
/// @brief 将年份和一年中的天数转换为日期
void fromYD(int year, int days){
aYDToDate(year, days, *this);
}
/// @brief 将日期转换为年份和一年中的天数
void toYD(int& year, int& days) const{
aDateToYD(*this, year, days);
}
/// @brief 规范化日期对象,将日期调整为有效日期
void normalize(){
aDateNormalize(*this);
}
/// @brief 返回规范化后的日期对象副本
Date normalized() const {
Date d = *this;
aDateNormalize(d);
return d;
}
public:
std::string toString() const{
return aDateToString(*this);
}
public:
int year_; ///< 年
int month_; ///< 月
int day_; ///< 日
};
/// @brief 将当天00:00的简约儒略日转换为当天日期
A_ALWAYS_INLINE Date aMJDToDate(int mjd){
Date date;
aMJDToDate(mjd, date);
return date;
}
A_ALWAYS_INLINE int aDateToMJD(int year, int month, int day){
return aDateToMJD({year, month, day});
}
/*! @} */
AST_NAMESPACE_END///
/// @file Time.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
class Time;
/// @brief 规范化时间对象
/// @details 将时间中的秒、分进行进位或借位调整,使其处于合理范围内(0-59)
/// @param time 要规范化的时间对象
AST_CORE_CAPI void aTimeNormalize(Time& time);
/// @brief 从总秒数创建时间对象
/// @details 根据总秒数计算时、分、秒,并将结果存储在时间对象中
/// @param totalSecond 总秒数
/// @param time 要存储结果的时间对象
AST_CORE_CAPI void aTimeFromTotalSecond(double totalSecond, Time& time);
/// @brief 时间
class Time
{
public:
int hour() const{return hour_;}
int& hour(){return hour_;}
int minute() const{return minute_;}
int& minute(){return minute_;}
double second() const{return second_;}
double& second(){return second_;}
void setHour(int hour){hour_ = hour;}
void setMinute(int minute){minute_ = minute;}
void setSecond(double second){second_ = second;}
/// @brief 获取时间对象的总秒数
/// @details 计算时间对象表示的总秒数,包括时、分、秒
/// @return 时间对象的总秒数
double totalSecond() const{return hour_ * 3600 + minute_ * 60 + second_;}
/// @brief 获取时间对象的日分数
/// @details 计算时间对象表示的日分数,范围为0-1
/// @return 时间对象的日分数
double dayFraction() const{return second_ / 86400.0 + minute_ / 1440.0 + hour_ / 24.0;}
public:
/// @brief 规范化时间对象
/// @details 将时间中的秒、分进行进位或借位调整,使其处于合理范围内(0-59)
void normalize(){
aTimeNormalize(*this);
}
/// @brief 获取规范化后的时间对象副本
Time normalized() const{
Time t = *this;
aTimeNormalize(t);
return t;
}
public:
int hour_; ///< 时
int minute_; ///< 分
double second_; ///< 秒
};
/*! @} */
AST_NAMESPACE_END///
/// @file DataTime.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstUtil/StringView.hpp"
#include "AstGlobal.h"
#include "Date.hpp"
#include "Time.hpp"
#include <time.h>
#include <string>
struct tm;
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
constexpr double kTimeDefaultFormatPrecision = 3;
class DateTime;
/// @brief 获取当前本地日期时间
AST_CORE_CAPI void aCurrentDateTimeLocal(DateTime& dttm);
/// @brief 获取当前UTC日期时间
AST_CORE_CAPI void aCurrentDateTimeUTC(DateTime& dttm);
/// @brief 获取今日00:00:00 UTC日期时间
/// @param dttm
/// @return
AST_CORE_CAPI void aTodayDateTimeUTC(DateTime& dttm);
/// @brief 获取明天00:00:00 UTC日期时间
/// @param dttm
/// @return
AST_CORE_CAPI void aTomorrowDateTimeUTC(DateTime& dttm);
// --------------------
// 日期时间规范化
// --------------------
/// @brief 规范化日期时间对象
/// @details 将时间调整到0-23时59分59秒之间,并调整日期到正确的范围内,不考虑闰秒
/// @param dttm
/// @return
AST_CORE_CAPI void aDateTimeNormalize(DateTime& dttm);
/// @brief 规范化日期时间对象(按UTC时间规范化)
/// @details 将日期时间对象调整到0-23时59分60秒,考虑闰秒
/// @param dttm
/// @return
AST_CORE_CAPI void aDateTimeNormalizeUTC(DateTime& dttm);
/// @brief 规范化日期时间对象(按本地时间规范化)
/// @details 将日期时间对象调整到0-23时59分60秒,考虑时区和闰秒
/// @param dttm 本地时间
/// @param timezone 时区偏移,单位:小时
/// @return
AST_CORE_CAPI void aDateTimeNormalizeLocal(DateTime& dttm, int timezone);
/// @brief 规范化日期时间对象(按北京时间规范化)
/// @details 将日期时间对象调整到0-23时59分60秒,考虑闰秒
/// @param dttm 北京时间
/// @return
AST_CORE_CAPI void aDateTimeNormalizeBJT(DateTime& dttm);
// -------------
// 日期时间递增
// -------------
/// @brief 增加年
/// @details 将日期时间对象增加指定的年数,并规范化日期时间对象
/// @param dttm
/// @param years
/// @return
AST_CORE_CAPI void aDateTimeAddYears(DateTime& dttm, int years);
/// @brief 增加月
/// @details 将日期时间对象增加指定的月数,并规范化日期时间对象
/// @param dttm
/// @param months
/// @return
AST_CORE_CAPI void aDateTimeAddMonths(DateTime& dttm, int months);
/// @brief 增加日
/// @details 将日期时间对象增加指定的天数,并规范化日期时间对象,不考虑闰秒
/// @param dttm
/// @param days
/// @return
AST_CORE_CAPI void aDateTimeAddDays(DateTime& dttm, int days);
/// @brief 增加日(UTC时间)
/// @details 将日期时间对象增加指定的天数(days*86400s)(UTC时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param days 增加的天数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddDaysUTC(DateTime& dttm, int days);
/// @brief 增加日(本地时间)
/// @details 将日期时间对象增加指定的天数(days*86400s)(本地时间),并规范化日期时间对象,考虑时区和闰秒
/// @param dttm
/// @param days 增加的天数,可正可负
/// @param timezone 时区偏移,单位:小时
/// @return
AST_CORE_CAPI void aDateTimeAddDaysLocal(DateTime& dttm, int days, int timezone);
/// @brief 增加日(北京时间)
/// @details 将日期时间对象增加指定的天数(days*86400s)(北京时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param days 增加的天数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddDaysBJT(DateTime& dttm, int days);
/// @brief 增加时
/// @details 将日期时间对象增加指定的小时数(hours*3600s),并规范化日期时间对象,不考虑闰秒
/// @param dttm
/// @param hours 增加的小时数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddHours(DateTime& dttm, int hours);
/// @brief 增加时(UTC时间)
/// @details 将日期时间对象增加指定的小时数(hours*3600s)(UTC时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param hours 增加的小时数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddHoursUTC(DateTime& dttm, int hours);
/// @brief 增加时(本地时间)
/// @details 将日期时间对象增加指定的小时数(hours*3600s)(本地时间),并规范化日期时间对象,考虑时区和闰秒
/// @param dttm
/// @param hours 增加的小时数,可正可负
/// @param timezone 时区偏移,单位:小时
/// @return
AST_CORE_CAPI void aDateTimeAddHoursLocal(DateTime& dttm, int hours, int timezone);
/// @brief 增加时(北京时间)
/// @details 将日期时间对象增加指定的小时数(hours*3600s)(北京时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param hours 增加的小时数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddHoursBJT(DateTime& dttm, int hours);
/// @brief 增加分
/// @details 将日期时间对象增加指定的分钟数(minutes*60s),并规范化日期时间对象,不考虑闰秒
/// @param dttm
/// @param minutes 增加的分钟数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddMinutes(DateTime& dttm, int minutes);
/// @brief 增加分(UTC时间)
/// @details 将日期时间对象增加指定的分钟数(UTC时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param minutes 增加的分钟数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddMinutesUTC(DateTime& dttm, int minutes);
/// @brief 增加分(本地时间)
/// @details 将日期时间对象增加指定的分钟数(minutes*60s)(本地时间),并规范化日期时间对象,考虑时区和闰秒
/// @param dttm
/// @param minutes 增加的分钟数,可正可负
/// @param timezone 时区偏移,单位:小时
/// @return
AST_CORE_CAPI void aDateTimeAddMinutesLocal(DateTime& dttm, int minutes, int timezone);
/// @brief 增加分(北京时间)
/// @details 将日期时间对象增加指定的分钟数(minutes*60s)(北京时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param minutes 增加的分钟数,可正可负
/// @return
AST_CORE_CAPI void aDateTimeAddMinutesBJT(DateTime& dttm, int minutes);
/// @brief 增加秒
/// @details 将日期时间对象增加指定的秒数,并规范化日期时间对象,不考虑闰秒
/// @param dttm
/// @param seconds
/// @return
AST_CORE_CAPI void aDateTimeAddSeconds(DateTime& dttm, double seconds);
/// @brief 增加秒(UTC时间)
/// @details 将日期时间对象增加指定的秒数(UTC时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param seconds
/// @return
AST_CORE_CAPI void aDateTimeAddSecondsUTC(DateTime& dttm, double seconds);
/// @brief 增加秒(本地时间)
/// @details 将日期时间对象增加指定的秒数(本地时间),并规范化日期时间对象,考虑时区和闰秒
/// @param dttm
/// @param seconds
/// @param timezone 时区偏移,单位:小时
/// @return
AST_CORE_CAPI void aDateTimeAddSecondsLocal(DateTime& dttm, double seconds, int timezone);
/// @brief 增加秒(北京时间)
/// @details 将日期时间对象增加指定的秒数(北京时间),并规范化日期时间对象,考虑闰秒
/// @param dttm
/// @param seconds
/// @return
AST_CORE_CAPI void aDateTimeAddSecondsBJT(DateTime& dttm, double seconds);
// -------------
// 日期时间格式化
// -------------
/// @brief 格式化日期时间为字符串
/// @details 将日期时间对象格式化为指定格式的字符串
/// @param dttm
/// @param format 格式化字符串,例如:"%Y-%m-%d %H:%M:%S"
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormat(const DateTime& dttm, StringView format, std::string& str);
/// @brief 格式化日期时间为格里高利历格式
/// @details 将日期时间对象格式化为格里高利历格式的字符串,例如:2025-11-21 12:34:56
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatGregorian(const DateTime& dttm, std::string& str, int precision = 3);
/// @brief 格式化日期时间为格里高利历格式(英文)
/// @details 将日期时间对象格式化为格里高利历格式的字符串(英文),例如:1 Jan 1970 00:00:00
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatGregorianEn(const DateTime& dttm, std::string& str);
/// @brief 格式化日期时间为GMT格式
/// @details 将日期时间对象格式化为GMT格式的字符串,例如:Sat, 21 Nov 2025 12:34:56 GMT
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatGMT(const DateTime& dttm, std::string& str);
/// @brief 格式化日期时间为ISO 8601格式
/// @details 将日期时间对象格式化为ISO 8601格式的字符串,例如:2025-11-21T12:34:56Z
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatISO8601(const DateTime& dttm, std::string& str);
/// @brief 格式化日期时间为简单ISO 8601格式
/// @details 将日期时间对象格式化为ISO 8601格式的字符串,例如:2025-11-21T12:34:56Z
A_ALWAYS_INLINE errc_t aDateTimeFormatISO(const DateTime& dttm, std::string& str)
{
return aDateTimeFormatISO8601(dttm, str);
}
/// @brief 格式化日期时间为RFC 3339格式
/// @details 将日期时间对象格式化为RFC 3339格式的字符串,例如:2025-11-21T12:34:56+08:00
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatRFC3339(const DateTime& dttm, std::string& str);
#ifdef AST_ENABLE_DATETIME_FORMAT_RFC // 启用其他RFC日期时间格式化
/// @brief 格式化日期时间为RFC 1123格式
/// @details 将日期时间对象格式化为RFC 1123格式的字符串,
/// 例如:Sat, 21 Nov 2025 12:34:56 GMT
/// 时区必须使用 GMT(RFC 1123 要求始终使用格林尼治时间)
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatRFC1123(const DateTime& dttm, std::string& str);
/// @brief 格式化日期时间为RFC 2822格式
/// @details 将日期时间对象格式化为RFC 2822格式的字符串,
/// 例如:Sat, 21 Nov 2025 12:34:56 +0800
/// Wed, 18 Feb 2015 23:16:09 GMT
/// 时区可以是 "+0000" 格式的数字时区,或者是 "GMT"、"UTC" 等标准时区名称
/// @param dttm
/// @param str
/// @return errc_t
AST_CORE_CAPI errc_t aDateTimeFormatRFC2822(const DateTime& dttm, std::string& str);
#endif
/// @brief 格式化日期时间为默认格式
/// @details 将日期时间对象格式化为默认格式的字符串,例如:2025-11-21 12:34:56.123
/// @param dttm
/// @param str
/// @return errc_t
A_ALWAYS_INLINE errc_t aDateTimeFormatDefault(const DateTime& dttm, std::string& str, int precision = kTimeDefaultFormatPrecision)
{
return aDateTimeFormatGregorian(dttm, str, precision);
}
// -------------
// 日期时间解析
// -------------
/// @brief 解析ISO 8601格式的日期时间字符串
/// @details 将ISO 8601格式的字符串解析为日期时间对象
/// @param str 包含ISO 8601格式日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseISO8601(StringView str, DateTime& dttm);
A_ALWAYS_INLINE errc_t aDateTimeParseISO(StringView str, DateTime& dttm)
{
return aDateTimeParseISO8601(str, dttm);
}
/// @brief 解析RFC 3339格式的日期时间字符串
/// @details 将RFC 3339格式的字符串解析为日期时间对象
/// @param str 包含RFC 3339格式日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseRFC3339(StringView str, DateTime& dttm);
/// @brief 解析格里高利历格式的日期时间字符串
/// @details 将格里高利历格式的字符串解析为日期时间对象
/// @param str 包含格里高利历格式日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseGregorian(StringView str, DateTime& dttm);
/// @brief 解析格里高利历格式(英文)的日期时间字符串
/// @details 将格里高利历格式(英文)的字符串解析为日期时间对象
/// @param str 包含格里高利历格式(英文)日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseGregorianEn(StringView str, DateTime& dttm);
/// @brief 解析GMT格式的日期时间字符串
/// @details 将GMT格式的字符串解析为日期时间对象
/// @param str 包含GMT格式日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseGMT(StringView str, DateTime& dttm);
/// @brief 解析自定义格式的日期时间字符串
/// @details 将自定义格式的字符串解析为日期时间对象
/// @param str 包含自定义格式日期时间的字符串
/// @param format 日期时间格式,参考strptime函数的格式规范
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParse(StringView str, StringView format, DateTime& dttm);
/// @brief 解析任意格式的日期时间字符串
/// @details 尝试解析多种日期时间格式,包括ISO 8601、RFC 3339、格里高利历等
/// @param str 包含日期时间的字符串
/// @param dttm 输出参数,解析后的日期时间对象
/// @return errc_t 错误码,eNoError表示成功
AST_CORE_CAPI errc_t aDateTimeParseAny(StringView str, DateTime& dttm);
/// @brief 日期时间
class DateTime
{
public:
/// @brief
enum ETimeZone{
eUTC = 0, ///< UTC时间(东0区)
eBJT = 8, ///< 北京时间(东8区)
};
public:
/// @brief 从儒略日数创建日期时间对象
/// @param jd 儒略日数
/// @return DateTime 日期时间对象
AST_CORE_API
static DateTime FromJD(const JulianDate& jd);
/// @brief 从儒略日数创建日期时间对象
/// @param jd 儒略日数
/// @return DateTime 日期时间对象
A_ALWAYS_INLINE
static DateTime FromJulianDate(const JulianDate& jd){return FromJD(jd);}
/// @brief 从字符串解析日期时间
/// @param str 包含日期时间的字符串
/// @param format 日期时间格式,参考strptime函数的格式规范
/// @return DateTime 解析后的日期时间对象
AST_CORE_API
static DateTime FromString(StringView str, StringView format);
/// @brief 从字符串解析日期时间(默认格式:"yyyy-MM-dd HH:mm:ss")
/// @param str 包含日期时间的字符串
/// @return DateTime 解析后的日期时间对象
AST_CORE_API
static DateTime FromString(StringView str);
/// @brief 从格里高利历日期时间创建日期时间对象
/// @return DateTime 日期时间对象
AST_CORE_API
static DateTime FromGregorian(StringView str);
/// @brief 根据系统时间创建日期时间对象
AST_CORE_API
static DateTime FromTm(const tm* time);
/// @brief 根据time_t创建本地时间的日期时间对象
AST_CORE_API
static DateTime FromTimeTLocal(time_t time);
/// @brief 根据time_t创建UTC时间的日期时间对象
AST_CORE_API
static DateTime FromTimeTUTC(time_t time);
/// @brief 从字符串解析日期时间(任意格式)
/// @param str 包含日期时间的字符串
/// @return DateTime 解析后的日期时间对象
static DateTime Parse(StringView str){
DateTime dttm;
aDateTimeParseAny(str, dttm);
return dttm;
}
public:
const Date& date() const{return date_;}
Date& date() {return date_;}
const Time& time() const {return time_;}
Time& time() {return time_;}
int year() const {return date_.year();}
int& year() {return date_.year();}
int month() const {return date_.month();}
int& month() {return date_.month();}
int day() const {return date_.day();}
int& day() {return date_.day();}
int hour() const {return time_.hour();}
int& hour() {return time_.hour();}
int minute() const {return time_.minute();}
int& minute() {return time_.minute();}
double second() const {return time_.second();}
double& second() {return time_.second();}
int dayOfYear() const {return date_.dayOfYear();}
int dayOfWeek() const {return date_.dayOfWeek();}
void setYear(int year) {date_.setYear(year);}
void setMonth(int month) {date_.setMonth(month);}
void setDay(int day) {date_.setDay(day);}
void setHour(int hour) {time_.setHour(hour);}
void setMinute(int minute) {time_.setMinute(minute);}
void setSecond(double second) {time_.setSecond(second);}
public:
void normalize(){
aDateTimeNormalize(*this);
}
void normalizeUTC(){
aDateTimeNormalizeUTC(*this);
}
void normalizeLocal(int timezone){
aDateTimeNormalizeLocal(*this, timezone);
}
void normalizeBJT(){
aDateTimeNormalizeBJT(*this);
}
DateTime normalized() const{
DateTime dttm = *this;
dttm.normalize();
return dttm;
}
DateTime normalizedUTC() const{
DateTime dttm = *this;
dttm.normalizeUTC();
return dttm;
}
DateTime normalizedLocal(int timezone) const{
DateTime dttm = *this;
dttm.normalizeLocal(timezone);
return dttm;
}
DateTime normalizedBJT() const{
DateTime dttm = *this;
dttm.normalizeBJT();
return dttm;
}
public:
std::string toString(int precision = 3) const{
std::string str;
aDateTimeFormatDefault(*this, str, precision);
return str;
}
public:
void addYears(int years){
aDateTimeAddYears(*this, years);
}
void addMonths(int months){
aDateTimeAddMonths(*this, months);
}
void addDays(int days){
aDateTimeAddDays(*this, days);
}
void addDaysUTC(int days){
aDateTimeAddDaysUTC(*this, days);
}
void addDaysLocal(int days, int timezone){
aDateTimeAddDaysLocal(*this, days, timezone);
}
void addDaysBJT(int days){
aDateTimeAddDaysBJT(*this, days);
}
void addHours(int hours){
aDateTimeAddHours(*this, hours);
}
void addHoursUTC(int hours){
aDateTimeAddHoursUTC(*this, hours);
}
void addHoursLocal(int hours, int timezone){
aDateTimeAddHoursLocal(*this, hours, timezone);
}
void addHoursBJT(int hours){
aDateTimeAddHoursBJT(*this, hours);
}
void addMinutes(int minutes){
aDateTimeAddMinutes(*this, minutes);
}
void addMinutesUTC(int minutes){
aDateTimeAddMinutesUTC(*this, minutes);
}
void addMinutesLocal(int minutes, int timezone){
aDateTimeAddMinutesLocal(*this, minutes, timezone);
}
void addMinutesBJT(int minutes){
aDateTimeAddMinutesBJT(*this, minutes);
}
void addSeconds(double seconds){
aDateTimeAddSeconds(*this, seconds);
}
void addSecondsUTC(double seconds){
aDateTimeAddSecondsUTC(*this, seconds);
}
void addSecondsLocal(double seconds, int timezone){
aDateTimeAddSecondsLocal(*this, seconds, timezone);
}
void addSecondsBJT(double seconds){
aDateTimeAddSecondsBJT(*this, seconds);
}
public:
DateTime& operator += (double sec)
{
this->second() += sec; // 适用于任何时间尺度,包括考虑闰秒的和不考虑闰秒的
return *this;
}
DateTime& operator -= (double sec)
{
this->second() -= sec; // 适用于任何时间尺度,包括考虑闰秒的和不考虑闰秒的
return *this;
}
DateTime operator + (double sec) const
{
auto dttm = DateTime{ *this };
dttm += sec;
return dttm;
}
DateTime operator -(double sec) const
{
auto dttm = DateTime{ *this };
dttm -= sec;
return dttm;
}
public:
Date date_; ///< 日期
Time time_; ///< 时间
};
A_ALWAYS_INLINE
DateTime aCurrentDateTimeLocal()
{
DateTime dttm;
aCurrentDateTimeLocal(dttm);
return dttm;
}
A_ALWAYS_INLINE
DateTime aCurrentDateTimeUTC()
{
DateTime dttm;
aCurrentDateTimeUTC(dttm);
return dttm;
}
/*! @} */
AST_NAMESPACE_END///
/// @file JulianDate.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
#include "Duration.hpp"
#include "AstUtil/Constants.h"
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
class JulianDate;
class Date;
class Time;
class DateTime;
/// @brief 将儒略日转换为简约儒略日
AST_CORE_CAPI void aJDToMJD(const JulianDate& jd, ModJulianDate& mjd);
/// @brief 将简约儒略日转换为儒略日
AST_CORE_CAPI void aMJDToJD(const ModJulianDate& mjd, JulianDate& jd);
/// @brief 将儒略日转换为简约儒略日
/// @warning 注意用单个double表示的时间精度不高
AST_CORE_API double aJDToMJD_Imprecise(const JulianDate& jd);
/// @brief 将简约儒略日Modified Julian Date(MJD)转换为儒略日
/// @warning 注意用单个double表示的时间精度不高
AST_CORE_API ImpreciseMJD aJDToMJD_Imprecise(ImpreciseJD jd);
/// @brief 将简约儒略日Modified Julian Date(MJD)转换为不精确的儒略日
/// @warning 注意用单个double表示的时间精度不高
AST_CORE_API ImpreciseJD aMJDToJD_Imprecise(const ModJulianDate& mjd);
/// @brief 将儒略日转换为简约儒略日Modified Julian Date(MJD)
/// @warning 注意用单个double表示的时间精度不高
AST_CORE_API ImpreciseJD aMJDToJD_Imprecise(ImpreciseMJD mjd);
/// @brief 将日期时间转换为儒略日
AST_CORE_CAPI void aDateTimeToJD(const DateTime& dttm, JulianDate& jd);
/// @brief 将儒略日转换为日期时间
AST_CORE_CAPI void aJDToDateTime(const JulianDate& jd, DateTime& dttm);
/// @brief 儒略日
/// @details 儒略日(Julian Date)是一种用于表示时间的方法,常用于天文学和计算机科学中。
/// ast项目将其实现为整数天 + 小数秒的形式,保证数值精度
class JulianDate
{
public:
/// @brief 根据不精确的天数创建儒略日对象
static JulianDate FromImpreciseDay(double JD){
int day = static_cast<int>(JD);
double second = (JD - day) * 86400.0;
return JulianDate::FromDaySecond(day, second);
}
/// @brief 根据天数和秒数创建儒略日对象
static JulianDate FromDaySecond(int day, double second){
return JulianDate{day, second};
}
/// @brief 根据日期时间创建儒略日对象
static JulianDate FromDateTime(const DateTime& dttm)
{
JulianDate jd;
aDateTimeToJD(dttm, jd);
return jd;
}
/// @brief 获取 J2000.0 历元的儒略日对象
static JulianDate J2000(){
return JulianDate::FromDaySecond(static_cast<int>(kJ2000Epoch), 0.0);
}
AST_CORE_API
static JulianDate FromDateTime(int year, int month, int day, int hour, int minute, double second);
public:
/// @brief 获取不精确的天数
/// @return 不精确的天数
double impreciseDay() const{return day_ + second_ /86400.;}
/// @brief 设置不精确的天数
void setImpreciseDay(double jd){
int day = static_cast<int>(jd);
double second = (jd - day) * 86400.0;
setDaySecond(day, second);
}
public:
int day() const{return day_;}
int& day(){return day_;}
double second() const {return second_;}
double& second(){return second_;}
void setDay(int day){day_ = day;}
void setSecond(double sec){second_ = sec;}
/// @brief 获取天数和秒数
void getDaySecond(int& day, double& second) const{
day = day_;
second = second_;
}
/// @brief 设置天数和秒数
void setDaySecond(int day, double second){
day_ = day;
second_ = second;
}
public:
/// @brief 获取小数部分的日数
double dayFractional() const{
return second_ / kSecondsPerDay;
}
/// @brief 设置小数部分的日数
void setDayFractional(double df){
second_ = df * kSecondsPerDay;
}
public:
/// @brief 计算儒略日与 J2000.0 历元的时间差(儒略世纪)
double julianCenturyFromJ2000() const{
return daysFromJ2000() / kDaysPerJulianCentury;
}
/// @brief 计算儒略日与 J2000.0 历元的时间差(儒略日)
double daysFromJ2000() const{
return ((day_ - kJ2000Epoch) + dayFractional());
}
/// @brief 计算儒略日与 J2000.0 历元的时间差(秒)
double secondsFromJ2000() const{
return (day_ - kJ2000Epoch) * kSecondsPerDay + second_;
}
public:
JulianDate& operator += (double sec)
{
this->second() += sec; // 适用于任何时间尺度,包括考核闰秒的和不考虑闰秒的
return *this;
}
JulianDate& operator -= (double sec)
{
this->second() -= sec; // 适用于任何时间尺度,包括考核闰秒的和不考虑闰秒的
return *this;
}
JulianDate operator + (double sec) const
{
JulianDate jd{ *this };
jd += sec;
return jd;
}
JulianDate operator - (double sec) const
{
JulianDate jd{ *this };
jd -= sec;
return jd;
}
DaySecDuration operator - (const JulianDate& other) const
{
return {day() - other.day(), second() - other.second()};
}
public:
/// @brief 计算儒略日偏移后的新儒略日
/// @param second 偏移秒数
/// @return 偏移后的新儒略日
JulianDate shiftedBySecond(double second) const{
return JulianDate::FromDaySecond(day_, second_ + second);
}
public:
int day_; // 天数部分 day part of julian date
double second_; // 秒数部分 second part of julia date
};
/*! @} */
AST_NAMESPACE_END///
/// @file ModJulianDate.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 30.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
#include "JulianDate.hpp"
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
/// @brief 简约儒略日
class ModJulianDate: protected JulianDate
{
public:
using JulianDate::JulianDate;
using JulianDate::day;
using JulianDate::second;
using JulianDate::setDay;
using JulianDate::setSecond;
using JulianDate::getDaySecond;
using JulianDate::setDaySecond;
using JulianDate::dayFractional;
using JulianDate::setDayFractional;
using JulianDate::impreciseDay;
using JulianDate::setImpreciseDay;
using JulianDate::operator +=;
using JulianDate::operator -=;
using JulianDate::operator +;
using JulianDate::operator -;
};
/*! @} */
AST_NAMESPACE_END///
/// @file Duration.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
#include "AstUtil/Constants.h"
#include <stdint.h> // for int64_t
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
/// @brief 短时长
class ShortDuration
{
public:
double second() const{return second_;}
double& second(){return second_;}
public:
double second_; // 秒数
};
/// @brief 长时长
class LongDuration
{
public:
/// @brief 获取整数秒部分
int64_t integer() const{return integer_;}
int64_t& integer(){return integer_;}
/// @brief 获取小数秒部分
double fractional() const{return fractional_;}
double& fractional(){return fractional_;}
/// @brief 时长减法运算符
/// @param other 另一个时长
/// @return 两个时长的差值(秒数)
double operator-(const LongDuration& other) const{
return minusInSecond(other);
}
/// @brief 时长减法方法(秒)
/// @param other 另一个时长
/// @return 两个时长的差值(秒数)
double minusInSecond(const LongDuration& other) const{
return (integer_ - other.integer_) + (fractional_ - other.fractional_);
}
/// @brief 时长减法方法(分钟)
/// @param other 另一个时长
/// @return 两个时长的差值(分钟数)
double minusInMinute(const LongDuration& other) const{
return (integer_ - other.integer_) / kSecondsPerMinute + (fractional_ - other.fractional_) / kSecondsPerMinute;
}
double minusInHour(const LongDuration& other) const{
return (integer_ - other.integer_) / kSecondsPerHour + (fractional_ - other.fractional_) / kSecondsPerHour;
}
/// @brief 时长减法方法(天)
/// @param other 另一个时长
/// @return 两个时长的差值(天数)
double minusInDay(const LongDuration& other) const{
return (integer_ - other.integer_) / kSecondsPerDay + (fractional_ - other.fractional_) / kSecondsPerDay;
}
public:
int64_t integer_; // 整数秒部分
double fractional_; // 小数秒部分
};
/// @brief 整数天 + 小数秒时长(也能解决长时长问题)
class DaySecDuration
{
public:
/// @brief 获取整数天部分
int day() const{return day_;}
int& day(){return day_;}
/// @brief 获取小数部分的秒数
double second() const{return second_;}
double& second(){return second_;}
/// @warning
/// 注意:totalSecond() 方法返回的是一个不精确的double值,
/// 计算会引入舍入误差。且不考虑闰秒等因素。
/// @return 总秒数(整数天秒数 + 小数秒数)
double totalSecond() const{return day_ * 86400.0 + second_;}
public:
int day_; // 整数天部分
double second_; // 小数秒部分
};
/*! @} */
AST_NAMESPACE_END///
/// @file TimeSystem.hpp
/// @brief
/// @details ~
/// @author axel
/// @date 21.11.2025
/// @copyright 版权所有 (C) 2025-present, ast项目.
///
/// ast项目(https://github.com/space-ast/ast)
/// 本项目基于 Apache 2.0 开源许可证分发。
/// 您可在遵守许可证条款的前提下使用、修改和分发本软件。
/// 许可证全文请见:
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// 重要须知:
/// 软件按“现有状态”提供,无任何明示或暗示的担保条件。
/// 除非法律要求或书面同意,作者与贡献者不承担任何责任。
/// 使用本软件所产生的风险,需由您自行承担。
#pragma once
#include "AstGlobal.h"
#include "AstCore/Constants.h"
#include "AstCore/DateTime.hpp"
#include "AstCore/JulianDate.hpp"
AST_NAMESPACE_BEGIN
/*!
@addtogroup Time
@{
*/
class JulianDate;
class DateTime;
/// @brief 从原子时(TAI) 转换为 地球时(TT)
/// @param tmTAI 原子时(TAI)
/// @param tmTT 地球时(TT)
template<typename Time>
A_ALWAYS_INLINE void aTAIToTT(const Time& tmTAI, Time& tmTT)
{
tmTT = aTAIToTT(tmTAI);
}
template<typename Time>
A_ALWAYS_INLINE Time aTAIToTT(const Time& tmTAI)
{
return tmTAI + kTTMinusTAI;
}
/// @brief 从地球时(TT) 转换为 原子时(TAI)
/// @param tmTT 地球时(TT)
/// @param tmTAI 原子时(TAI)
template<typename Time>
A_ALWAYS_INLINE void aTTToTAI(const Time& tmTT, Time& tmTAI)
{
tmTAI = aTTToTAI(tmTT);
}
template<typename Time>
A_ALWAYS_INLINE Time aTTToTAI(const Time& tmTT)
{
return tmTT - kTTMinusTAI;
}
/// @brief 从原子时(TAI) 转换为 GPS时
/// @param tmTAI 原子时(TAI)
/// @param tmGPS GPS时
template<typename Time>
A_ALWAYS_INLINE void aTAIToGPS(const Time& tmTAI, Time& tmGPS)
{
tmGPS = tmTAI + kGPSMinusTAI;
}
template<typename Time>
A_ALWAYS_INLINE Time aTAIToGPS(const Time& tmTAI)
{
return tmTAI + kGPSMinusTAI;
}
/// @brief 从GPS时 转换为 原子时(TAI)
/// @param tmGPS GPS时
/// @param tmTAI 原子时(TAI)
template<typename Time>
A_ALWAYS_INLINE void aGPSToTAI(const Time& tmGPS, Time& tmTAI)
{
tmTAI = tmGPS - kGPSMinusTAI;
}
template<typename Time>
A_ALWAYS_INLINE Time aGPSToTAI(const Time& tmGPS)
{
return tmGPS - kGPSMinusTAI;
}
/// @brief 从原子时(TAI) 转换为 协调世界时(UTC)
/// @param jdTAI 原子时(TAI)
/// @param jdUTC 协调世界时(UTC)
AST_CORE_API void aTAIToUTC(const JulianDate& jdTAI, JulianDate& jdUTC);
AST_CORE_API void aTAIToUTC(const DateTime& dttmTAI, DateTime& dttmUTC);
A_ALWAYS_INLINE JulianDate aTAIToUTC(const JulianDate& jdTAI)
{
JulianDate jdUTC;
aTAIToUTC(jdTAI, jdUTC);
return jdUTC;
}
A_ALWAYS_INLINE DateTime aTAIToUTC(const DateTime& dttmTAI)
{
DateTime dttmUTC;
aTAIToUTC(dttmTAI, dttmUTC);
return dttmUTC;
}
/// @brief 从协调世界时(UTC) 转换为 原子时(TAI)
/// @param jdUTC 协调世界时(UTC)
/// @param jdTAI 原子时(TAI)
AST_CORE_API void aUTCToTAI(const JulianDate& jdUTC, JulianDate& jdTAI);
AST_CORE_API void aUTCToTAI(const DateTime& dttmUTC, DateTime& dttmTAI);
A_ALWAYS_INLINE JulianDate aUTCToTAI(const JulianDate& jdUTC)
{
JulianDate jdTAI;
aUTCToTAI(jdUTC, jdTAI);
return jdTAI;
}
A_ALWAYS_INLINE DateTime aUTCToTAI(const DateTime& dttmUTC)
{
DateTime dttmTAI;
aUTCToTAI(dttmUTC, dttmTAI);
return dttmTAI;
}
/// @brief 从协调世界时(UTC) 转换为 地球时(TT)
/// @param jdUTC 协调世界时(UTC)
/// @param jdTT 地球时(TT)
AST_CORE_API void aUTCToTT(const JulianDate& jdUTC, JulianDate& jdTT);
AST_CORE_API void aUTCToTT(const DateTime& dttmUTC, DateTime& dttmTT);
A_ALWAYS_INLINE JulianDate aUTCToTT(const JulianDate& jdUTC)
{
JulianDate jdTT;
aUTCToTT(jdUTC, jdTT);
return jdTT;
}
A_ALWAYS_INLINE DateTime aUTCToTT(const DateTime& dttmUTC)
{
DateTime dttmTT;
aUTCToTT(dttmUTC, dttmTT);
return dttmTT;
}
/// @brief 从协调世界时(UTC) 转换为 世界时(UT1)
AST_CORE_API void aUTCToUT1(const JulianDate& jdUTC, JulianDate& jdUT1);
AST_CORE_API void aUTCToUT1(const DateTime& dttmUTC, DateTime& dttmUT1);
/// @brief 从地球时(TT) 转换为 协调世界时(UTC)
/// @param jdTT 地球时(TT)
/// @param jdUTC 协调世界时(UTC)
AST_CORE_API void aTTToUTC(const JulianDate& jdTT, JulianDate& jdUTC);
AST_CORE_API void aTTToUTC(const DateTime& dttmTT, DateTime& dttmUTC);
A_ALWAYS_INLINE JulianDate aTTToUTC(const JulianDate& jdTT)
{
JulianDate jdUTC;
aTTToUTC(jdTT, jdUTC);
return jdUTC;
}
A_ALWAYS_INLINE DateTime aTTToUTC(const DateTime& dttmTT)
{
DateTime dttmUTC;
aTTToUTC(dttmTT, dttmUTC);
return dttmUTC;
}
/// @brief 从地球时(TT) 转换为质心动力学时(TDB)
/// @param jdTT 地球时(TT)
/// @param jdTDB 质心动力学时(TDB)
AST_CORE_API void aTTToTDB(const JulianDate& jdTT, JulianDate& jdTDB);
AST_CORE_API void aTTToTDB(const DateTime& dttmTT, DateTime& dttmTDB);
A_ALWAYS_INLINE JulianDate aTTToTDB(const JulianDate& jdTT)
{
JulianDate jdTDB;
aTTToTDB(jdTT, jdTDB);
return jdTDB;
}
A_ALWAYS_INLINE DateTime aTTToTDB(const DateTime& dttmTT)
{
DateTime dttmTDB;
aTTToTDB(dttmTT, dttmTDB);
return dttmTDB;
}
AST_CORE_API void aTDBToTT(const JulianDate& jdTDB, JulianDate& jdTT);
AST_CORE_API void aTDBToTT(const DateTime& dttmTDB, DateTime& dttmTT);
A_ALWAYS_INLINE JulianDate aTDBToTT(const JulianDate& jdTDB)
{
JulianDate jdTT;
aTDBToTT(jdTDB, jdTT);
return jdTT;
}
A_ALWAYS_INLINE DateTime aTDBToTT(const DateTime& dttmTDB)
{
DateTime dttmTT;
aTDBToTT(dttmTDB, dttmTT);
return dttmTT;
}
/// @brief 计算 质心动力学时(TDB) 时间与 地球时(TT) 时间的差值
/// @param jdTT 地球时(TT)
/// @warning 注意输入的时间必须是 地球时(TT) 时间
/// @return 质心动力学时(TDB) 时间与 地球时(TT) 时间的差值
AST_CORE_CAPI double aTDBMinusTT(const JulianDate& jdTT);
/// @brief 计算 地球时(TT) 时间与 质心动力学时(TDB) 时间的差值
/// @param jdTDB 质心动力学时(TDB)
/// @warning 注意输入的时间必须是 质心动力学时(TDB) 时间
/// @return 地球时(TT) 时间与 质心动力学时(TDB) 时间的差值
AST_CORE_CAPI double aTTMinusTDB(const JulianDate& jdTDB);
/// @brief 计算儒略世纪数,以 J2000.0 为基准
/// @param jd 儒略日
/// @return 儒略世纪数
AST_CORE_CAPI double aJulianCenturyFromJ2000(const JulianDate& jd);
/// @brief 将 SPICE 时间转换为 TimePoint
/// @param et SPICE 时间(秒)
/// @return 对应的 TimePoint 实例
AST_CORE_API TimePoint aSpiceEtToTimePoint(double et);
/// @brief 将 TimePoint 转换为 SPICE 时间
/// @param tp TimePoint 实例
/// @return 对应的 SPICE 时间(秒)
AST_CORE_API double aTimePointToSpiceEt(const TimePoint& tp);
/*! @} */
AST_NAMESPACE_END