45 static void initialize( ut_system *units_system );
46 static void get_origin( ut_unit *dataunits,
int *y0,
int *mon0,
int *d0,
int *
h0,
int *min0,
double *s0 );
59 #define UTC2_MAX_UNKCAL_WARNS 1000
66 int utCalendar2_cal(
double val, ut_unit *dataunits,
int *year,
int *month,
int *day,
int *hour,
67 int *minute,
double *second,
const char *calendar_name )
70 int jdnew, ndinc, ierr, iorig, iround;
71 double fdays, extra_seconds, tot_extra_seconds;
78 static ut_unit *prev_units=NULL;
79 static cv_converter *conv_user_units_to_days=NULL;
80 static int y0, mon0, d0,
h0, min0, jday0;
81 static double s0, extra_seconds0;
82 static char *prev_calendar=NULL;
84 if( dataunits == NULL ) {
85 fprintf( stderr,
"Error, utCalendar2 passed a NULL units\n" );
94 cal2use =
getcal( calendar_name );
95 if( cal2use == NULL ) {
97 cal2use =
getcal(
"Standard" );
103 if( (prev_units != NULL) && (prev_calendar != NULL)
104 && (strcmp(prev_calendar,cal2use->
name)==0)
105 && (ut_compare( prev_units, dataunits ) == 0)) {
112 if( prev_units != NULL )
113 ut_free( prev_units );
115 if( prev_calendar != NULL )
116 free( prev_calendar );
119 get_origin( dataunits, &y0, &mon0, &d0, &
h0, &min0, &s0 );
122 extra_seconds0 =
h0*3600.0 + min0*60.0 + s0;
125 if( (ierr =
ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) {
126 fprintf( stderr,
"Error in utCalendar2: %s\n",
ccs_err_str(ierr) );
131 if( conv_user_units_to_days != NULL )
132 cv_free( conv_user_units_to_days );
138 prev_units = ut_clone( dataunits );
139 if( ut_compare( prev_units, dataunits ) != 0 ) {
140 fprintf( stderr,
"error, internal error in udunits2 library found in routine utCalendar2: a clone of the user's units does not equal the original units!\n" );
144 prev_calendar = (
char *)malloc(
sizeof(
char) * (strlen(cal2use->
name)+1 ));
145 strcpy( prev_calendar, cal2use->
name );
149 fdays = cv_convert_double( conv_user_units_to_days, val );
153 extra_seconds = (fdays - ndays)*86400.0;
156 jdnew = jday0 + ndays;
159 tot_extra_seconds = extra_seconds0 + extra_seconds;
160 ndinc = tot_extra_seconds / 86400.0;
162 tot_extra_seconds -= ndinc*86400.0;
163 if( tot_extra_seconds < 0.0 ) {
164 tot_extra_seconds += 86400.0;
169 if( (ierr =
ccs_jday2date( cal2use, jdnew, year, month, day )) != 0 ) {
170 fprintf( stderr,
"Error in utCalendar2: %s\n",
ccs_err_str(ierr) );
174 *hour = tot_extra_seconds / 3600.0;
175 tot_extra_seconds -= *hour * 3600.0;
176 *minute = tot_extra_seconds / 60.0;
177 tot_extra_seconds -= *minute * 60.0;
178 *second = tot_extra_seconds;
183 if( iround > iorig ) {
185 *second = (double)iround;
186 if( *second >= 60.0 ) {
189 if( *minute >= 60.0 ) {
192 if( *hour >= 24.0 ) {
194 if( (ierr =
ccs_jday2date( cal2use, jdnew+1, year, month, day )) != 0 ) {
195 fprintf( stderr,
"Error in utCalendar2: %s\n",
ccs_err_str(ierr) );
211 ut_unit *user_unit,
double *value,
const char *calendar_name )
213 int jday, ierr, diff_in_days;
214 double fdiff_in_days, val_days, val_partdays, fdiff_in_partdays, fpartday;
218 static ut_unit *prev_units=NULL;
219 static int y0, mon0, d0,
h0, min0, jday0;
220 static double s0, fpartday0;
221 static cv_converter *conv_days_to_user_units=NULL;
222 static char *prev_calendar=NULL;
229 cal2use =
getcal( calendar_name );
230 if( cal2use == NULL ) {
232 cal2use =
getcal(
"Standard" );
235 if( (prev_units != NULL) && (prev_calendar != NULL)
236 && (strcmp(prev_calendar,cal2use->
name)==0)
237 && (ut_compare( prev_units, user_unit ) == 0)) {
242 if( prev_units != NULL )
243 ut_free( prev_units );
245 if( prev_calendar != NULL )
246 free( prev_calendar );
248 if( conv_days_to_user_units != NULL )
249 cv_free( conv_days_to_user_units );
252 get_origin( user_unit, &y0, &mon0, &d0, &
h0, &min0, &s0 );
255 if( (ierr =
ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) {
256 fprintf( stderr,
"Error in utCalendar2: %s\n",
ccs_err_str(ierr) );
261 fpartday0 = (double)
h0/24.0 + (
double)min0/1440.0 + s0/86400.0;
269 prev_units = ut_clone( user_unit );
270 if( ut_compare( prev_units, user_unit ) != 0 ) {
271 fprintf( stderr,
"error, internal error in udunits2 library found in routine utInvCalendar2: a clone of the user's units does not equal the original units!\n" );
275 prev_calendar = (
char *)malloc(
sizeof(
char) * (strlen(cal2use->
name)+1 ));
276 strcpy( prev_calendar, cal2use->
name );
280 if( (ierr =
ccs_date2jday( cal2use, year, month, day, &jday )) != 0 ) {
281 fprintf( stderr,
"Error in utInvCalendar2: %s\n",
ccs_err_str(ierr) );
288 diff_in_days = jday - jday0;
289 fdiff_in_days = (double)diff_in_days;
293 fpartday = (double)hour/24.0 + (
double)minute/1440.0 + second/86400.0;
294 fdiff_in_partdays = fpartday - fpartday0;
297 val_days = cv_convert_double( conv_days_to_user_units, fdiff_in_days );
298 val_partdays = cv_convert_double( conv_days_to_user_units, fdiff_in_partdays );
301 *value = val_days + val_partdays;
313 cv_converter *conv_user_units_to_days;
315 sprintf( daystr,
"days since %04d-%02d-%02d %02d:%02d:%f",
316 y0, mon0, d0,
h0, min0, s0 );
318 udu_days = ut_parse( ut_get_system(uu), daystr, UT_ASCII );
319 if( udu_days == NULL ) {
320 fprintf( stderr,
"internal error in utCalendar2/conv_to_days: failed to parse following string: \"%s\"\n",
324 conv_user_units_to_days = ut_get_converter( uu, udu_days );
325 if( conv_user_units_to_days == NULL ) {
326 fprintf( stderr,
"internal error in utCalendar2/conv_to_days: cannot convert from \"%s\" to user units\n",
332 return( conv_user_units_to_days );
342 cv_converter *conv_days_to_user_units;
344 sprintf( daystr,
"days since %04d-%02d-%02d %02d:%02d:%f",
345 y0, mon0, d0,
h0, min0, s0 );
347 udu_days = ut_parse( ut_get_system(uu), daystr, UT_ASCII );
348 if( udu_days == NULL ) {
349 fprintf( stderr,
"internal error in utCalendar2/conv_to_user_units: failed to parse following string: \"%s\"\n",
353 conv_days_to_user_units = ut_get_converter( udu_days, uu );
354 if( conv_days_to_user_units == NULL ) {
355 fprintf( stderr,
"internal error in utCalendar2/conv_to_user_units: cannot convert from user units to \"%s\"\n",
361 return( conv_days_to_user_units );
369 static void get_origin( ut_unit *dataunits,
int *y0,
int *mon0,
int *d0,
int *
h0,
int *min0,
double *s0 )
371 double s0lib, rez, tval, tval_conv, resolution;
372 cv_converter *conv_user_date_to_ref_date;
374 int y0lib, mon0lib, d0lib, h0lib, min0lib;
377 static ut_unit *udu_ref_date=NULL;
379 if( udu_ref_date == NULL ) {
388 if( (tmpu = ut_parse( ut_get_system(dataunits),
"days since 2010-01-09", UT_ASCII )) == NULL ) {
389 fprintf( stderr,
"Internal error in routnie utCalendar2/get_origin: failed to parse temp timestamp string\n" );
395 ut_decode_time( tval, &y0lib, &mon0lib, &d0lib, &h0lib, &min0lib, &s0lib, &rez );
396 sprintf( ustr,
"seconds since %04d-%02d-%02d %02d:%02d:%f",
397 y0lib, mon0lib, d0lib, h0lib, min0lib, s0lib );
398 udu_ref_date = ut_parse( ut_get_system(dataunits), ustr, UT_ASCII );
399 if( udu_ref_date == NULL ) {
400 fprintf( stderr,
"internal error in routine utCalendar2/get_origin: could not parse origin string \"%s\"\n",
407 conv_user_date_to_ref_date = ut_get_converter( dataunits, udu_ref_date );
411 tval_conv = cv_convert_double( conv_user_date_to_ref_date, tval );
414 ut_decode_time( tval_conv, y0, mon0, d0,
h0, min0, s0, &resolution );
416 cv_free( conv_user_date_to_ref_date );
427 fprintf( stderr,
"Error in utCalendar2 routines, could not allocate internal storage\n" );
434 fprintf( stderr,
"Error in utCalendar2 routines, could not allocate internal storage for calendar names\n" );
455 fprintf( stderr,
"Coding error in utCalendar2_cal routines, cal_std is null!\n" );
459 if( strcasecmp( name,
"standard" ) == 0 )
470 if( new_cal == NULL )
480 new_index = strlen(name);
495 known_cal_name[new_index] = (
char *)malloc(
sizeof(
char) * (strlen(name)+1 ));
518 fprintf( stderr,
"Error in utCalendar2_cal/utInvCalendar2_cal: unknown calendar \"%s\". Using Standard calendar instead\n",
524 fprintf( stderr,
"Error in utCalendar_cal: could not allocate internal memory to store string \"%s\"\n",
calcalcs_cal * ccs_init_calendar(const char *calname)
char * ccs_err_str(int error_code)
int ccs_jday2date(calcalcs_cal *calendar, int jday, int *year, int *month, int *day)
void ccs_free_calendar(calcalcs_cal *cc)
int ccs_date2jday(calcalcs_cal *calendar, int year, int month, int day, int *jday)
int utCalendar2_cal(double val, ut_unit *dataunits, int *year, int *month, int *day, int *hour, int *minute, double *second, const char *calendar_name)
static void initialize(ut_system *units_system)
static char ** known_cal_name
static cv_converter * get_day_to_user_converter(ut_unit *uu, int y0, int mon0, int d0, int h0, int min0, double s0)
int utInvCalendar2_cal(int year, int month, int day, int hour, int minute, double second, ut_unit *user_unit, double *value, const char *calendar_name)
static const double sec_rounding_value
#define UTC2_MAX_UNKCAL_WARNS
static void unknown_cal_emit_warning(const char *calendar_name)
static void get_origin(ut_unit *dataunits, int *y0, int *mon0, int *d0, int *h0, int *min0, double *s0)
static calcalcs_cal * getcal(const char *name)
static char * unknown_cal_emitted_warning_for[UTC2_MAX_UNKCAL_WARNS]
static cv_converter * get_user_to_day_converter(ut_unit *uu, int y0, int mon0, int d0, int h0, int min0, double s0)
static calcalcs_cal ** known_cal
static const int maxcals_known
static calcalcs_cal * cal_std