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 <[email protected]> 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