Edit report at https://bugs.php.net/bug.php?id=33445&edit=1

 ID:                 33445
 Updated by:         der...@php.net
 Reported by:        richard dot quadling at bandvulc dot co dot uk
 Summary:            strftime() arguments are system dependent
-Status:             Assigned
+Status:             Open
 Type:               Feature/Change Request
 Package:            Date/time related
 Operating System:   *
 PHP Version:        5.0.4
-Assigned To:        derick
+Assigned To:        
 Block user comment: N
 Private report:     N



Previous Comments:
------------------------------------------------------------------------
[2005-08-11 20:18:15] der...@php.net

The fix up of strftime() is not done though - please keep it assigned.

------------------------------------------------------------------------
[2005-08-11 20:15:14] nlop...@php.net

Already implemented in PHP 5.1 as date('o').

------------------------------------------------------------------------
[2005-06-23 13:32:10] der...@php.net

This will be re-implemented very soon, so stay tuned!

------------------------------------------------------------------------
[2005-06-23 10:44:16] richard dot quadling at bandvulc dot co dot uk

Maybe a better solution would be to make the strftime and date functions the 
same and to consolidate the code to remove the dependency on platform specific 
libraries (e.g. the Windows strftime function does not support V,G or g).

Alternatively, amend the documentation to indicate which formats are supported 
by which platform.

It does seem that both of these functions do the same job and could be 
consilidated though.

Richard.

------------------------------------------------------------------------
[2005-06-23 10:17:55] richard dot quadling at bandvulc dot co dot uk

Description:
------------
This could also be a fix for a "Will Not Fix" bug #22711.



On Windows, the strftime() function does not support %V, %G or %g.

The date() function supports 'W' which deals with %V (if you get what I mean), 
but when the week number is 52 or 53 and you are looking at a January date, 
getting the correct year also would be useful.

I've included below a CVS diff datetime.c.

I don't know who to send it to.

date('V') emulates strftime('%G');
date('v') emulates strftime('%g');

I've also rewritten the date('W') code to combine with V and v.

Index: datetime.c
===================================================================
RCS file: /repository/php-src/ext/standard/datetime.c,v
retrieving revision 1.129
diff -u -r1.129 datetime.c
--- datetime.c  19 Jun 2005 22:15:26 -0000      1.129
+++ datetime.c  23 Jun 2005 08:00:48 -0000
@@ -288,7 +288,7 @@
        pval **format, **timestamp;
        time_t the_time;
        struct tm *ta, tmbuf;
-       int i, size = 0, length, h, beat, fd, wd, yd, wk;
+       int i, size = 0, length, h, beat, fd, wd, yd, wk, yr;
        char tmp_buff[32];
 #if !HAVE_TM_GMTOFF
        long tzone;
@@ -382,6 +382,7 @@
                                size += 5;
                                break;
                        case 'Y':               /* year, numeric, 4 digits */
+                       case 'V':               /* ISO-8601 year number of 
year, numeric, 4 digits */
                                size += 4;
                                break;
                        case 'M':               /* month, textual, 3 letters */
@@ -406,6 +407,7 @@
                        case 'S':               /* standard english suffix for 
the day of the month (e.g. 3rd, 2nd, etc) */
                        case 't':               /* days in current month */
                        case 'W':               /* ISO-8601 week number of 
year, weeks starting on Monday */
+                       case 'v':               /* ISO-8601 year number of 
year, numeric, 2 digits */
                                size += 2;
                                break;
                        case '\\':
@@ -641,27 +643,67 @@
                                strcat(Z_STRVAL_P(return_value), tmp_buff);
                                break;
                        case 'W':               /* ISO-8601 week number of 
year, weeks starting on Monday */
-                               wd = ta->tm_wday == 0 ? 6 : ta->tm_wday - 1; /* 
weekday */
-                               yd = ta->tm_yday + 1;                           
        /* days since January 1st */
-
-                               fd = (7 + wd - yd % 7+ 1) % 7;                  
/* weekday (1st January) */     
-
-                               /* week is a last year week (52 or 53) */
-                               if ((yd <= 7 - fd) && fd > 3){                  
-                                       wk = (fd == 4 || (fd == 5 && 
isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52;
-                               }
-                               /* week is a next year week (1) */
-                               else if (isleap((ta->tm_year+YEAR_BASE)) + 365 
- yd < 3 - wd){
-                                       wk = 1;
+                       case 'V':               /* ISO-8601 year number of 
year, numeric, 4 digits */
+                       case 'v':               /* ISO-8601 year number of 
year, numeric, 2 digits */
+                               yr = ta->tm_year + YEAR_BASE;
+                               yd = ta->tm_yday;
+                               wd = ta->tm_wday;
+                               while(1) {
+                                       int len, bot, top;
+                                       
+                                       len = isleap(yr) ? 366 : 365;
+                                       bot = ((yd + 11 - wd) % 7) - 3;
+                                       top = bot - (len % 7);
+                                       if (top < -3) {
+                                               top += 7;
+                                       }
+                                       top += len;
+                                       if (yd >= top) {
+                                               ++yr;
+                                               w = 1;
+                                               break;
+                                       }
+                                       if (yd >= bot) {
+                                               w = 1 + ((yd - bot) / 7);
+                                               break;
+                                       }
+                                       --year;
+                                       yd += isleap(yr) ? 366 : 365;
                                }
-                               /* normal week */
-                               else {
-                                       wk = (yd + 6 - wd + fd) / 7 - (fd > 3);
+                               switch (Z_STRVAL_PP(format)[i]) {
+                                       case 'W':               /* ISO-8601 
week number of year, weeks starting on Monday */
+                                               sprintf(tmp_buff, "%d", wk);  
/* SAFE */
+                                               break;
+                                       case 'V':               /* ISO-8601 
year number of year, numeric, 4 digits */
+                                               sprintf(tmp_buff, "%d", yr);  
/* SAFE */
+                                               break;
+                                       case 'v':               /* ISO-8601 
year number of year, numeric, 2 digits */
+                                               sprintf(tmp_buff, "%02d", yr % 
100);  /* SAFE */
+                                               break;
                                }
-
-                               sprintf(tmp_buff, "%d", wk);  /* SAFE */
                                strcat(Z_STRVAL_P(return_value), tmp_buff);
                                break;
+//                             wd = ta->tm_wday == 0 ? 6 : ta->tm_wday - 1; /* 
weekday */
+//                             yd = ta->tm_yday + 1;                           
        /* days since January 1st */
+
+//                             fd = (7 + wd - yd % 7+ 1) % 7;                  
/* weekday (1st January) */     
+
+//                             /* week is a last year week (52 or 53) */
+//                             if ((yd <= 7 - fd) && fd > 3){                  
+//                                     wk = (fd == 4 || (fd == 5 && 
isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52;
+//                             }
+//                             /* week is a next year week (1) */
+//                             else if (isleap((ta->tm_year+YEAR_BASE)) + 365 
- yd < 3 - wd){
+//                                     wk = 1;
+//                             }
+//                             /* normal week */
+//                             else {
+//                                     wk = (yd + 6 - wd + fd) / 7 - (fd > 3);
+//                             }
+
+//                             sprintf(tmp_buff, "%d", wk);  /* SAFE */
+//                             strcat(Z_STRVAL_P(return_value), tmp_buff);
+//                             break;
 
                        default:
                                length = strlen(Z_STRVAL_P(return_value));
@@ -773,22 +815,62 @@
                case 'I':
                        return ta->tm_isdst;
                case 'W':               /* ISO-8601 week number of year, weeks 
starting on Monday */
-                       wd = (ta->tm_wday == 0) ? 6 : ta->tm_wday - 1; /* 
weekday */
-                       yd = ta->tm_yday + 1;                                   
/* days since January 1st */
-                       fd = (7 + wd - yd % 7+ 1) % 7;                  /* 
weekday (1st January) */
-                       if ((yd <= 7 - fd) && fd > 3) {                 /* week 
is a last year week (52 or 53) */
-                               wk = (fd == 4 || (fd == 5 && 
isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52;
-                       }
-                       /* week is a next year week (1) */
-                       else if (isleap((ta->tm_year + YEAR_BASE)) + 365 - yd < 
3 - wd) {
-                               wk = 1;
+               case 'V':               /* ISO-8601 year number of year, 
numeric, 4 digits */
+               case 'v':               /* ISO-8601 year number of year, 
numeric, 2 digits */
+                       yr = ta->tm_year + YEAR_BASE;
+                       yd = ta->tm_yday;
+                       wd = ta->tm_wday;
+                       while(1) {
+                               int len, bot, top;
+                               
+                               len = isleap(yr) ? 366 : 365;
+                               bot = ((yd + 11 - wd) % 7) - 3;
+                               top = bot - (len % 7);
+                               if (top < -3) {
+                                       top += 7;
+                               }
+                               top += len;
+                               if (yd >= top) {
+                                       ++yr;
+                                       w = 1;
+                                       break;
+                               }
+                               if (yd >= bot) {
+                                       w = 1 + ((yd - bot) / 7);
+                                       break;
+                               }
+                               --year;
+                               yd += isleap(yr) ? 366 : 365;
                        }
-                       /* normal week */
-                       else {
-                               wk = (yd + 6 - wd + fd) / 7 - (fd > 3);
+                       switch (format) {
+                               case 'W':               /* ISO-8601 week number 
of year, weeks starting on Monday */
+                                       return wk;
+                                       break;
+                               case 'V':               /* ISO-8601 year number 
of year, numeric, 4 digits */
+                                       return yr;
+                                       break;
+                               case 'v':               /* ISO-8601 year number 
of year, numeric, 2 digits */
+                                       yr = yr % 100
+                                       return yr;
+                                       break;
                        }
-                       return wk;
                        break;
+//                     wd = (ta->tm_wday == 0) ? 6 : ta->tm_wday - 1; /* 
weekday */
+//                     yd = ta->tm_yday + 1;                                   
/* days since January 1st */
+//                     fd = (7 + wd - yd % 7+ 1) % 7;                  /* 
weekday (1st January) */
+//                     if ((yd <= 7 - fd) && fd > 3) {                 /* week 
is a last year week (52 or 53) */
+//                             wk = (fd == 4 || (fd == 5 && 
isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52;
+//                     }
+//                     /* week is a next year week (1) */
+//                     else if (isleap((ta->tm_year + YEAR_BASE)) + 365 - yd < 
3 - wd) {
+//                             wk = 1;
+//                     }
+//                     /* normal week */
+//                     else {
+//                             wk = (yd + 6 - wd + fd) / 7 - (fd > 3);
+//                     }
+//                     return wk;
+//                     break;
                default:
                        return 0;
        }


Regards,

Richard Quadling.




------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=33445&edit=1

Reply via email to