#include "billing.h"
|
#include "sundry.h"
|
#include "string.h"
|
#include "system_parameter.h"
|
#include "main.h"
|
#include "system_log.h"
|
|
double yesterday_cumulate_sc = 0;
|
uint8_t no_use_gas_days_cnt = 0;
|
|
ErrorStatus_STM32 have_gprs_send_flag = ERROR_1;
|
uint8_t no_gprs_days_cnt = 0;
|
|
BILLING_REAL_PARA_T billing_real_para_g = {
|
.price_type_mode_now = 0,
|
.price_now = 10000, // ĬÈϵ¥¼Û ·Å´ó10000±¶
|
.balance_now = 10.0f // ĬÈÏÓà¶î
|
};
|
|
TYPE_CHECK_SIZE(BILLING_ALARM_CFG_T,39);//ºË²é½á¹¹Ìå´óС
|
BILLING_ALARM_CFG_T billing_alarm_cfg_g = {
|
.balance_small_value = {10000, 5000, 0, -5000, -10000}, //·Å´ó100±¶
|
.cumulate_flow_value = 0,
|
.no_gprs_days = 5,
|
.no_use_gas_days = 7};
|
|
TYPE_CHECK_SIZE(LADDER_PRICE_CFG_PARA_T,111);//ºË²é½á¹¹Ìå´óС
|
LADDER_PRICE_CFG_PARA_T ladder_price_cfg_para_true_g = {
|
.price_ver = LADDER_PRICE_DEFAULT_VER,
|
.normal_price_now = 10000,
|
.set_price_type_mode = SPM_NORMAL,
|
.period_state = PPS_CYCLICALLY,
|
.period_start_time = {0x22, 0x11, 0x01, 0, 0, 0},
|
.period_unit = PPU_DAY,
|
.period_duration = 30,
|
.set_ladder_price = {35000, 40000, 50000, 60000, 70000},
|
.set_ladder_cumulate = {500, 1000, 1500, 2000, 2500},
|
.set_time_price[0] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[1] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[2] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[3] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[4] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.time_unit = PPU_DAY,
|
.price_scheme_start_time = {0x22, 0x11, 0x01, 0, 0, 0},
|
};
|
LADDER_PRICE_CFG_PARA_T ladder_price_cfg_para_new_g = {
|
.price_ver = LADDER_PRICE_DEFAULT_VER,
|
.normal_price_now = 10000,
|
.set_price_type_mode = SPM_NORMAL,
|
.period_state = PPS_CYCLICALLY,
|
.period_start_time = {0x22, 0x11, 0x01, 0, 0, 0},
|
.period_unit = PPU_DAY,
|
.period_duration = 30,
|
.set_ladder_price = {35000, 40000, 50000, 60000, 70000},
|
.set_ladder_cumulate = {500, 1000, 1500, 2000, 2500},
|
.set_time_price[0] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[1] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[2] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[3] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.set_time_price[4] = {.time = {0x22, 0x11, 0x01, 0, 0, 0}, .duration = 0},
|
.time_unit = PPU_DAY,
|
.price_scheme_start_time = {0x22, 0x11, 0x01, 0, 0, 0},
|
};
|
|
/*¼ÆÁ¿Êý¾Ý״̬/±¨¾¯×Ö´¦Àí*/
|
void State_Alarm_Bytes_BillingDataHandler(double balance, BILLING_ALARM_CFG_T *billing_alarm_cfg_p)
|
{
|
if (balance > (billing_alarm_cfg_p->balance_small_value[0] * 0.01f)) // 100 ~ ÕýÎÞÇî
|
{
|
__SYS_STATUS_BYTES_STATUS(balance_small_1, RESET, AV_BALANCE_1);
|
__SYS_STATUS_BYTES_STATUS(balance_small_2, RESET, AV_BALANCE_2);
|
__SYS_STATUS_BYTES_STATUS(balance_small_3, RESET, AV_BALANCE_3);
|
__SYS_STATUS_BYTES_STATUS(balance_small_4, RESET, AV_BALANCE_4);
|
}
|
else if (balance > (billing_alarm_cfg_p->balance_small_value[1] * 0.01f)) // 50~100
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_1);
|
else if (balance > (billing_alarm_cfg_p->balance_small_value[2] * 0.01f)) // 0~50
|
{
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_1);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_2);
|
}
|
else if (balance > (billing_alarm_cfg_p->balance_small_value[3] * 0.01f)) // -50~0
|
{
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_1);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_2);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_3);
|
}
|
else // if (balance > (billing_alarm_cfg_p->balance_small_value[4] * 0.01f)) //-100 ~ -50
|
{
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_1);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_2);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_3);
|
__SYS_STATUS_ALARM_BYTES_SET(balance_small_4);
|
}
|
// else // ¸ºÎÞÇî ~ -100
|
// {
|
// __SYS_STATUS_ALARM_BYTES_SET(balance_small_1);
|
// __SYS_STATUS_ALARM_BYTES_SET(balance_small_2);
|
// __SYS_STATUS_ALARM_BYTES_SET(balance_small_3);
|
// __SYS_STATUS_ALARM_BYTES_SET(balance_small_4);
|
// __SYS_STATUS_ALARM_BYTES_SET(balance_small_5);
|
// }
|
/*ÀÛ¼ÆÆøÁ¿µ½*/
|
if (billing_alarm_cfg_p->cumulate_flow_value != 0)
|
{
|
if (sys_realtime_data_g.measure_para_s.forward_cumulate_sc >= billing_alarm_cfg_p->cumulate_flow_value)
|
{
|
// Sys_Log_E2pParaWrite(cumulate_close_valve_flag,AV_SET_CUMULATE);
|
__SYS_STATUS_ALARM_BYTES_SET(set_cumulate_up_to);
|
}
|
}
|
}
|
/*ÎÞÓÃÆø/Éϱ¨Êý¾Ý״̬/±¨¾¯×Ö´¦Àí*/
|
void State_Alarm_Bytes_NoGpra_NoGasHandler(BILLING_ALARM_CFG_T *billing_alarm_cfg_p)
|
{
|
if (DAILY_ZERO) // 0µã0·Ö0Ãë
|
{
|
/*ÎÞÓÃÆøÌìÊýµ½*/
|
if (billing_alarm_cfg_p->no_use_gas_days)
|
{
|
if (sys_realtime_data_g.measure_para_s.forward_cumulate_sc > yesterday_cumulate_sc)
|
{
|
yesterday_cumulate_sc = sys_realtime_data_g.measure_para_s.forward_cumulate_sc;
|
no_use_gas_days_cnt = 0;
|
__SYS_STATUS_BYTES_STATUS(no_use_gas_date_up_to, RESET, AV_NO_USE_GAS);
|
}
|
else
|
{
|
if (++no_use_gas_days_cnt >= billing_alarm_cfg_p->no_use_gas_days)
|
__SYS_STATUS_ALARM_BYTES_SET(no_use_gas_date_up_to);
|
}
|
}
|
/*ÎÞÉϱ¨ÌìÊýµ½*/
|
if (billing_alarm_cfg_p->no_gprs_days)
|
{
|
if (have_gprs_send_flag == SUCCESS_0)
|
{
|
have_gprs_send_flag = ERROR_1;
|
no_gprs_days_cnt = 0;
|
__SYS_STATUS_BYTES_STATUS(no_gprs_date_up_to, RESET, AV_NO_GPRS);
|
}
|
else
|
{
|
if (++no_gprs_days_cnt >= billing_alarm_cfg_p->no_gprs_days)
|
__SYS_STATUS_ALARM_BYTES_SET(no_gprs_date_up_to);
|
}
|
}
|
}
|
}
|
/*ʵʱ¼Æ·Ñ³ÌÐò
|
* single_flow_sum£ºµ¥´ÎµÄÁ÷Á¿ºÍ
|
*/
|
void Billing_RealTimeProcess(BILLING_MODE_T start_flag, __IO double single_flow_sum, LADDER_PRICE_CFG_PARA_T *ladder_cfg_real_p, BILLING_REAL_PARA_T *billing_para_p)
|
{
|
if ((start_flag == BM_DEVICE || (start_flag == BM_PLATFORM && __SYS_STATUS_BYTES_GET(virtual_billing) == SET)) && single_flow_sum > 0)
|
{
|
double price_double = 0;
|
double single_use_money = 0;
|
/*²ÎÊýÅäÖÃ*/
|
GasCumulant_Ladder_PeriodCfg(ladder_cfg_real_p, &ladder_price_cfg_para_new_g, &calendar_g);
|
/*ËãÇ®*/
|
if (ladder_cfg_real_p->set_price_type_mode == SPM_NORMAL) // ÆÕͨ¼Æ·Ñ
|
{
|
if(start_flag == BM_DEVICE)
|
billing_para_p->price_type_mode_now = BPM_NORMAL;
|
billing_para_p->price_now = ladder_cfg_real_p->normal_price_now;
|
price_double = ladder_cfg_real_p->normal_price_now * 0.0001f;
|
single_use_money = single_flow_sum * price_double;
|
billing_para_p->residual_gas_now = billing_para_p->balance_now / price_double;
|
}
|
else if (ladder_cfg_real_p->set_price_type_mode == SPM_LADDER) // °´ÆøÁ¿½×ÌݼƷÑ
|
{
|
single_use_money = GasCumulant_Ladder_PeriodCalculation(start_flag,single_flow_sum, ladder_cfg_real_p, billing_para_p);
|
}
|
else if (ladder_cfg_real_p->set_price_type_mode == SPM_TIME) // °´Ê±¼ä¶Î¼Æ·Ñ
|
{
|
}
|
billing_para_p->use_money_sum += single_use_money; // µÃ³öÀÛ¼ÆÊ¹Óýð¶î
|
billing_para_p->balance_now -= single_use_money; // µÃ³öÓà¶î
|
/*¼Æ·Ñ/ÓÃÆøÏà¹Ø±¨¾¯ÅжÏ*/
|
State_Alarm_Bytes_BillingDataHandler(billing_para_p->balance_now, &billing_alarm_cfg_g);
|
}
|
State_Alarm_Bytes_NoGpra_NoGasHandler(&billing_alarm_cfg_g);
|
|
if(billing_para_p->balance_now > (billing_alarm_cfg_g.balance_small_value[0] * 0.01f))
|
{
|
/*½öÓà¶î²úÉúµÄÇ¿ÖÆÐÔ±¨¾¯¹Ø·§£¬µ±Óà¶î³ä×ãʱ×Ô¶¯½âËø*/
|
if(op_cl_valve_cause_id >= 0x90 && op_cl_valve_cause_id <= 0x94 && __SYS_STATUS_BYTES_GET(valve_state) == VALVE_CL)
|
{
|
if(__SYS_STATUS_BYTES_GET(valve_lock) == SET)
|
{
|
__VALVE_WORK_TYPE_SET(VWT_UNLOCK); // ½âËø£¨ÓÃÓÚ´æ´¢¼Ç¼£©
|
__SYS_STATUS_BYTES_STATUS(valve_lock, RESET, AV_NORMAL); // ½âËø£¨ÓÃÓÚÕæÕý¿ØÖÆ£©
|
}
|
}
|
}
|
}
|
/*ÆøÌåÀÛ»ýÁ¿-½×ÌݼÆËã*/
|
double GasCumulant_Ladder_PeriodCalculation(BILLING_MODE_T mode_flag,double single_flow_sum,
|
LADDER_PRICE_CFG_PARA_T *ladder_cfg_p_p, BILLING_REAL_PARA_T *billing_para_p_p)
|
{
|
double price_double = 0; // µ¥¼Û
|
double single_use_money = 0; // µ¥´ÎµÄʹÓýð¶î
|
double ladder_cumulate_sc_before = billing_para_p_p->ladder_cumulate_sc;
|
billing_para_p_p->ladder_cumulate_sc += single_flow_sum; // ½×ÌÝÖÜÆÚÄÚµÄÀÛ»ýÁ¿
|
if (billing_para_p_p->ladder_cumulate_sc <= ladder_cfg_p_p->set_ladder_cumulate[0]) // 0~100
|
{
|
if(mode_flag == BM_DEVICE)
|
billing_para_p_p->price_type_mode_now = BPM_LADDER_1;
|
/*¼ÆËãµ¥´ÎµÄʹÓýð¶î*/
|
billing_para_p_p->price_now = ladder_cfg_p_p->set_ladder_price[0];
|
price_double = ladder_cfg_p_p->set_ladder_price[0] * 0.0001f;
|
single_use_money = single_flow_sum * price_double;
|
}
|
else if (billing_para_p_p->ladder_cumulate_sc <= ladder_cfg_p_p->set_ladder_cumulate[1]) // 100~200
|
{
|
|
price_double = ladder_cfg_p_p->set_ladder_price[1] * 0.0001f;
|
if (ladder_cumulate_sc_before < ladder_cfg_p_p->set_ladder_cumulate[0]) // ÉÏ´ÎÊý¾ÝСÓÚÁÙ½çÖµ£¬±¾´ÎÊý¾ÝÈ´´óÓÚÁÙ½çÖµ
|
{
|
if(mode_flag == BM_DEVICE)
|
billing_para_p_p->price_type_mode_now = BPM_LADDER_2;
|
single_use_money = (ladder_cfg_p_p->set_ladder_cumulate[0] - ladder_cumulate_sc_before) * (ladder_cfg_p_p->set_ladder_price[0] * 0.0001f) +
|
(billing_para_p_p->ladder_cumulate_sc - ladder_cfg_p_p->set_ladder_cumulate[0]) * price_double;
|
billing_para_p_p->price_now = ladder_cfg_p_p->set_ladder_price[1];
|
}
|
else
|
single_use_money = single_flow_sum * price_double;
|
}
|
else if (billing_para_p_p->ladder_cumulate_sc <= ladder_cfg_p_p->set_ladder_cumulate[2]) // 200~300
|
{
|
price_double = ladder_cfg_p_p->set_ladder_price[2] * 0.0001f;
|
if (ladder_cumulate_sc_before < ladder_cfg_p_p->set_ladder_cumulate[1]) // ÉÏ´ÎÊý¾ÝСÓÚÁÙ½çÖµ£¬±¾´ÎÊý¾ÝÈ´´óÓÚÁÙ½çÖµ
|
{
|
if(mode_flag == BM_DEVICE)
|
billing_para_p_p->price_type_mode_now = BPM_LADDER_3;
|
single_use_money = (ladder_cfg_p_p->set_ladder_cumulate[1] - ladder_cumulate_sc_before) * (ladder_cfg_p_p->set_ladder_price[1] * 0.0001f) +
|
(billing_para_p_p->ladder_cumulate_sc - ladder_cfg_p_p->set_ladder_cumulate[1]) * price_double;
|
billing_para_p_p->price_now = ladder_cfg_p_p->set_ladder_price[2];
|
}
|
else
|
single_use_money = single_flow_sum * price_double;
|
}
|
else if (billing_para_p_p->ladder_cumulate_sc <= ladder_cfg_p_p->set_ladder_cumulate[3]) // 300~400
|
{
|
price_double = ladder_cfg_p_p->set_ladder_price[3] * 0.0001f;
|
if (ladder_cumulate_sc_before < ladder_cfg_p_p->set_ladder_cumulate[2]) // ÉÏ´ÎÊý¾ÝСÓÚÁÙ½çÖµ£¬±¾´ÎÊý¾ÝÈ´´óÓÚÁÙ½çÖµ
|
{
|
if(mode_flag == BM_DEVICE)
|
billing_para_p_p->price_type_mode_now = BPM_LADDER_4;
|
single_use_money = (ladder_cfg_p_p->set_ladder_cumulate[2] - ladder_cumulate_sc_before) * (ladder_cfg_p_p->set_ladder_price[2] * 0.0001f) +
|
(billing_para_p_p->ladder_cumulate_sc - ladder_cfg_p_p->set_ladder_cumulate[2]) * price_double;
|
billing_para_p_p->price_now = ladder_cfg_p_p->set_ladder_price[3];
|
}
|
else
|
single_use_money = single_flow_sum * price_double;
|
}
|
else // >400
|
{
|
price_double = ladder_cfg_p_p->set_ladder_price[4] * 0.0001f;
|
if (ladder_cumulate_sc_before < ladder_cfg_p_p->set_ladder_cumulate[3]) // ÉÏ´ÎÊý¾ÝСÓÚÁÙ½çÖµ£¬±¾´ÎÊý¾ÝÈ´´óÓÚÁÙ½çÖµ
|
{
|
if(mode_flag == BM_DEVICE)
|
billing_para_p_p->price_type_mode_now = BPM_LADDER_5;
|
single_use_money = (ladder_cfg_p_p->set_ladder_cumulate[3] - ladder_cumulate_sc_before) * (ladder_cfg_p_p->set_ladder_price[3] * 0.0001f) +
|
(billing_para_p_p->ladder_cumulate_sc - ladder_cfg_p_p->set_ladder_cumulate[3]) * price_double;
|
billing_para_p_p->price_now = ladder_cfg_p_p->set_ladder_price[4];
|
}
|
else
|
single_use_money = single_flow_sum * price_double;
|
}
|
return single_use_money;
|
}
|
/*ÆøÌåÀÛ»ýÁ¿-½×ÌÝÖÜÆÚÅäÖã¨ÖÜÆÚʱ¼äµ½½×ÌÝÀÛ»ýÁ¿ÇåÁ㣩*/
|
void GasCumulant_Ladder_PeriodCfg(LADDER_PRICE_CFG_PARA_T *ladder_cfg_old, LADDER_PRICE_CFG_PARA_T *ladder_cfg_new, __IO RTC_TimeDateTypeDef *calendar)
|
{
|
static uint8_t period_flag = 0; // ÖÜÆÚÊ״αê־λ
|
static uint8_t next_period_start_time[6] = {0}; // ÏÂÒ»´ÎµÄÖÜÆÚ¿ªÊ¼Ê±¼ä
|
uint8_t real_time[6] = {calendar->Year & 0xFF, calendar->Month, calendar->Date, calendar->Hour, calendar->Minute, calendar->Second}; // µ±Ç°Ê±¼ä
|
/*ÐÂÀϰ汾²»Í¬ÇÒеļ۸ñ·½°¸ÉúЧʱ¼äµ½*/
|
if ((ladder_cfg_old->price_ver != ladder_cfg_new->price_ver) &&
|
Datecmp(ladder_cfg_new->price_scheme_start_time, real_time) <= 0) // м۸ñ·½°¸ÉúЧʱ¼ä <= µ±Ç°Ê±¼ä£¨Ð¼۸ñʱ¼äµ½£©
|
{
|
memcpy(ladder_cfg_old, ladder_cfg_new, sizeof(LADDER_PRICE_CFG_PARA_T)); // ¼Û¸ñ·½°¸Ìæ»»
|
period_flag = 0;
|
}
|
if (ladder_cfg_old->set_price_type_mode == SPM_LADDER) // Èç¹ûµ±Ç°Êǽ×ÌݼƷÑ
|
{
|
if (period_flag == 0 && Datecmp(ladder_cfg_old->period_start_time, real_time) <= 0) // Ê״ε½´ïÖÜÆÚʱ¼ä
|
{
|
billing_real_para_g.ladder_cumulate_sc = 0;
|
period_flag = 1;
|
memcpy(next_period_start_time, ladder_cfg_old->period_start_time, sizeof(next_period_start_time));
|
StartTime_NextCalculation(ladder_cfg_old->period_unit, ladder_cfg_old->period_duration, next_period_start_time);
|
}
|
else if (period_flag)
|
{
|
if (Datecmp(next_period_start_time, real_time) <= 0)
|
{
|
if (ladder_cfg_old->period_state == PPS_CYCLICALLY) // Ñ»·Ö´ÐÐ
|
StartTime_NextCalculation(ladder_cfg_old->period_unit, ladder_cfg_old->period_duration, next_period_start_time);
|
else if (ladder_cfg_old->period_state == PPS_ONLY_ONE) // Ö»Ö´ÐÐÒ»´Î
|
ladder_cfg_old->set_price_type_mode = SPM_NORMAL;
|
billing_real_para_g.ladder_cumulate_sc = 0;
|
}
|
}
|
}
|
}
|
/*¼ÆËãÏ´οªÊ¼Ê±¼ä*/
|
void StartTime_NextCalculation(PRICE_PERIOD_UNIT_T price_unit, uint16_t time_duration, uint8_t *pNext_time)
|
{
|
uint8_t year_h, month_h, day_h, hour_h;
|
uint8_t temp_quarter = 0;
|
switch (price_unit)
|
{
|
case PPU_HOUR:
|
hour_h = BCD_2_HEX_U8(pNext_time[3]) + time_duration;
|
day_h = hour_h / 24;
|
pNext_time[3] = HEX_2_BCD_U8(hour_h % 24);
|
if (day_h)
|
Add_days_CalculateYearMonTHDay(&pNext_time[0], &pNext_time[1], &pNext_time[2], day_h);
|
break;
|
case PPU_DAY:
|
Add_days_CalculateYearMonTHDay(&pNext_time[0], &pNext_time[1], &pNext_time[2], time_duration);
|
break;
|
case PPU_MONTH:
|
month_h = BCD_2_HEX_U8(pNext_time[1]) + time_duration;
|
year_h = BCD_2_HEX_U8(pNext_time[0]);
|
while (month_h > 12)
|
{
|
month_h -= 12;
|
year_h++;
|
}
|
pNext_time[0] = HEX_2_BCD_U8(year_h);
|
pNext_time[1] = HEX_2_BCD_U8(month_h);
|
break;
|
case PPU_QUARTER:
|
year_h = BCD_2_HEX_U8(pNext_time[0]);
|
month_h = BCD_2_HEX_U8(pNext_time[1]);
|
temp_quarter = (month_h - 1) / 3; // 1~3Ϊ1 4~6Ϊ2 7~9Ϊ3 10~12Ϊ4
|
temp_quarter += time_duration;
|
while (temp_quarter > 3)
|
{
|
temp_quarter -= 4;
|
year_h++;
|
}
|
month_h = temp_quarter * 3 + 1;
|
pNext_time[0] = HEX_2_BCD_U8(year_h);
|
pNext_time[1] = HEX_2_BCD_U8(month_h);
|
pNext_time[2] = 1;
|
pNext_time[3] = 0;
|
pNext_time[4] = 0;
|
pNext_time[5] = 0;
|
break;
|
default:
|
break;
|
}
|
}
|
/******************************************
|
* func: Add_days_CalculateYearMonTHDay
|
* desc: ¼ÆËãijÄêijÔÂijÌìÔö¼ÓЩÐíÌìÊýºó£¬ÎªÄ³ÄêijÔÂijÌì
|
* input: pYear_bcd Äê·Ýbcd
|
* pMonth_bcd Ô·Ýbcd
|
* pDay_bcd Ììbcd
|
* add_days Ôö¼ÓµÄÌìÊý
|
* output: *pYear_bcd ¼ÆËãµÄ½á¹ûÄê·Ýbcd
|
* *pMonth_bcd ¼ÆËãµÄ½á¹ûÔ·Ýbcd
|
* *pDay_bcd ¼ÆËãµÄ½á¹ûÌìbcd
|
* return: none
|
* bug: ¸Ãº¯ÊýÌí¼ÓµÄÌìÊý²»ÄÜ¿äÁ½ÄêÒÔÉÏ£¬·ñÔò»á³ö´í¡£È磺¿ÉÒÔ´Ó2016ÄêÌí¼ÓÌìÊýµ½2017Ä꣬µ«Êǵ½2018ÄêÒÔÉÏ»á³ö´í
|
*****************************************/
|
void Add_days_CalculateYearMonTHDay(uint8_t *pYear_bcd, uint8_t *pMonth_bcd, uint8_t *pDay_bcd, uint16_t add_days)
|
{
|
uint16_t year_h = BCD_2_HEX_U8(*pYear_bcd) + 2000, temp_year_h = 0, days_of_year = 0;
|
uint8_t month_h = BCD_2_HEX_U8(*pMonth_bcd), day_h = BCD_2_HEX_U8(*pDay_bcd), i;
|
uint8_t leap = ((year_h % 4 == 0) && (year_h % 100 != 0)) || (year_h % 400 == 0); // 1ΪÈòÄê 0ΪƽÄê
|
uint8_t days_of_month[2][13] = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
/*¼ÆËã¸ÃÄê¸ÃÔ¸ÃÌìΪµÚ¼¸Ìì*/
|
for (i = 1; i < month_h; i++)
|
days_of_year += days_of_month[leap][i];
|
days_of_year += day_h;
|
/*Ôö¼ÓÌìÊý*/
|
days_of_year += add_days;
|
temp_year_h = year_h;
|
if (leap)
|
{
|
if (days_of_year > 366)
|
{
|
temp_year_h += days_of_year / 366;
|
days_of_year -= 366;
|
}
|
}
|
else
|
{
|
if (days_of_year > 365)
|
{
|
temp_year_h += days_of_year / 365;
|
days_of_year -= 365;
|
}
|
}
|
leap = ((temp_year_h % 4 == 0) && (temp_year_h % 100 != 0)) || (temp_year_h % 400 == 0);
|
for (i = 1; days_of_year > days_of_month[leap][i]; i++)
|
days_of_year -= days_of_month[leap][i];
|
*pYear_bcd = HEX_2_BCD_U8(temp_year_h - 2000);
|
*pMonth_bcd = HEX_2_BCD_U8(i);
|
*pDay_bcd = HEX_2_BCD_U8(days_of_year);
|
}
|