You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xiaomibianqianweihu/calendar.h

214 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef LUNAR_H
#define LUNAR_H
#include <ctime>
#include <string>
#include <vector>
#include <map>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif // _WIN32
typedef long long int INT64;
class Calendar
{
/*
* ********************************************************************
* ********************************************************************
* **
* ** 1.【功能】根据公历日期查 农历日期、四柱、节气(精确到秒)
* **
* ** 2.【重要信息】本程序的四柱是以 <立春> 为界限(精确到秒)
* **
* ** 3.【支持的时间段】公历 1900-01-31 至 2098-12-31
* ** 此时间段内时间标准与寿星天文历数据一致
* **
* ** 4.【实现】 因使用跨度和信息很少,因此使用查表法实现
* **
* ** 5.【接口】内含时间日期处理,和节气日期处理的函数接口可以使用。
* ** 但要注意部分日期处理仅支持上诉日期范围,如节气的日期计算。
* **
* ** -- by taynpg
* *********************************************************************
* *********************************************************************
*/
/*
* 《使用方法》
* 新建一个 Calendar 对象后
* 先调用以下函数进行 公历 [年月日时分秒]录入,即可使用其他内容。
*
* < SetSolarDate >
*/
/* 本程序的初始化入口函数 */
public:
// 录入公历日期(同一个对象可以反复调用),如果日期不合法,返回 false。
// 最后两个参数 分钟 秒钟 默认为 0可以不填写。若传入的日期当天有节气则可能会对结果有影响
// 若传入的日期当天没有节气,则对结果无影响、因此若日期当日有节气信息,建议传入精确时间。
bool SetSolarDate(int year, int month, int day, int hour, int min = 0, int second = 0);
/* 该部分是传入的内容 (用户主要使用的部分) */
public:
int solarYear = 0; // 公历年 4 位数字
int solarMonth = 0; // 公历月
int solarDay = 0; // 公历日
int solarHour = 0; // 公历小时
int solarMin = 0; // 公历分
int solarSecond = 0; // 公历秒
/* 该部分是计算出来的内容 (用户主要使用的部分) */
public:
int lunarYear = 0; // 农历年 4 位数字
int lunarMonth = 0; // 农历月
int lunarDay = 0; // 农历日
bool isBigMonth = false; // 农历的月 月大还是月小,(月大 30 天,月小 29 天)。
bool isLeapMonth = false; // 当前农历月是否为农历闰月
std::string lunarYearZhu = ""; // 年柱信息(两个字),如 甲子
std::string lunarMonthZhu = ""; // 月柱信息(两个字),如 甲子
std::string lunarDayZhu = ""; // 日柱信息(两个字),如 甲子
std::string lunarHourZhu = ""; // 时柱信息(两个字),如 甲子
std::string jieQiOne = ""; // 本月第一个节气信息,返回格式示例 04-04-清明-时间-13:12:44
std::string jieQiTwo = ""; // 本月第二个节气信息,返回格式示例 04-19-谷雨-时间-20:01:14
std::string shengxiaoyear = ""; // 生肖年
/* (本程序使用的接口, 用户也可使用,但用户需要自己判断输入的参数内容或格式是否合法) */
public:
Calendar();
~Calendar();
void Init(); // 初始化成员变量,因该函数需要反复调用,所以单独拿出来。
// 根据基准日期时间和相差的秒钟算 另一个日期 格式 YYYYMMDDHHMMSS ,相差秒钟分正(向前)负(向后)
std::string GetDateFromTimeDiffAndBase(const std::string &date, INT64 seconds);
// 返回一个公历日期的前一天的日期, 格式 YYYYMMDD未检查输入日期的合法性。
std::string GetPreDayFromDate(const std::string &date);
// 返回一个公历日期的后一天的日期, 格式 YYYYMMDD未检查输入日期的合法性。
std::string GetAfterDayFromDate(const std::string &date);
// 判断中间的日期是否在前后两个日期之间 格式 YYYYMMDDHHMMSS
bool IsDateBetweenAC(const std::string &one, const std::string &two, const std::string &three);
// 计算两个日期时间之间相差的秒数 参数为 YYYYMMDDHHMMSS
INT64 GetDateTimeDiffTwo(const std::string &one, const std::string &two);
// 返回两个时间点的秒数之差 参数都为 HHMMSS
int GetTimeDiffTwo(const std::string &one, const std::string &two);
// 判断是否是闰年
bool IsLeapYear(int year);
// 让月、日、时、分、秒为个数时首位加 0
std::string TurnWithZero(long num);
// 判断时间是否合法 HHMMSS
bool IsTimeLegal(const std::string &time);
// 判断日期时间是否合法 YYYYMMDDHHMMSS
bool IsDateTimeLegal(const std::string &dateTime);
// 判断公历是否合法 YYYYMMDD
bool IsSolarLegal(const std::string &date);
// 返回两个日期之间的天数差 参数为 YYYYMMDD
int GetDayDiffTwo(const std::string &one, const std::string &two);
// 返回距离 1900.1.1 的天数 格式 YYYYMMDD
int GetDayDiffFromBase(const std::string &date);
// 传入年月日给出标准 YYYYMMDD 格式
std::string GetStandardDate(int year, int month, int day);
// 传入标准 YYYYMMDD 格式,返回年月日
void GetDateFromStandardString(const std::string& datetime, int& year, int& month, int& day);
// 传入年月日时分秒给出标准 YYYYMMDDHHMMSS 格式
std::string GetStandardDateTime(int year, int month, int day, int hour, int min, int sec);
// 传入标准 YYYYMMDDHHMMSS 格式, 返回年月日时分秒
void GetDateTimeFromStandardString(const std::string &datetime, int &year, int &month, int &day, int &hour, int &min, int &sec);
// 传入时分秒给出标准 HHMMSS 格式
std::string GetStandardTime(int hour, int min, int sec);
// 传入标准 HHMMSS 时间格式返回时分秒
void GetTimeFromStandardString(const std::string time, int &hour, int &min, int &sec);
/* 本程序未使用但个人认为有用的函数 */
public:
// 获取当前系统日期时间,精确到毫秒 格式 YYYYMMDDHHMMSSMIL
std::string GetSysDateTimeMill();
// 返回一个时间到 00:00:00 的秒数 ,输入 HHMMSS
int GetMiaoDiffToZero(const std::string &time);
// 根据日期 YYYYMMDD 返回这一天是星期几 0-周日, 1-周一 以此类推
int GetWeekIndexFromDate(const std::string &date);
//根据年份 返回这一年是哪个生肖年
int Getzodiacyear(int year);
/* 表 */
public:
std::map<int, std::string> sixtyJiazi; // 序号->查60甲子
std::map<std::string, int> sixtyJiaziIndex; // 60甲子->序号
std::map<std::string, int> jieQiInfo; // 节气信息->序号
std::map<int, std::string> jieQiInfoIndex; // 序号->节气信息
std::vector<std::string> tianGan; // 天干信息表
std::vector<std::string> diZhi; // 地支信息表
std::vector<std::string> shengxiao; //十二生肖
/* 表 */
public:
std::vector<int> lunarInfo; // 查表法的农历信息表
int* times = NULL; // 各节气之间相差的秒数(精确数据,用于计算节气的具体时间)
std::map<std::string, std::string> wuHu; // 五虎遁年起月表
std::map<std::string, std::string> qiShi; // 日上起时法表
/* 主要是本程序使用 */
public:
std::string getJiazi(int num); // 传入 offset 返回干支, 0=甲子
// 将格式为 【04-04-清明-时间-13:12:44】的字符串转成 YYYYMMDDHHMMSS 标准格式,节气名称保存到 jieQi 中
std::string getJieQiStandardTime(int year, const std::string& time, std::string& jieQi);
// 对于纯中文(注意不能字符和中文夹杂)的 substr (参数num 为该字符串有几个中文汉字)
std::string zhSubstr(const std::string& data, int num, size_t start, size_t length);
// 对 num 取余jinZhi 为基数num 支持负数,结果在 [0, jinZhi-1]内
int getRemainder(int num, int jinZhi);
/* 主要是本程序使用 */
public:
int getLunarYearDays(int year); // 返回农历 y 年的总天数
int getLunarLeapDays(int year); // 返回农历 y 年闰月的天数
int getLunarLeapMonth(int year); // 返回农历 y 年闰哪个月 1-12 , 没闰返回 0
int getLunarMonthDays(int year, int month); // 返回农历 y 年 m 月的总天数
int getLunarSTerm(int year, int n, std::string& result); // 某年的第 n 个节气为几日 (从0小寒起算)
void getYearMonthZhu(); // 计算农历年的 年柱、月柱 (以立春为新年)
void getHourZhu(); // 计算时柱 (该函数要在计算年柱月柱之后执行)
// 给出某年某月的年柱、月柱、返回上一个月的年柱、月柱。并指出所给月份是否是含立春的月份。
std::string getPreMonthYearMothZhu(const std::string &yearZhu, const std::string &monthZhu, bool isLiChun);
// 传入公历的年、月、此月的节气、此月的月柱、此年柱 -> 获取该节气的下一个节气的 年、月、节气、月柱、年柱(YYYYMMXXPPYY)
void getNexJieQiInfo(int &year, int &month, std::string &jieQi, std::string &monthZhu, std::string &yearZhu);
// 给出年柱,返回下一年的起始月柱, 格式 XX
std::string getNextYearYearMonthZhu(const std::string &yearZhu);
// 字符串分割
void SplitString(const std::string &data, std::string splitString, std::vector<std::string> &result);
};
#endif // LUNAR_H