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

Reply via email to