|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2005-06-23 10:17 UTC] 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. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 01 17:00:02 2025 UTC |
Already implemented in PHP 5.1 as date('o').