gdate.c

来自「嵌入式下基于MiniGUI的Web Browser」· C语言 代码 · 共 1,435 行 · 第 1/3 页

C
1,435
字号
g_date_is_last_of_month (const GDate *d){  gint index;    g_return_val_if_fail (d != NULL, FALSE);  g_return_val_if_fail (g_date_valid (d), FALSE);    if (!d->dmy)     {      g_date_update_dmy (d);    }  g_return_val_if_fail (d->dmy, FALSE);      index = g_date_is_leap_year (d->year) ? 1 : 0;    if (d->day == days_in_months[index][d->month]) return TRUE;  else return FALSE;}void         g_date_add_days (GDate *d, guint ndays){  g_return_if_fail (d != NULL);  g_return_if_fail (g_date_valid (d));    if (!d->julian)    {      g_date_update_julian (d);    }  g_return_if_fail (d->julian);    d->julian_days += ndays;  d->dmy = FALSE;}void         g_date_subtract_days (GDate *d, guint ndays){  g_return_if_fail (d != NULL);  g_return_if_fail (g_date_valid (d));    if (!d->julian)    {      g_date_update_julian (d);    }  g_return_if_fail (d->julian);  g_return_if_fail (d->julian_days > ndays);    d->julian_days -= ndays;  d->dmy = FALSE;}void         g_date_add_months (GDate       *d,                    guint        nmonths){  guint years, months;  gint index;    g_return_if_fail (d != NULL);  g_return_if_fail (g_date_valid (d));    if (!d->dmy)     {      g_date_update_dmy (d);    }  g_return_if_fail (d->dmy);      nmonths += d->month - 1;    years  = nmonths/12;  months = nmonths%12;    d->month = months + 1;  d->year  += years;    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_subtract_months (GDate       *d,                         guint        nmonths){  guint years, months;  gint index;    g_return_if_fail (d != NULL);  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_add_years (GDate       *d,                   guint        nyears){  g_return_if_fail (d != NULL);  g_return_if_fail (g_date_valid (d));    if (!d->dmy)     {      g_date_update_dmy (d);    }  g_return_if_fail (d->dmy);      d->year += nyears;    if (d->month == 2 && d->day == 29)    {      if (!g_date_is_leap_year (d->year))        {          d->day = 28;        }    }    d->julian = FALSE;}void         g_date_subtract_years (GDate       *d,                        guint        nyears){  g_return_if_fail (d != NULL);  g_return_if_fail (g_date_valid (d));    if (!d->dmy)     {      g_date_update_dmy (d);    }  g_return_if_fail (d->dmy);    g_return_if_fail (d->year > nyears);    d->year -= nyears;    if (d->month == 2 && d->day == 29)    {      if (!g_date_is_leap_year (d->year))        {          d->day = 28;        }    }    d->julian = FALSE;}gboolean     g_date_is_leap_year (GDateYear  year){  g_return_val_if_fail (g_date_valid_year (year), FALSE);    return ( (((year % 4) == 0) && ((year % 100) != 0)) ||           (year % 400) == 0 );}guint8         g_date_get_days_in_month (GDateMonth month,                           GDateYear  year){  gint index;    g_return_val_if_fail (g_date_valid_year (year), 0);  g_return_val_if_fail (g_date_valid_month (month), 0);    index = g_date_is_leap_year (year) ? 1 : 0;    return days_in_months[index][month];}guint8       g_date_get_monday_weeks_in_year (GDateYear  year){  GDate d;    g_return_val_if_fail (g_date_valid_year (year), 0);    g_date_clear (&d, 1);  g_date_set_dmy (&d, 1, 1, year);  if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;  g_date_set_dmy (&d, 31, 12, year);  if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;  if (g_date_is_leap_year (year))     {      g_date_set_dmy (&d, 2, 1, year);      if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;      g_date_set_dmy (&d, 30, 12, year);      if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;    }  return 52;}guint8       g_date_get_sunday_weeks_in_year (GDateYear  year){  GDate d;    g_return_val_if_fail (g_date_valid_year (year), 0);    g_date_clear (&d, 1);  g_date_set_dmy (&d, 1, 1, year);  if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;  g_date_set_dmy (&d, 31, 12, year);  if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;  if (g_date_is_leap_year (year))     {      g_date_set_dmy (&d, 2, 1, year);      if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;      g_date_set_dmy (&d, 30, 12, year);      if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;    }  return 52;}gint         g_date_compare (const GDate *lhs,                 const GDate *rhs){  g_return_val_if_fail (lhs != NULL, 0);  g_return_val_if_fail (rhs != NULL, 0);  g_return_val_if_fail (g_date_valid (lhs), 0);  g_return_val_if_fail (g_date_valid (rhs), 0);    /* Remember the self-comparison case! I think it works right now. */    while (TRUE)    {            if (lhs->julian && rhs->julian)         {          if (lhs->julian_days < rhs->julian_days) return -1;          else if (lhs->julian_days > rhs->julian_days) return 1;          else                                          return 0;        }      else if (lhs->dmy && rhs->dmy)         {          if (lhs->year < rhs->year)               return -1;          else if (lhs->year > rhs->year)               return 1;          else             {              if (lhs->month < rhs->month)         return -1;              else if (lhs->month > rhs->month)         return 1;              else                 {                  if (lhs->day < rhs->day)              return -1;                  else if (lhs->day > rhs->day)              return 1;                  else                                       return 0;                }                          }                  }      else        {          if (!lhs->julian) g_date_update_julian (lhs);          if (!rhs->julian) g_date_update_julian (rhs);          g_return_val_if_fail (lhs->julian, 0);          g_return_val_if_fail (rhs->julian, 0);        }          }  return 0; /* warnings */}void        g_date_to_struct_tm (const 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_get_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_get_day_of_year (d) - 1; /* 0 to 365 */  tm->tm_isdst = -1; /* -1 means "information not available" */}voidg_date_clamp (GDate *date,	      const GDate *min_date,	      const GDate *max_date){  g_return_if_fail (date);  g_return_if_fail (g_date_valid (date));  if (min_date != NULL)    g_return_if_fail (g_date_valid (min_date));  if (max_date != NULL)    g_return_if_fail (g_date_valid (max_date));  if (min_date != NULL && max_date != NULL)    g_return_if_fail (g_date_compare (min_date, max_date) <= 0);  if (min_date && g_date_compare (date, min_date) < 0)    *date = *min_date;  if (max_date && g_date_compare (max_date, date) < 0)    *date = *max_date;}voidg_date_order (GDate *date1,              GDate *date2){  g_return_if_fail (date1 != NULL);  g_return_if_fail (date2 != NULL);  g_return_if_fail (g_date_valid (date1));  g_return_if_fail (g_date_valid (date2));  if (g_date_compare (date1, date2) > 0)    {      GDate tmp = *date1;      *date1 = *date2;      *date2 = tmp;    }}gsize     g_date_strftime (gchar       *s,                  gsize        slen,                  const gchar *format,                  const GDate *d){  struct tm tm;  gsize locale_format_len = 0;  gchar *locale_format;  gsize tmplen;  gchar *tmpbuf;  gsize tmpbufsize;  gsize convlen = 0;  gchar *convbuf;  GError *error = NULL;  gsize retval;  g_return_val_if_fail (d != NULL, 0);  g_return_val_if_fail (g_date_valid (d), 0);  g_return_val_if_fail (slen > 0, 0);   g_return_val_if_fail (format != 0, 0);  g_return_val_if_fail (s != 0, 0);  g_date_to_struct_tm (d, &tm);  locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);  if (error)    {      g_warning (G_STRLOC "Error converting format to locale encoding: %s\n", error->message);      g_error_free (error);      s[0] = '\0';      return 0;    }  tmpbufsize = MAX (128, locale_format_len * 2);  while (TRUE)    {      tmpbuf = g_malloc (tmpbufsize);      /* Set the first byte to something other than '\0', to be able to       * recognize whether strftime actually failed or just returned "".       */      tmpbuf[0] = '\1';      tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);      if (tmplen == 0 && tmpbuf[0] != '\0')        {          g_free (tmpbuf);          tmpbufsize *= 2;          if (tmpbufsize > 65536)            {              g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up\n");              g_free (locale_format);              s[0] = '\0';              return 0;            }        }      else        break;    }  g_free (locale_format);  convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);  g_free (tmpbuf);  if (error)    {      g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s\n", error->message);      g_error_free (error);      s[0] = '\0';      return 0;    }  if (slen <= convlen)    {      /* Ensure only whole characters are copied into the buffer.       */      gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);      g_assert (end != NULL);      convlen = end - convbuf;      /* Return 0 because the buffer isn't large enough.       */      retval = 0;    }  else    retval = convlen;  memcpy (s, convbuf, convlen);  s[convlen] = '\0';  g_free (convbuf);  return retval;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?