"French Vanilla" - and some sprinkles

“French Vanilla” is the name given (probably by Richard Morton) to Emmanuel Lévy’s very fast vanilla method for getting month numbers from AppleScript dates.

OS version: Any

set theDate to current date -- or any AppleScript date

(* "French Vanilla". Clue: 2629728 seconds is one twelfth of 365.24 days. *)

copy theDate to b
set b's month to January
set monthNum to 1 + (theDate - b + 1314864) div 2629728


(* "Vanille Américaine"? Richard Hartman later rethought the logic and came up
   with a shorter last line, which uses a divisor of any number of seconds
   between 28 days and 29 days. 2500000 is a round number in that range. *)

set monthNum to 1 + (theDate - b) div 2500000

(* Later still, I realised how Emmanuel's own maths could be optimised. *)
   
set monthNum to (theDate - b + 3944592) div 2629728


(* A Mac OS bug causes French Vanilla to error with dates before 1904. A fix for
  this is to switch to a year with an identical layout from *after* that period.
  Just add enough Gregorian cycles (multiples of 400 years) to get past 1903.
  The earliest year in the AppleScript date range is 1000, so adding 1200 years
  (37868342400 seconds) will cover all the possibilities. *)
   
set yearNum to theDate's year
if yearNum comes before 1904 then
  set theDate to theDate + 3.78683424E+10
  --> Same date and time, 1200 years later
end if
-- French Vanilla here


(* A good way to turn month numbers into strings padded with leading zeros where
   necessary is with: 'text 2 thru 3 of ((100 + monthNum) as string)'. But the
   numbers in French Vanilla can be adjusted to give a result that's 100 more
   than the month number anyway, so you could amaze your friends and clients
   with this code: :-) *)

set yearNum to theDate's year
if yearNum comes before 1904 then
  set theDate to theDate + 3.78683424E+10
end tell
copy theDate to b
set b's month to January
set monthNumStr to text 2 thru 3 of ¬
  (((theDate - b + 266917392) div 2629728) as string)

-- NG

Hello.

From Tiger and onward you can just coerce the month to integer.


set intMonth to month of (current date) as integer

See This post.

Best Regards

McUsr

Er ” thanks for that update, McUsr. :wink:

My final solution to this was to subtract the later date from the earlier one (which way round wasn’t affected by the bug), to compensate with a negative divisor, and to use Richard’s numbers for memorability:

copy theDate to b
set b's month to January
(b - theDate - 2500000) div -2500000

However, besides removing the need for French Vanilla, Tiger also cured the bug that required this form of it.

The fact that the “add 400 years” work-round doesn’t work with dates before October 1582 in Snow Leopard is an example of the damage that’s been done to AppleScript’s date arithmetic by the half-hearted imposition of the Julian Calendar on that system.

Hello.

I thought I’d mention it in the post above, since honestly looking at such calculations, and maybe have to verify them brings word like living daylight and such to my mind.

Whereas when I finally found out that I could coerce a month to an integer: thank God was the first immediate thought.

I think there are better solutions for what must be called Advanced date manipulation by some other means than AppleScripts Implementation. -It would of course slow things down a lot, but accuracy is the most important.

And by the way, as of lately I have experienced that SL (at least) has broken many of yesteryears date tricks, especially some of those which uses dates before 1000 AD.

Hopefully I’ll find the formulas I once had for calculating easter and share them with you.

Best Regards

McUsr

Here we go

Hello.

I see that butchers algorithm (which was the one I got) is already implemented. :slight_smile:

Thanks Stefan.

Best Regards

McUsr