/* * check the existence of given calendar elements * this includes either number of day in the month * and calendars pecularities (year 0 and October 1582) */ static int check_date(int century, int wy, Int_token y, Int_token m, Int_token d, long *jul) { int y_expand, y_check, m_check, d_check; /* expands years written with two digits only */ if (y.value >= 0 && y.value < wy && y.digits <= 2) { y_expand = century + y.value; } else if (y.value >= wy && y.value < 100 && y.digits <= 2) { y_expand = century - 100 + y.value; } else { y_expand = y.value; } if (m.digits > 2 || d.digits > 2) { /* this should be the year instead of either the month or the day */ return EXIT_FAILURE; } *jul = cal_to_jul(y_expand, m.value, d.value); jul_to_cal(*jul, &y_check, &m_check, &d_check); if (y_expand != y_check || m.value != m_check || d.value != d_check) { return EXIT_FAILURE; } else { return EXIT_SUCCESS; } }
/* * convert julian day to calendar and hourly elements * rounding_tol allows to say 1999-12-31T23:59:59.501 * should be rounded to 2000-01-01T00:00:00.000 assuming * it is set to 0.5 second. It is wise to set it according * to the display accuracy of seconds. */ void jul_to_cal_and_time(double jday, double rounding_tol, int *y, int *m, int *d, int *hour, int *min, double *sec) { long n; /* find the time of the day */ n = (long) floor(jday + 0.5); *sec = 24.0*(jday + 0.5 - n); *hour = (int) floor(*sec); *sec = 60.0*(*sec - *hour); *min = (int) floor(*sec); *sec = 60.0*(*sec - *min); if (*sec + rounding_tol >= 60.0) { /* we should round to next minute */ *sec = 0.0; *min += 1; if (*min == 60) { *min = 0; *hour += 1; if (*hour == 24) { *hour = 0; n++; } } } /* now find the date */ jul_to_cal(n, y, m, d); }
/* * check the existence of given calendar elements * this includes either number of day in the month * and calendars pecularities (year 0 and October 1582) */ static int check_date(Int_token y, Int_token m, Int_token d, long *jul) { int y_expand, y_check, m_check, d_check; y_expand = expanded_year (y); if (m.digits > 2 || d.digits > 2) { /* this should be the year instead of either the month or the day */ return RETURN_FAILURE; } *jul = cal_to_jul(y_expand, m.value, d.value); jul_to_cal(*jul, &y_check, &m_check, &d_check); if (y_expand != y_check || m.value != m_check || d.value != d_check) { return RETURN_FAILURE; } else { return RETURN_SUCCESS; } }
/* * convert julian day to calendar and hourly elements */ void jul_to_cal_and_time(double jday, int rounding, int *y, int *m, int *d, int *hour, int *min, int *sec) { long n; double tmp; /* compensate for the reference date */ jday += get_ref_date(); /* find the time of the day */ n = (long) floor(jday + 0.5); tmp = 24.0*(jday + 0.5 - n); *hour = (int) floor(tmp); tmp = 60.0*(tmp - *hour); *min = (int) floor(tmp); tmp = 60.0*(tmp - *min); *sec = (int) floor(tmp + 0.5); /* perform some rounding */ if (*sec >= 60 || rounding > ROUND_SECOND) { /* we should round to at least nearest minute */ if (*sec >= 30) { (*min)++; } *sec = 0; if (*min == 60 || rounding > ROUND_MINUTE) { /* we should round to at least nearest hour */ if (*min >= 30) { (*hour)++; } *min = 0; if (*hour == 24 || rounding > ROUND_HOUR) { /* we should round to at least nearest day */ if (*hour >= 12) { n++; } *hour = 0; } } } /* now find the date */ jul_to_cal(n, y, m, d); /* perform more rounding */ if (rounding == ROUND_MONTH) { int m2, y2; if (*m < 12) { m2 = *m + 1; y2 = *y; } else { m2 = 1; y2 = *y + 1; } if ((cal_to_jul(y2, m2, 1) - n) <= (n - cal_to_jul(*y, *m, 1))) { *m = m2; *y = y2; } *d = 1; } /* introduce the y2k bug for those who want it :) */ *y = reduced_year(*y); }