Re: glib1.3.5 : g_date_xxxx_week_of_year



> For better or for worse, the GDate routines are meant to behave in a
> manner that matches the week-number codes in strftime.
> 
> >From the strftime man page:
> 
>        %U     The week number of the current year  as  a  decimal
>               number,  range  00  to  53, starting with the first
>               Sunday as the first day of week 01. See also %V and
>               %W.
> 
>        %W     The week number of the current year  as  a  decimal
>               number,  range  00  to  53, starting with the first
>               Monday as the first day of week 01.
> 
> As far as I can tell, your test program shows that this behavior
> (whether it is the optimal behavior or not) is implemented by
> g_date_get_{sunday,monday}_week_of_year.
> 
> Now since I originally implemented those week-of-year calculations way
> back when, a third option such has appeared:
> 
>        %V     The  ISO  8601:1988 week number of the current year
>               as a decimal number, range 01 to 53, where  week  1
>               is  the  first week that has at least 4 days in the
>               current year, and with Monday as the first  day  of
>               the week. See also %U and %W. (SU)
> 
> ...which seems to be what you are talking about.
> 
> So it would probably be a good idea to add a new function to GDate (is
> it too late for that?) called "g_date_get_iso8601_week_of_year", or
> maybe just "g_date_get_week_of_year", that would use the ISO8601 method.
> 
> -JT
I suggest the following patchs for the g_date_get_iso8601_week_of_year
and g_date_get_iso8601_weeks_in_year routines.

gdate.h.patch and gdate.c.patch

Best regards

Jean-Noel
*** gdate.c.old	Fri Jun 29 20:04:30 2001
--- gdate.c	Fri Jun 29 20:06:30 2001
***************
*** 395,400 ****
--- 395,443 ----
    return ((day + wd)/7U + (wd == 0 ? 1 : 0));
  }
  
+ 
+ guint        
+ g_date_get_iso8601_week_of_year (GDate *d)
+ {
+   GDateWeekday wd;
+   guint day;
+   GDate first;
+   guint ret;
+   
+   g_return_val_if_fail (d != NULL, 0);
+   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;
+   
+ ret =  ((day + wd)/7U + (wd < 4 ? 1 : 0));
+  if (ret == 0)
+  {
+    g_date_clear (&first, 1);
+   g_date_set_dmy (&first, 31, 12, d->year - 1);
+   return g_date_get_iso8601_week_of_year (&first);
+  }
+  wd = g_date_get_weekday (d);
+  if ((ret == 53) && (wd < 4))
+  {
+   g_date_clear (&first, 1); 
+    g_date_set_dmy (&first, 1, 1, d->year + 1); 
+    return g_date_get_iso8601_week_of_year (&first); 
+ } 
+  return ret;
+ }
+ 
+ 
+ 
  void         
  g_date_clear (GDate       *d, guint ndates)
  {
***************
*** 1182,1187 ****
--- 1225,1251 ----
      }
    return 52;
  }
+ 
+ 
+ guint8       
+ g_date_get_iso8601_weeks_in_year (GDateYear  year)
+ {
+   GDate date;
+   guint8 week;
+   
+   g_return_val_if_fail (g_date_valid_year (year), 0);
+   
+   g_date_clear (&date, 1);
+   g_date_set_dmy (&date, 31, 12, year);
+   week = g_date_get_iso8601_week_of_year (&date);
+   if (week == 1)
+   {
+     g_date_subtract_days(&date, 7);
+     return g_date_get_iso8601_week_of_year (&date);
+   } 
+   return week;
+ }
+ 
  
  gint         
  g_date_compare (GDate     *lhs, 
*** gdate.h.old	Fri Jun 29 20:04:19 2001
--- gdate.h	Fri Jun 29 20:25:20 2001
***************
*** 150,155 ****
--- 150,161 ----
   */
  guint        g_date_get_monday_week_of_year (GDate      *date);
  guint        g_date_get_sunday_week_of_year (GDate      *date);
+ /* ISO weeks of the year
+  * the first week of the year is the week containing 
+  * the first Thursday.
+  */
+ guint        g_date_get_iso8601_week_of_year (GDate     *date);
+ 
  
  /* If you create a static date struct you need to clear it to get it
   * in a sane state before use. You can clear a whole array at
***************
*** 203,208 ****
--- 209,215 ----
                                             GDateYear    year) G_GNUC_CONST;
  guint8       g_date_get_monday_weeks_in_year  (GDateYear    year) G_GNUC_CONST;
  guint8       g_date_get_sunday_weeks_in_year  (GDateYear    year) G_GNUC_CONST;
+ guint8       g_date_get_iso8601_weeks_in_year (GDateYear  year) G_GNUC_CONST;
  
  /* qsort-friendly (with a cast...) */
  gint         g_date_compare               (GDate       *lhs,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]