static char * try_auto_date (GnmValue *value, const GOFormat *format, GODateConventions const *date_conv) { gnm_float v, vr, vs; GOFormat *actual; char *res; gboolean needs_date, needs_time, needs_frac_sec; gboolean is_date; int is_time; GString *xlfmt; GDate date; format = gnm_format_specialize (format, value); is_date = go_format_is_date (format) > 0; is_time = go_format_is_time (format); if (!is_date && is_time <= 0) return NULL; /* We don't want to coerce strings. */ if (!VALUE_IS_FLOAT (value)) return NULL; /* Verify that the date is valid. */ if (!datetime_value_to_g (&date, value, date_conv)) return NULL; v = value_get_as_float (value); vr = gnm_fake_round (v); vs = (24 * 60 * 60) * gnm_abs (v - vr); needs_date = is_time < 2 && (is_date || gnm_abs (v) >= 1); needs_time = is_time > 0 || gnm_abs (v - vr) > 1e-9; needs_frac_sec = needs_time && gnm_abs (vs - gnm_fake_round (vs)) >= 0.5e-3; xlfmt = g_string_new (NULL); if (needs_date) g_string_append (xlfmt, "yyyy/mm/dd"); if (needs_time) { if (needs_date) g_string_append_c (xlfmt, ' '); if (is_time == 2) g_string_append (xlfmt, "[h]:mm:ss"); else g_string_append (xlfmt, "hh:mm:ss"); if (needs_frac_sec) g_string_append (xlfmt, ".000"); } actual = go_format_new_from_XL (xlfmt->str); g_string_free (xlfmt, TRUE); res = format_value (actual, value, -1, date_conv); go_format_unref (actual); return res; }
static GnmValue * gnumeric_date_get_date (GnmFuncEvalInfo * ei, GnmValue const * const val, int *year, int *month, int *day) { GDate date; if (val == NULL) g_date_set_time_t (&date, time (NULL)); else if (!datetime_value_to_g (&date, val, DATE_CONV (ei->pos))) return value_new_error_NUM (ei->pos); *year = g_date_get_year (&date); *month = g_date_get_month (&date); *day = g_date_get_day (&date); return NULL; }
/** * go_val_bucketer_apply : * @bucketer : #GOValBucketer * @v : #GOVal * * Calculate which bucket @v falls into. * * Returns -1 on general failure, and 0 for out of range below the start of the domain. * Some bucketer types will also create a bucket on the high end for out of range above. **/ int go_val_bucketer_apply (GOValBucketer const *bucketer, GOVal const *v) { g_return_val_if_fail (bucketer != NULL, 0); g_return_val_if_fail (v != NULL, 0); if (bucketer->type == GO_VAL_BUCKET_NONE) return 0; /* Time based */ if (bucketer->type <= GO_VAL_BUCKET_HOUR) { switch (bucketer->type) { case GO_VAL_BUCKET_SECOND : break; case GO_VAL_BUCKET_MINUTE : break; default : g_assert_not_reached (); } } /* date based */ if (bucketer->type <= GO_VAL_BUCKET_YEAR) { static GODateConventions const default_conv = {FALSE}; GDate d; if (!datetime_value_to_g (&d, v, &default_conv)) return -1; switch (bucketer->type) { case GO_VAL_BUCKET_DAY_OF_YEAR : return 1 + g_date_get_day_of_year (&d); case GO_VAL_BUCKET_MONTH : return g_date_get_month (&d); case GO_VAL_BUCKET_CALENDAR_QUARTER : return 1 + ((g_date_get_month (&d)-1) / 3); case GO_VAL_BUCKET_YEAR : return 1 + g_date_get_year (&d); default : g_assert_not_reached (); } } /* >= GO_VAL_BUCKET_SERIES_LINEAR) */ return 0; }
/* * Returns the number of days in the year for the given date accoring to * the day counting system specified by 'basis' argument. Basis may have * one of the following values: * * 0 for US 30/360 (days in a month/days in a year) * 1 for actual days/actual days * 2 for actual days/360 * 3 for actual days/365 * 4 for European 30/360 * * This function returns 360 for basis 0, 2, and 4, it returns value * 365 for basis 3, and value 365 or 366 for basis 1 accoring to the * year of the given date (366 is returned if the date is in a leap * year). */ int annual_year_basis (GnmValue const *value_date, go_basis_t basis, GODateConventions const *date_conv) { GDate date; switch (basis) { case GO_BASIS_MSRB_30_360: return 360; case GO_BASIS_ACT_ACT: if (!datetime_value_to_g (&date, value_date, date_conv)) return -1; return g_date_is_leap_year (g_date_get_year (&date)) ? 366 : 365; case GO_BASIS_ACT_360: return 360; case GO_BASIS_ACT_365: return 365; case GO_BASIS_30E_360: return 360; default: return -1; } }