Suchen / SearchNavigation |
AppleScript Holidays and Calendar Conversions via PHP12 Sep 2010 - 15:26 AbstractThis page provides some code snippets that can be used as replacements for some of the more complex functions, contained in my Calendar Functions collection. They use PHP commands rather than doing the calculation in AppleScript. They deal with Easter and with conversions between calendars. All snippets here will not run on Mac OS prior to 10.6 (Snow Leopard). Advantages: Code is very compact and all handlers are self-contained, i.e. they do not depend on other handlers. That makes copy / paste easier. Disadvantages: These handlers are much slower than the functions I wrote in pure AppleScript. IntroductionWhen I checked the PHP installation on my Mac recently, I found that it does include the calendar extension now. This PHP extension has functions to calculate Easter and to convert dates between the Gregorian, Julian and Hebrew (or Jewish) calendars. (They implement the French Revolutionary Calendar as well, but I will ignore this here.) I implemented these functions in AppleScript itself, because they were not available in PHP on Mac previously. Of course, those functions are much more complex than simply calling PHP to do the job. But calling of PHP via "do shell script” is far slower. On a testing machine, I tried one of the more complex handlers, “heb_to_cdn”. (It is a handler, converting a Hebrew date to a Julian Day Number.) The version using PHP and “do shell script” needed some 9.43333 seconds for 100 conversions. The same function in the pure AppleScript code needed 0.00833 seconds! That is a factor of 1000. There should be an even larger difference for the other, less complex functions like Easter. This speed difference will be no problem, if you need just one or two conversion in a script. So the shorter code which is self-contained for all handlers may be a good idea. But if you need to calculate holidays for several years, use the pure AppleScript handlers from the other page. The handlers have the same names as the corresponding ones in the calendar function collection. They return similar values. Hence, one version may simply replace the other one in a script. I did not add all the argument checking code of the original calendar functions, to keep code simple. If you want to check, if months and days are in a reasonable range, add that code for yourself. The Easter functions use “current date” to create a new date object and change it afterwards. Done this way, it will run under any language settings of the system, if copied / pasted from the Web browser into the Script Editor. Julian Date to Julian Day NumberThe handler takes three arguments, the year, month and day of the date in the Julian calendar. It returns an integer, the Chronological Julian Day Number of that date. on julian_to_cdn(y, m, d) set php_script to ¬ " $cal = CAL_JULIAN; $m = (int) $argv[2]; $d = (int) $argv[3]; $y = (int) $argv[1]; $cdn = cal_to_jd ( $cal, $m, $d, $y ); print $cdn; " set php_script to quoted form of php_script set php_call to "php -r " set args to quoted form of (y as string) & ¬ " " & quoted form of (m as string) & ¬ " " & quoted form of (d as string) set cdn to (do shell script php_call & php_script & " " & args) as integer return cdn end julian_to_cdn Hebrew Date to Julian Day NumberThe handler takes three arguments, the year, month and day of the date in the Hebrew calendar. The year is anno mundi (“Year of the World”, “Year since Creation”), months are counted from Nisan as 1. It returns an integer, the Chronological Julian Day Number of that date. on heb_to_cdn(y, m, d) set php_script to ¬ " $cal = CAL_JEWISH; $m = (int) $argv[2]; $d = (int) $argv[3]; $y = (int) $argv[1]; $cdn = cal_to_jd ( $cal, $m, $d, $y ); print $cdn; " set php_script to quoted form of php_script set php_call to "php -r " -- PHP counts Tishri as month 1, -- my functions count Nisan as month 1. -- Rotate the month value set m to (m + 6) mod 13 + 1 set args to quoted form of (y as string) & ¬ " " & quoted form of (m as string) & ¬ " " & quoted form of (d as string) set cdn to (do shell script php_call & php_script & " " & args) as integer return cdn end heb_to_cdn Julian Day Number to Julian DateThe handler takes a Chronological Julian Day Number and returns a record with the year, month and day, belonging to that day number in the Julian calendar.
on cdn_to_julian(cdn)
set php_call to "php -r "
set php_script to ¬
"
$x = cal_from_jd ( (int) $argv[1] , CAL_JEWISH );
print $x['year'] . '-' . $x['month'] . '-' . $x['day'];
"
set php_script to quoted form of php_script
set args to quoted form of (cdn as text)
set r to (do shell script (php_call & php_script & " " & args))
set old_delims to AppleScript's text item delimiters
set AppleScript's text item delimiters to "-"
set {The_year, The_month, The_day} to every text item of r
set AppleScript's text item delimiters to old_delims
set The_year to The_year as integer
set The_month to The_month as integer
set The_day to The_day as integer
-- rotate month since I count from Nisan
set The_month to (The_month + 5) mod 13 + 1
return {year:The_year, month:The_month, day:The_day}
end cdn_to_julian
Julian Day Number to Hebrew DateThe handler takes a Chronological Julian Day Number and returns a record with the year, month and day, belonging to that day number in the Hebrew calendar.
on cdn_to_heb(cdn)
set php_call to "php -r "
set php_script to ¬
"
$x = cal_from_jd ( (int) $argv[1] , CAL_JEWISH );
print $x['year'] . '-' . $x['month'] . '-' . $x['day'];
"
set php_script to quoted form of php_script
set args to quoted form of (cdn as text)
set r to (do shell script (php_call & php_script & " " & args))
set old_delims to AppleScript's text item delimiters
set AppleScript's text item delimiters to "-"
set {The_year, The_month, The_day} to every text item of r
set AppleScript's text item delimiters to old_delims
set The_year to The_year as integer
set The_month to The_month as integer
set The_day to The_day as integer
-- rotate month since I count from Nisan
set The_month to (The_month + 5) mod 13 + 1
return {year:The_year, month:The_month, day:The_day}
end cdn_to_heb
Date of Easter (Gregorian) in a YearThe handler takes the number of a year as the argument. It returns an AppleScript date object for Gregorian Easter in that year.
on easter_greg_date(The_year)
set php_script to ¬
"
print ( easter_days ( $argv[1], CAL_GREGORIAN ) );
"
set php_script to quoted form of php_script
set php_call to "php -r "
set args to quoted form of (The_year as text)
set e_days to (do shell script php_call & php_script & " " & args) as integer
set ed to current date
set {time of ed, day of ed, month of ed, year of ed} to {0, 21, 3, The_year}
set ed to ed + e_days * days
return ed
end easter_greg_date
Date of Easter (Julian) in a YearThe handler takes the number of a year as the argument. It returns an AppleScript date object for Julian Easter in that year. Note that the code is almost the same as for the Gregorian Easter. Just one PHP constant is different.
on easter_jul_date(The_year)
set php_script to ¬
"
print ( easter_days ( $argv[1], CAL_JULIAN ) );
"
set php_script to quoted form of php_script
set php_call to "php -r "
set args to quoted form of (The_year as text)
set e_days to (do shell script php_call & php_script & " " & args) as integer
set ed to current date
set {time of ed, day of ed, month of ed, year of ed} to {0, 21, 3, The_year}
set ed to ed + e_days * days
return ed
end easter_jul_date
|
AppleScript Date Objects and Calculations |