#ifndef __INC_PUBLHEAD_H__
#define __INC_PUBLHEAD_H__
#include <stdio.h>
#include "PublType.h"
#endif
#ifndef __INC_PUBLTYPE_H__
#define __INC_PUBLTYPE_H__
typedef char String;
typedef unsigned int Boolean;
typedef unsigned char UFix08;
typedef unsigned short int UFix16;
typedef unsigned long int UFix32;
typedef signed char SFix08;
typedef signed short int SFix16;
typedef signed long int SFix32;
typedef unsigned int UAuto08;
typedef unsigned int UAuto16;
typedef unsigned long UAuto32;
typedef signed char SAuto08;
typedef signed int SAuto16;
typedef signed long SAuto32;
#endif
#include "PublHead.h"
typedef struct
{
UAuto32 year;
UAuto08 month;
UAuto08 day;
} STR_DTTM;
static Boolean IsLeapYear(UAuto32 y)
{
return ((((y % 4) == 0) && ((y % 100) != 0)) || ((y % 400) == 0)) ? 1 : 0;
}
static const UAuto16 day_of_month[2][13] =
{
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
};
static UAuto32 Date_Sub_010101(STR_DTTM const *dt)
{
UAuto32 year;
year = dt->year - 1;
return year * 365 + ((year / 4) - (year / 100) + (year / 400)) + day_of_month[IsLeapYear(dt->year)][dt->month - 1] + (dt->day - 1);
}
static SAuto32 Date_Sub_Date(STR_DTTM const *dt1, STR_DTTM const *dt2)
{
#if 1
return Date_Sub_010101(dt1) - Date_Sub_010101(dt2);
#else
UAuto32 i = 0;
SAuto32 day = 0;
SAuto16 sign = 0;
STR_DTTM big_year;
STR_DTTM small_year;
if (!IsLegal(dt1)|| !IsLegal(dt2)) {
return 0;
}
sign = dt1->year > dt2->year ? -1:1;
big_year = dt1->year > dt2->year ? *dt1:*dt2;
small_year = dt1->year < dt2->year ? *dt1:*dt2;
for (i = small_year.year; i < big_year.year; i++) {
if (IsLeapYear(i)) {
day += 366;
} else {
day += 365;
}
}
day = sign*(Cal_Day_Of_Year(&big_year) - Cal_Day_Of_Year(&small_year) + day);
return day;
#endif
}
#define FOUR_YEARS 1461
#define FOUR_HUNGRED_YEARS 146097
#define ONE_HUNGRED_YEARS 36524
#define THREE_HUNGRED_YEARS 109572
#define ONE_YEARS 365
#define THREE_YEARS 1095
static void Cal_Date_By_Offset(STR_DTTM *dest, UAuto32 days)
{
UAuto16 i;
UAuto16 const *tbl;
dest->year = (days / FOUR_HUNGRED_YEARS) * 400 + 1;
days %= FOUR_HUNGRED_YEARS;
if (days > THREE_HUNGRED_YEARS) {
dest->year += 300;
days -= THREE_HUNGRED_YEARS;
} else {
dest->year += (days / ONE_HUNGRED_YEARS) * 100;
days %= ONE_HUNGRED_YEARS;
}
dest->year += (days / FOUR_YEARS) * 4;
days %= FOUR_YEARS;
if (days > THREE_YEARS) {
dest->year += 3;
days -= THREE_YEARS;
} else {
dest->year += days / ONE_YEARS;
days %= ONE_YEARS;
}
tbl = day_of_month[IsLeapYear(dest->year)];
for (i = days/31; i < 13; i++) {
if ((days >= tbl[i]) && (days < tbl[i + 1])) {
dest->month = i + 1;
break;
}
}
dest->day = days - tbl[dest->month - 1] + 1;
}
static void TranDateHexToDate(STR_DTTM *dest, STR_DTTM const *src, SAuto32 days)
{
#if 1
Cal_Date_By_Offset(dest, Date_Sub_010101(src) + days);
#else
UAuto32 i = 0;
UAuto32 j = 0;
SAuto16 sign = 0;
SAuto32 year = 0;
SAuto32 differ_days = 0;
SAuto16 one_year_of_day = 0;
UAuto32 day_of_moth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (!IsLegal(src)) {
return;
}
if (!days) {
*dest = *src;
return;
}
sign = days > 0 ? 1:-1;
differ_days = days + Cal_Day_Of_Year(src);
if (days > 0) {
one_year_of_day = IsLeapYear(src->year) > 0 ? 366:365;
} else {
one_year_of_day = IsLeapYear(src->year - 1) > 0 ? 366:365;
j = -1;
}
while(differ_days < -1*one_year_of_day || differ_days > one_year_of_day) {
differ_days -= sign*one_year_of_day;
year += sign;
if(IsLeapYear(src->year + year + j)) {
one_year_of_day = 366;
} else {
one_year_of_day = 365;
}
}
if (days < 0) {
if(IsLeapYear(src->year + year + sign)) {
differ_days += 366;
} else {
differ_days += 365;
}
year += sign;
}
dest->year = src->year + year;
if (IsLeapYear(dest->year)) {
day_of_moth[1]++;
}
for(i = 0; differ_days > day_of_moth[i]; i++) {
differ_days -= day_of_moth[i];
}
dest->month = i+1;
dest->day = differ_days;
#endif
}
void main(void)
{
STR_UFix64 mlong1 = {0};
STR_DTTM date1 = {0};
STR_DTTM date2 = {0};
date1.year = 2003;
date1.month = 1;
date1.day = 1;
date2.year = 4;
date2.month = 12;
date2.day = 31;
TranDateHexToDate(&date1, &date2, 0);
printf("010101 days = %ld\n", Date_Sub_010101(&date2));
printf("year = %ld month = %ld day = %ld\n", date1.year, date1.month, date1.day);
Cal_U32_Mul_U32(0xfdf52234L, 0x00fed741, &mlong1);
printf("retv->high = %lx, ",mlong1.high);
printf("retv->low = %lx\r\n",mlong1.low);
}