Woops, sorry. Here's the file renamed to .txt. Thanks for the tip!
--Kris On Tue, Aug 10, 2010 at 12:50 PM, Michael Maclean <m...@php.net> wrote: > On 10/08/10 20:28, Kris Craig wrote: > >> Sorry, I guess it would help if I actually attached the patch..... Here >> it is. >> > > The list strips attachments with filenames ending in something other than > .txt - resend or perhaps put it online somewhere? > > -- > Cheers, > Michael >
--- C:\dev\PHP\5.3.2_linux_diffbase\ext\date\php_date.c Thu Feb 11 15:37:50 2010 +++ php_date.c Tue Aug 10 11:58:44 2010 @@ -967,6 +967,10 @@ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +static char *season_names[] = { + "Winter", "Spring", "Summer", "Fall" +}; + static char *english_suffix(timelib_sll number) { if (number >= 10 && number <= 19) { @@ -982,6 +986,188 @@ } /* }}} */ +/* {{{ Astronomical season equinox/solstice calculations. --Kris */ +float php_date_get_equinox_jde( timelib_sll y, int season ) +{ + float jde, y2; + + //Equations derived from "Astronomical Algorithms" by Jean Meeus. --Kris + + y2 = (y - 2000) / 1000; + + switch ( season ) + { + default: + case 0: + //December solstice, start of winter. --Kris + jde = 2451900.05952 + (365242.74049 * y2) - (0.06223 * pow( y2, 2 )) - (0.00823 * pow( y2, 3 )) + (0.00032 * pow( y2, 4 )); + break; + case 1: + //March equinox, start of spring. --Kris + jde = 2451623.80984 + (365242.37404 * y2) + (0.05169 * pow( y2, 2 )) - (0.00411 * pow( y2, 3 )) - (0.00057 * pow( y2, 4 )); + break; + case 2: + //June solstice, start of summer. --Kris + jde = 2451716.56767 + (365241.62603 * y2) + (0.00325 * pow( y2, 2 )) + (0.00888 * pow( y2, 3 )) - (0.00030 * pow( y2, 4 )); + break; + case 3: + //September equinox, start of fall. --Kris + jde = 2451810.21715 + (365242.01767 * y2) - (0.11575 * pow( y2, 2 )) + (0.00337 * pow( y2, 3 )) + (0.00078 * pow( y2, 4 )); + break; + } + + return jde; +} + +int gregorian_base_from_jd( float jd ) +{ + int Z, A, a; + + jd += 0.5; + + Z = (int) jd; + + if ( Z < 2299161 ) + { + A = Z; + } + else + { + a = (int) ((Z - 1867216.25) / 36524.25); + A = Z + 1 + a - (int) (a / 4); + } + + return (A + 1524); +} + +float dayofmonth_from_jd( float jd ) +{ + int B, C, D, E; //Ambiguity aside, I'm just keeping the variable names consistent with the original formulas. --Kris + float F; + + B = (int) gregorian_base_from_jd( jd ); + C = (int) ((B - 122.1) / 365.25); + D = (int) (365.25 * C); + E = (int) ((B - D) / 30.6001); + F = (float) (jd + 0.05) - (int) (jd + 0.05); + + return (B - D - (int) (30.6001 * E) + F); +} + +int month_from_jd( float jd ) +{ + int B, C, D, E; + float F; + + B = (int) gregorian_base_from_jd( jd ); + C = (int) ((B - 122.1) / 365.25); + D = (int) (365.25 * C); + E = (int) ((B - D) / 30.6001); + F = (float) (jd + 0.05) - (int) (jd + 0.05); + + if ( E < 14 ) + { + return (E - 1); + } + else + { + return (E - 13); + } +} + +int year_from_jd( float jd ) +{ + int B, C; + + B = (int) gregorian_base_from_jd( jd ); + C = (int) ((B - 122.1) / 365.25); + + if ( month_from_jd( jd ) > 2 ) + { + return (C - 4716); + } + else + { + return (C - 4715); + } +} + +/* }}} */ + +/* {{{ Get the current season. If hemisphere cannot be determined, assume north. --Kris */ +int php_date_get_season( timelib_sll y, timelib_sll m, timelib_sll d, char *timezone ) +{ + int hemisphere, season; + + //TODO - return (Season# + Hemisphere#) % 4; //Where Hemisphere# is 0 for North, 2 for South. --Kris + hemisphere = 0; + + //TODO? - Currently rounds to the day. Should we make it accurate down to the second instead? It can be done easily enough. --Kris + switch ( m ) + { + default: + case 1: + case 2: + season = 0; + break; + case 3: + if ( (int) dayofmonth_from_jd( php_date_get_equinox_jde( y, 1 ) ) > d ) + { + season = 0; + } + else + { + season = 1; + } + break; + case 4: + case 5: + season = 1; + break; + case 6: + if ( (int) dayofmonth_from_jd( php_date_get_equinox_jde( y, 2 ) ) > d ) + { + season = 1; + } + else + { + season = 2; + } + break; + case 7: + case 8: + season = 2; + break; + case 9: + if ( (int) dayofmonth_from_jd( php_date_get_equinox_jde( y, 3 ) ) > d ) + { + season = 2; + } + else + { + season = 3; + } + break; + case 10: + case 11: + season = 3; + break; + case 12: + if ( (int) dayofmonth_from_jd( php_date_get_equinox_jde( y, 0 ) ) > d ) + { + season = 3; + } + else + { + season = 0; + } + break; + } + + return (season + hemisphere) % 4; +} +/* }}} */ + /* {{{ day of week helpers */ char *php_date_full_day_name(timelib_sll y, timelib_sll m, timelib_sll d) { @@ -1067,6 +1253,10 @@ case 'L': length = slprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break; case 'y': length = slprintf(buffer, 32, "%02d", (int) t->y % 100); break; case 'Y': length = slprintf(buffer, 32, "%s%04lld", t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break; + + /* season */ + case 'v': length = slprintf(buffer, 32, "%s", season_names[(int) php_date_get_season( t->y, t->m, t->d, + localtime && t->zone_type == TIMELIB_ZONETYPE_ID ? t->tz_info->name : "" )]); break; /* time */ case 'a': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break;
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php