mirror of
https://github.com/tsl0922/EPD-nRF5.git
synced 2025-12-06 15:42:48 +08:00
449 lines
19 KiB
C
449 lines
19 KiB
C
#include "Lunar.h"
|
||
|
||
const char Lunar_MonthString[13][7] = {"----", "正月", "二月", "三月", "四月", "五月", "六月",
|
||
"七月", "八月", "九月", "十月", "冬月", "腊月"};
|
||
|
||
const char Lunar_MonthLeapString[2][4] = {" ", "闰"};
|
||
|
||
const char Lunar_DateString[31][7] = {"----", "初一", "初二", "初三", "初四", "初五", "初六", "初七",
|
||
"初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五",
|
||
"十六", "十七", "十八", "十九", "二十", "廿一", "廿二", "廿三",
|
||
"廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"};
|
||
|
||
const char Lunar_DayString[7][4] = {"日", "一", "二", "三", "四", "五", "六"};
|
||
|
||
const char Lunar_ZodiacString[12][4] = {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"};
|
||
|
||
const char Lunar_StemStrig[10][4] = {"庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁", "戊", "己"};
|
||
|
||
const char Lunar_BranchStrig[12][4] = {"申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"};
|
||
|
||
/* 2000 ~ 2199 */
|
||
const uint32_t lunar_month_days[] = {
|
||
1997,
|
||
0x0000B26D, 0x0000125C, 0x0000192C, 0x00009A95, 0x00001A94, 0x00001B4A, 0x00004B55, 0x00000AD4, 0x0000F55B,
|
||
0x000004BA, 0x0000125A, 0x0000B92B, 0x0000152A, 0x00001694, 0x000096AA, 0x000015AA, 0x00012AB5, 0x00000974,
|
||
0x000014B6, 0x0000CA57, 0x00000A56, 0x00001526, 0x00008E95, 0x00000D54, 0x000015AA, 0x000049B5, 0x0000096C,
|
||
0x0000D4AE, 0x0000149C, 0x00001A4C, 0x0000BD26, 0x00001AA6, 0x00000B54, 0x00006D6A, 0x000012DA, 0x0001695D,
|
||
0x0000095A, 0x0000149A, 0x0000DA4B, 0x00001A4A, 0x00001AA4, 0x0000BB54, 0x000016B4, 0x00000ADA, 0x0000495B,
|
||
0x00000936, 0x0000F497, 0x00001496, 0x0000154A, 0x0000B6A5, 0x00000DA4, 0x000015B4, 0x00006AB6, 0x0000126E,
|
||
/*0x0001092F, 0x0000092E, 0x00000C96, 0x0000CD4A, 0x00001D4A, 0x00000D64, 0x0000956C, 0x0000155C, 0x0000125C,
|
||
0x0000792E, 0x0000192C, 0x0000FA95, 0x00001A94, 0x00001B4A, 0x0000AB55, 0x00000AD4, 0x000014DA, 0x00008A5D,
|
||
0x00000A5A, 0x0001152B, 0x0000152A, 0x00001694, 0x0000D6AA, 0x000015AA, 0x00000AB4, 0x000094BA, 0x000014B6,
|
||
0x00000A56, 0x00007527, 0x00000D26, 0x0000EE53, 0x00000D54, 0x000015AA, 0x0000A9B5, 0x0000096C, 0x000014AE,
|
||
0x00008A4E, 0x00001A4C, 0x00011D26, 0x00001AA4, 0x00001B54, 0x0000CD6A, 0x00000ADA, 0x0000095C, 0x0000949D,
|
||
0x0000149A, 0x00001A2A, 0x00005B25, 0x00001AA4, 0x0000FB52, 0x000016B4, 0x00000ABA, 0x0000A95B, 0x00000936,
|
||
0x00001496, 0x00009A4B, 0x0000154A, 0x000136A5, 0x00000DA4, 0x000015AC, 0x0000CAB6, 0x0000126E, 0x0000092E,
|
||
0x00008C97, 0x00000A96, 0x00000D4A, 0x00006DA5, 0x00000D54, 0x0000F56A, 0x0000155A, 0x00000A5C, 0x0000B92E,
|
||
0x0000152C, 0x00001A94, 0x00009D4A, 0x00001B2A, 0x00016B55, 0x00000AD4, 0x000014DA, 0x0000CA5D, 0x00000A5A,
|
||
0x0000151A, 0x0000BA95, 0x00001654, 0x000016AA, 0x00004AD5, 0x00000AB4, 0x0000F4BA, 0x000014B6, 0x00000A56,
|
||
0x0000B517, 0x00000D16, 0x00000E52, 0x000096AA, 0x00000D6A, 0x000165B5, 0x0000096C, 0x000014AE, 0x0000CA2E,
|
||
0x00001A2C, 0x00001D16, 0x0000AD52, 0x00001B52, 0x00000B6A, 0x0000656D, 0x0000055C, 0x0000F45D, 0x0000145A,
|
||
0x00001A2A, 0x0000DA95, 0x000016A4, 0x00001AD2, 0x00008B5A, 0x00000AB6, 0x0001455B, 0x000008B6, 0x00001456,
|
||
0x0000D52B, 0x0000152A, 0x00001694, 0x0000B6AA, 0x000015AA, 0x00000AB6, 0x000064B7, 0x000008AE, 0x0000EC57,
|
||
0x00000A56, 0x00000D2A, 0x0000CD95, 0x00000B54, 0x0000156A, 0x00008A6D, 0x0000095C, 0x000014AE, 0x00004A56,
|
||
0x00001A54, 0x0000DD2A, 0x00001AAA, 0x00000B54, 0x0000B56A, 0x000014DA, 0x0000095C, 0x000074AB, 0x0000149A,
|
||
0x0000FA4B, 0x00001652, 0x000016AA, 0x0000CAD5, 0x000005B4*/};
|
||
|
||
/* 2000 ~ 2199 */
|
||
const uint32_t solar_1_1[] = {
|
||
1997,
|
||
0x000F9C3C, 0x000F9E50, 0x000FA045, 0x000FA238, 0x000FA44C, 0x000FA641, 0x000FA836, 0x000FAA49, 0x000FAC3D,
|
||
0x000FAE52, 0x000FB047, 0x000FB23A, 0x000FB44E, 0x000FB643, 0x000FB837, 0x000FBA4A, 0x000FBC3F, 0x000FBE53,
|
||
0x000FC048, 0x000FC23C, 0x000FC450, 0x000FC645, 0x000FC839, 0x000FCA4C, 0x000FCC41, 0x000FCE36, 0x000FD04A,
|
||
0x000FD23D, 0x000FD451, 0x000FD646, 0x000FD83A, 0x000FDA4D, 0x000FDC43, 0x000FDE37, 0x000FE04B, 0x000FE23F,
|
||
0x000FE453, 0x000FE648, 0x000FE83C, 0x000FEA4F, 0x000FEC44, 0x000FEE38, 0x000FF04C, 0x000FF241, 0x000FF436,
|
||
0x000FF64A, 0x000FF83E, 0x000FFA51, 0x000FFC46, 0x000FFE3A, 0x0010004E, 0x00100242, 0x00100437, 0x0010064B,
|
||
/*0x00100841, 0x00100A53, 0x00100C48, 0x00100E3C, 0x0010104F, 0x00101244, 0x00101438, 0x0010164C, 0x00101842,
|
||
0x00101A35, 0x00101C49, 0x00101E3D, 0x00102051, 0x00102245, 0x0010243A, 0x0010264E, 0x00102843, 0x00102A37,
|
||
0x00102C4B, 0x00102E3F, 0x00103053, 0x00103247, 0x0010343B, 0x0010364F, 0x00103845, 0x00103A38, 0x00103C4C,
|
||
0x00103E42, 0x00104036, 0x00104249, 0x0010443D, 0x00104651, 0x00104846, 0x00104A3A, 0x00104C4E, 0x00104E43,
|
||
0x00105038, 0x0010524A, 0x0010543E, 0x00105652, 0x00105847, 0x00105A3B, 0x00105C4F, 0x00105E45, 0x00106039,
|
||
0x0010624C, 0x00106441, 0x00106635, 0x00106849, 0x00106A3D, 0x00106C51, 0x00106E47, 0x0010703C, 0x0010724F,
|
||
0x00107444, 0x00107638, 0x0010784C, 0x00107A3F, 0x00107C53, 0x00107E48, 0x0010803D, 0x00108250, 0x00108446,
|
||
0x0010863A, 0x0010884E, 0x00108A42, 0x00108C36, 0x00108E4A, 0x0010903E, 0x00109251, 0x00109447, 0x0010963B,
|
||
0x0010984F, 0x00109A43, 0x00109C37, 0x00109E4B, 0x0010A041, 0x0010A253, 0x0010A448, 0x0010A63D, 0x0010A851,
|
||
0x0010AA45, 0x0010AC39, 0x0010AE4D, 0x0010B042, 0x0010B236, 0x0010B44A, 0x0010B63E, 0x0010B852, 0x0010BA47,
|
||
0x0010BC3B, 0x0010BE4F, 0x0010C044, 0x0010C237, 0x0010C44B, 0x0010C641, 0x0010C854, 0x0010CA48, 0x0010CC3D,
|
||
0x0010CE50, 0x0010D045, 0x0010D239, 0x0010D44C, 0x0010D642, 0x0010D837, 0x0010DA4A, 0x0010DC3E, 0x0010DE52,
|
||
0x0010E047, 0x0010E23A, 0x0010E44E, 0x0010E643, 0x0010E838, 0x0010EA4B, 0x0010EC41, 0x0010EE54, 0x0010F049,
|
||
0x0010F23C, 0x0010F450, 0x0010F645, 0x0010F839, 0x0010FA4C, 0x0010FC42, 0x0010FE37, 0x0011004B, 0x0011023E,
|
||
0x00110452, 0x00110647, 0x0011083B, 0x00110A4E, 0x00110C43, 0x00110E38, 0x0011104C, 0x0011123F, 0x00111435,
|
||
0x00111648, 0x0011183C, 0x00111A4F, 0x00111C45, 0x00111E39, 0x0011204D, 0x00112242, 0x00112436, 0x0011264A,
|
||
0x0011283E, 0x00112A51, 0x00112C46, 0x00112E3B, 0x0011304F*/};
|
||
|
||
static uint32_t GetBitInt(uint32_t data, uint8_t length, uint8_t shift) {
|
||
return (data & (((1 << length) - 1) << shift)) >> shift;
|
||
}
|
||
|
||
// WARNING: Dates before Oct. 1582 are inaccurate
|
||
static uint16_t SolarToInt(uint16_t y, uint8_t m, uint8_t d) {
|
||
m = (m + 9) % 12;
|
||
y = y - m / 10;
|
||
return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
|
||
}
|
||
|
||
void LUNAR_SolarToLunar(struct Lunar_Date* lunar, uint16_t solar_year, uint8_t solar_month, uint8_t solar_date) {
|
||
uint8_t i, lunarM, m, d, leap, dm;
|
||
uint16_t year_index, lunarY, y, offset;
|
||
uint32_t solar_data, solar11, days;
|
||
|
||
if (solar_month < 1 || solar_month > 12 || solar_date < 1 || solar_date > 31 || (solar_year - solar_1_1[0] < 3) ||
|
||
((solar_year - solar_1_1[0]) > (sizeof(solar_1_1) / sizeof(uint32_t) - 2))) {
|
||
lunar->Year = 0;
|
||
lunar->Month = 0;
|
||
lunar->Date = 0;
|
||
lunar->IsLeap = 0;
|
||
return;
|
||
}
|
||
|
||
year_index = solar_year - solar_1_1[0];
|
||
solar_data = ((uint32_t)solar_year << 9) | ((uint32_t)solar_month << 5) | ((uint32_t)solar_date);
|
||
if (solar_1_1[year_index] > solar_data) {
|
||
year_index -= 1;
|
||
}
|
||
solar11 = solar_1_1[year_index];
|
||
y = GetBitInt(solar11, 12, 9);
|
||
m = GetBitInt(solar11, 4, 5);
|
||
d = GetBitInt(solar11, 5, 0);
|
||
offset = SolarToInt(solar_year, solar_month, solar_date) - SolarToInt(y, m, d);
|
||
|
||
days = lunar_month_days[year_index];
|
||
leap = GetBitInt(days, 4, 13);
|
||
|
||
lunarY = year_index + solar_1_1[0];
|
||
lunarM = 1;
|
||
offset += 1;
|
||
for (i = 0; i < 13; i++) {
|
||
if (GetBitInt(days, 1, 12 - i) == 1) {
|
||
dm = 30;
|
||
} else {
|
||
dm = 29;
|
||
}
|
||
if (offset > dm) {
|
||
lunarM += 1;
|
||
offset -= dm;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
lunar->IsLeap = 0;
|
||
if (leap != 0 && lunarM > leap) {
|
||
if (lunarM == leap + 1) {
|
||
lunar->IsLeap = 1;
|
||
}
|
||
lunarM -= 1;
|
||
}
|
||
lunar->Month = lunarM;
|
||
lunar->Date = offset;
|
||
lunar->Year = lunarY;
|
||
}
|
||
|
||
uint8_t LUNAR_GetZodiac(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||
|
||
uint8_t LUNAR_GetStem(const struct Lunar_Date* lunar) { return lunar->Year % 10; }
|
||
|
||
uint8_t LUNAR_GetBranch(const struct Lunar_Date* lunar) { return lunar->Year % 12; }
|
||
|
||
/*********************************************************************************************************
|
||
** 以下为24节气计算相关程序
|
||
**------------------------------------------------------------------------------------------------------
|
||
********************************************************************************************************/
|
||
|
||
/*
|
||
每年24节气标志表
|
||
有兴趣的朋友可按照上面给的原理添加其它年份的表格
|
||
不是很清楚的朋友可给我发EMAIL
|
||
*/
|
||
static const uint8_t YearMonthBit[160] = {
|
||
0x4E, 0xA6, 0x99, // 2000
|
||
0x9C, 0xA2, 0x98, // 2001
|
||
0x80, 0x00, 0x18, // 2002
|
||
0x00, 0x10, 0x24, // 2003
|
||
0x4E, 0xA6, 0x99, // 2004
|
||
0x9C, 0xA2, 0x98, // 2005
|
||
0x80, 0x82, 0x18, // 2006
|
||
0x00, 0x10, 0x24, // 2007
|
||
0x4E, 0xA6, 0xD9, // 2008
|
||
0x9E, 0xA2, 0x98, // 2009
|
||
|
||
0x80, 0x82, 0x18, // 2010
|
||
0x00, 0x10, 0x04, // 2011
|
||
0x4E, 0xE6, 0xD9, // 2012
|
||
0x9E, 0xA6, 0xA8, // 2013
|
||
0x80, 0x82, 0x18, // 2014
|
||
0x00, 0x10, 0x00, // 2015
|
||
0x0F, 0xE6, 0xD9, // 2016
|
||
0xBE, 0xA6, 0x98, // 2017
|
||
0x88, 0x82, 0x18, // 2018
|
||
0x80, 0x00, 0x00, // 2019
|
||
|
||
0x0F, 0xEF, 0xD9, // 2020
|
||
0xBE, 0xA6, 0x99, // 2021
|
||
0x8C, 0x82, 0x98, // 2022
|
||
0x80, 0x00, 0x00, // 2023
|
||
0x0F, 0xEF, 0xDB, // 2024
|
||
0xBE, 0xA6, 0x99, // 2025
|
||
0x9C, 0xA2, 0x98, // 2026
|
||
0x80, 0x00, 0x18, // 2027
|
||
0x0F, 0xEF, 0xDB, // 2028
|
||
0xBE, 0xA6, 0x99, // 2029
|
||
|
||
0x9C, 0xA2, 0x98, // 2030
|
||
0x80, 0x00, 0x18, // 2031
|
||
0x0F, 0xEF, 0xDB, // 2032
|
||
0xBE, 0xA2, 0x99, // 2033
|
||
0x8C, 0xA0, 0x98, // 2034
|
||
0x80, 0x82, 0x18, // 2035
|
||
0x0B, 0xEF, 0xDB, // 2036
|
||
0xBE, 0xA6, 0x99, // 2037
|
||
0x8C, 0xA2, 0x98, // 2038
|
||
0x80, 0x82, 0x18, // 2039
|
||
|
||
0x0F, 0xEF, 0xDB, // 2040
|
||
0xBE, 0xE6, 0xD9, // 2041
|
||
0x9E, 0xA2, 0x98, // 2042
|
||
0x80, 0x82, 0x18, // 2043
|
||
0x0F, 0xEF, 0xFB, // 2044
|
||
0xBF, 0xE6, 0xD9, // 2045
|
||
0x9E, 0xA6, 0x98, // 2046
|
||
0x80, 0x82, 0x18, // 2047
|
||
0x0F, 0xFF, 0xFF, // 2048
|
||
0xFC, 0xEF, 0xD9, // 2049
|
||
0xBE, 0xA6, 0x18, // 2050
|
||
};
|
||
static const uint8_t days[24] = {
|
||
6, 20, 4, 19, 6, 21, // 一月到三月 的节气基本日期
|
||
5, 20, 6, 21, 6, 21, // 四月到六月 的节气基本日期
|
||
7, 23, 8, 23, 8, 23, // 七月到九月 的节气基本日期
|
||
8, 24, 8, 22, 7, 22, // 十月到十二月的节气基本日期
|
||
};
|
||
/*立春、雨水、惊蛰、春分、清明、谷雨、立夏、小满、芒种、夏至、小暑、大暑、立秋、处暑、白露、秋分、寒露、霜降、立冬、小雪、大雪、冬至、小寒、大寒
|
||
*
|
||
*/
|
||
const char JieQiStr[24][7] = {
|
||
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
|
||
"小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至",
|
||
};
|
||
const uint8_t MonthDayMax[12] = {
|
||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
|
||
};
|
||
|
||
/*********************************************************************************************************
|
||
** 函数名称:GetJieQi
|
||
** 功能描述:输入公历日期得到本月24节气日期 day<15返回上半月节气,反之返回下半月
|
||
** 如:GetJieQiStr(2007,02,08,str) 返回str[0]=4
|
||
** 输 入: year 公历年
|
||
** month 公历月
|
||
** day 公历日
|
||
** str 储存对应本月节气日期地址 1Byte
|
||
** 输 出: 1 成功
|
||
** 0 失败
|
||
** 作 者: 赖皮 ★〓个人原创〓★
|
||
** 日 期: 2007年02月08日
|
||
**-------------------------------------------------------------------------------------------------------
|
||
** 修改人:
|
||
** 日 期:
|
||
**------------------------------------------------------------------------------------------------------
|
||
********************************************************************************************************/
|
||
uint8_t GetJieQi(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* JQdate) {
|
||
uint8_t bak1, value, JQ;
|
||
|
||
if ((myear < 2000) || (myear > 2050)) return 0;
|
||
if ((mmonth == 0) || (mmonth > 12)) return 0;
|
||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||
if (mday >= 15) JQ++; // 判断是否是上半月
|
||
|
||
bak1 = YearMonthBit[(myear - 2000) * 3 + JQ / 8]; // 获得节气日期相对值所在字节
|
||
value = ((bak1 << (JQ % 8)) & 0x80); // 获得节气日期相对值状态
|
||
|
||
*JQdate = days[JQ];
|
||
if (value != 0) {
|
||
// 判断年份,以决定节气相对值1代表1,还是-1。
|
||
if ((JQ == 1 || JQ == 11 || JQ == 18 || JQ == 21) && myear < 2044)
|
||
(*JQdate)++;
|
||
else
|
||
(*JQdate)--;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/*********************************************************************************************************
|
||
** 函数名称:GetJieQiStr位置
|
||
** 如:GetJieQiStr(2007,02,08,day) 返回str="离雨水还有11天" day式距离几天
|
||
** 输 入: year 公历年
|
||
** month 公历月
|
||
** day 公历日
|
||
** str 储存24节气字符串地址 15Byte
|
||
** 输 出: 1 成功
|
||
** 0xFF 失败
|
||
** 作 者: 赖皮 ★〓个人原创〓★
|
||
** 日 期: 2007年02月08日
|
||
**-------------------------------------------------------------------------------------------------------
|
||
** 修改人:
|
||
** 日 期:
|
||
**------------------------------------------------------------------------------------------------------
|
||
********************************************************************************************************/
|
||
uint8_t GetJieQiStr(uint16_t myear, uint8_t mmonth, uint8_t mday, uint8_t* day) {
|
||
uint8_t JQdate, JQ, MaxDay;
|
||
|
||
if (GetJieQi(myear, mmonth, mday, &JQdate) == 0) return 0xFF;
|
||
|
||
JQ = (mmonth - 1) * 2; // 获得节气顺序标号(0~23
|
||
|
||
if (mday >= 15) JQ++; // 判断是否是上半月
|
||
|
||
if (mday == JQdate) // 今天正是一个节气日
|
||
{
|
||
*day = 0;
|
||
return JQ;
|
||
}
|
||
// 今天不是一个节气日
|
||
// StrCopy(str, (uint8_t *)"离小寒还有??天", 15);
|
||
|
||
if (mday < JQdate) // 如果今天日期小于本月的节气日期
|
||
{
|
||
mday = JQdate - mday;
|
||
} else // 如果今天日期大于本月的节气日期
|
||
{
|
||
JQ++;
|
||
|
||
if (mday < 15) {
|
||
GetJieQi(myear, mmonth, 15, &JQdate);
|
||
mday = JQdate - mday;
|
||
} else // 翻月
|
||
{
|
||
MaxDay = MonthDayMax[mmonth - 1];
|
||
if (mmonth == 2) // 润月问题
|
||
{
|
||
if ((myear % 4 == 0) && ((myear % 100 != 0) || (myear % 400 == 0))) MaxDay++;
|
||
}
|
||
if (++mmonth == 13) mmonth = 1;
|
||
GetJieQi(myear, mmonth, 1, &JQdate);
|
||
mday = MaxDay - mday + JQdate;
|
||
}
|
||
}
|
||
*day = mday;
|
||
return JQ;
|
||
}
|
||
|
||
uint32_t SEC_PER_YR[2] = {31536000, 31622400}; // 闰年和非闰年的秒数
|
||
uint32_t SEC_PER_MT[2][12] = {
|
||
{2678400, 2419200, 2678400, 2592000, 2678400, 2592000, 2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||
{2678400, 2505600, 2678400, 2592000, 2678400, 2592000, 2678400, 2678400, 2592000, 2678400, 2592000, 2678400},
|
||
};
|
||
#define SECOND_OF_DAY 86400 // 一天多少秒
|
||
|
||
/**
|
||
* @Name : static int is_leap(int yr)
|
||
* @Description: 判断是否为闰年
|
||
* "非整百年份:能被4整除的是闰年。"
|
||
* "整百年份:能被400整除的是闰年。"
|
||
* @In : 待机算的年份
|
||
* @Out : 1:是闰年 0:非闰年
|
||
* @Author : Denis
|
||
*/
|
||
int is_leap(int yr) {
|
||
if (0 == (yr % 100))
|
||
return (yr % 400 == 0) ? 1 : 0;
|
||
else
|
||
return (yr % 4 == 0) ? 1 : 0;
|
||
}
|
||
|
||
/**
|
||
* @Name : static unsigned char day_of_week_get(unsigned char month, unsigned char day,
|
||
unsigned short year)
|
||
* @Description: 根据输入的年月日计算当天为星期几
|
||
* @In : 年、月、日
|
||
* @Out : 星期几
|
||
* @Author : Denis
|
||
*/
|
||
unsigned char day_of_week_get(unsigned char month, unsigned char day, unsigned short year) {
|
||
/* Month should be a number 0 to 11, Day should be a number 1 to 31 */
|
||
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
|
||
year -= (uint8_t)(month < 3);
|
||
return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
|
||
}
|
||
|
||
void transformTime(uint32_t unix_time, struct devtm* result) {
|
||
int leapyr = 0;
|
||
uint32_t ltime = unix_time;
|
||
|
||
memset(result, 0, sizeof(struct devtm));
|
||
result->tm_year = EPOCH_YR;
|
||
|
||
while (1) {
|
||
if (ltime < SEC_PER_YR[is_leap(result->tm_year)]) {
|
||
break;
|
||
}
|
||
ltime -= SEC_PER_YR[is_leap(result->tm_year)];
|
||
++(result->tm_year);
|
||
}
|
||
|
||
leapyr = is_leap(result->tm_year);
|
||
|
||
while (1) {
|
||
if (ltime < SEC_PER_MT[leapyr][result->tm_mon]) break;
|
||
ltime -= SEC_PER_MT[leapyr][result->tm_mon];
|
||
++(result->tm_mon);
|
||
}
|
||
|
||
result->tm_mday = ltime / SEC_PER_DY;
|
||
++(result->tm_mday);
|
||
ltime = ltime % SEC_PER_DY;
|
||
|
||
result->tm_hour = ltime / SEC_PER_HR;
|
||
ltime = ltime % SEC_PER_HR;
|
||
|
||
result->tm_min = ltime / 60;
|
||
result->tm_sec = ltime % 60;
|
||
|
||
result->tm_wday = day_of_week_get(result->tm_mon + 1, result->tm_mday, result->tm_year);
|
||
|
||
/*
|
||
* The number of years since YEAR0"
|
||
*/
|
||
result->tm_year -= YEAR0;
|
||
}
|
||
|
||
uint8_t map[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||
|
||
/*
|
||
获取一个月最后一天值
|
||
*/
|
||
uint8_t get_last_day(uint16_t year, uint8_t month) {
|
||
if (month % 12 == 1) {
|
||
return map[month % 12] + is_leap(year);
|
||
}
|
||
return map[month % 12];
|
||
}
|
||
|
||
/*
|
||
获取一个月第一天星期值
|
||
*/
|
||
uint8_t get_first_day_week(uint16_t year, uint8_t month) { return day_of_week_get(month, 1, year); }
|
||
|
||
// 时间结构体转时间戳
|
||
uint32_t transformTimeStruct(struct devtm* result) {
|
||
uint32_t Cyear = 0;
|
||
for (uint16_t i = 1970; i < result->tm_year; i++) {
|
||
if (is_leap(i) == 1) Cyear++;
|
||
}
|
||
|
||
uint32_t CountDay =
|
||
Cyear * (uint32_t)366 + (uint32_t)(result->tm_year - 1970 - Cyear) * (uint32_t)365 + result->tm_mday - 1;
|
||
for (uint8_t i = 0; i < result->tm_mon - 1; i++) {
|
||
CountDay += get_last_day(result->tm_year, i);
|
||
}
|
||
|
||
return (CountDay * SECOND_OF_DAY + (uint32_t)result->tm_sec + (uint32_t)result->tm_min * 60 +
|
||
(uint32_t)result->tm_hour * 3600);
|
||
}
|
||
|
||
uint8_t thisMonthMaxDays(uint8_t year, uint8_t month) {
|
||
if (year % 4 == 0 && month == 2)
|
||
return MonthDayMax[month - 1] + 1;
|
||
else
|
||
return MonthDayMax[month - 1];
|
||
}
|