void g_date_subtract_months (GDate *d, guint nmonths) { guint years, months; gint index; g_return_if_fail (g_date_valid (d)); if (!d->dmy) g_date_update_dmy (d); g_return_if_fail (d->dmy); years = nmonths/12; months = nmonths%12; g_return_if_fail (d->year > years); d->year -= years; if (d->month > months) d->month -= months; else { months -= d->month; d->month = 12 - months; d->year -= 1; } index = g_date_is_leap_year (d->year) ? 1 : 0; if (d->day > days_in_months[index][d->month]) d->day = days_in_months[index][d->month]; d->julian = FALSE; g_return_if_fail (g_date_valid (d)); }
void g_date_to_struct_tm (GDate *d, struct tm *tm) { GDateWeekday day; g_return_if_fail (d != NULL); g_return_if_fail (g_date_valid (d)); g_return_if_fail (tm != NULL); if (!d->dmy) { g_date_update_dmy (d); } g_return_if_fail (d->dmy); /* zero all the irrelevant fields to be sure they're valid */ /* On Linux and maybe other systems, there are weird non-POSIX * fields on the end of struct tm that choke strftime if they * contain garbage. So we need to 0 the entire struct, not just the * fields we know to exist. */ memset (tm, 0x0, sizeof (struct tm)); tm->tm_mday = d->day; tm->tm_mon = d->month - 1; /* 0-11 goes in tm */ tm->tm_year = ((int)d->year) - 1900; /* X/Open says tm_year can be negative */ day = g_date_weekday (d); if (day == 7) day = 0; /* struct tm wants days since Sunday, so Sunday is 0 */ tm->tm_wday = (int)day; tm->tm_yday = g_date_day_of_year (d) - 1; /* 0 to 365 */ tm->tm_isdst = -1; /* -1 means "information not available" */ }
guint g_date_get_monday_week_of_year (const GDate *d) { GDateWeekday wd; guint day; GDate first; g_return_val_if_fail (g_date_valid (d), 0); if (!d->dmy) g_date_update_dmy (d); g_return_val_if_fail (d->dmy, 0); g_date_clear (&first, 1); g_date_set_dmy (&first, 1, 1, d->year); wd = g_date_get_weekday (&first) - 1; /* make Monday day 0 */ day = g_date_get_day_of_year (d) - 1; return ((day + wd)/7U + (wd == 0 ? 1 : 0)); }