/* * Plik zawiera implementację funkcji operujących na dacie. * Author: Ostolski Dariusz */ #include #include #include #include #include "date.h" #include "defs.h" double dt_diff(const ya_date *da, const ya_date *db) { return dt_toJulian(da)-dt_toJulian(db); } void dt_minusDays(ya_date *da, int days) { dt_fromJulian(da, dt_toJulian(da)-days); } void dt_addDays(ya_date *da, int days) { dt_fromJulian(da, dt_toJulian(da)+days); } double dt_toJulian(const ya_date *dat) { double a,b,c,e; register double year, month, day; year = (double)dat->year; month = (double)dat->month; day = (double)dat->day; a = 4716 + year+((int)((month+9)/12)); b = 1729279.5 + 367 * year + ((int) (275 * month / 9))- ((int )( 7 * a / 4)) + day; c = (int)( ( a + 83 ) / 100 ); e = (int)( 3 * ( c + 1 ) / 4 ); return b + 38 - e; } void dt_fromJulian(ya_date *dat, double JD) { double W,X,Z,Y,A,B,C,E,F,U; W = JD + 0.5; X = floor(W); Y = floor(( X + 32044.5 ) / 36524.25 ); Z = X + Y - (int)( Y / 4 ) - 38; U = W-X; A = Z + 1524; B = floor(( ( A - 122.1 ) / 365.25 )); C = A - (int) ( 365.25 * B ); E = (int) ( C / 30.61 ); F = (int) ( E / 14 ); dat->year = (unsigned int)(B - 4716 + F); dat->month =(unsigned int)( E - 1 - 12 * F); dat->day =(unsigned int)( C + U - ((int)( 153 * E / 5 ))); } int dt_cmp(const ya_date *a, const ya_date *b) { /* first we check years */ if(a->year > b->year) return 1; if(a->year < b->year) return -1; /* Next we check monhts */ if(a->month > b->month) return 1; if(a->month < b->month) return -1; /* Now we check days */ if(a->day > b->day) return 1; if(a->day < b->day) return -1; return 0; } int dt_asciiToDate(const char *format, const char *buffer, ya_date *d) { char *endPtr; long temp; while( *format != '\0' && *buffer!= '\0') { if( *format == '%') { format++; switch(*format) { case 'Y': case 'y': temp = strtol(buffer, &endPtr, 10); if(errno == ERANGE || temp == 0) return YACL_ECONV_ERROR; d->year = (unsigned int) (temp); buffer = endPtr; break; case 'm': case 'M': temp = strtol(buffer, &endPtr, 10); if(errno == ERANGE || temp == 0 ) return YACL_ECONV_ERROR; d->month = (unsigned int) (temp); buffer = endPtr; break; case 'd': case 'D': temp = strtol(buffer, &endPtr, 10); if(errno == ERANGE || temp == 0) return YACL_ECONV_ERROR; d->day = (unsigned int) (temp); buffer = endPtr; break; case '\0': return YACL_SUCCESS; } format++; } else { format++; buffer++; } } return YACL_SUCCESS; } size_t dt_toAscii(const char *format, const ya_date *d, char *buffer, size_t n) { size_t i=0; *buffer = '\0'; while( *format!='\0' ) { if( *format == '%' ) { char *temp = &buffer[i]; int ret; format++; switch(*format) { case 'Y': case 'y': if( i+4 >= n ) { i = n; break; } if( d->year>=YEAR_MAX ) { i = n; break; } ret = sprintf(temp, "%u", d->year); i += ret; break; case 'm': case 'M': if( i+2 >= n ) { i = n; break; } if((d->monthmonth >=MONTH_MAX)) { i = n; break; } ret = sprintf(temp, "%u", d->month); i += ret; break; case 'd': case 'D': if( i+2 >= n ) { i = n; break; } if(d->dayday >= DAY_MAX) { i = n; break; } ret = sprintf(temp, "%u", d->day); i+= ret; break; default: buffer[i]=*format; i++; } format++; if( i>=n ) break; } else { if( i>=n ) break; buffer[i] = *format; i++; format++; } } if( i>=n ) buffer[n-1] = '\0'; else buffer[i] = '\0'; return i; } int dt_isValid(const ya_date *date) { static const unsigned int months[2] [13] = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12*/ {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 } }; int leap =(int)((date->year%4 == 0 && date->year%100 != 0) || date->year%400 == 0); if( date->year>YEAR_MAX ) return 0; if( date->month<1 || date->month>12 ) return 0; if( date->day>months[leap][date->month] || date->day<1 ) return 0; return 1; }