I recently started working on a
Vana'diel (
Final Fantasy XI) clock written in
Cocoa. My reasoning for doing this (when there really isn't any need for
another Vana'diel clock) is two-fold:
1. I want to learn Cocoa and a good way to learn something is to associate it with something you already enjoy (ie. Final Fantasy).
2. The only Mac OS X Vana'diel clock out there is old, lacks some info I'd like it to have, and doesn't really have the nicest interface (text only - no eye candy).
The biggest hump for me so far was figuring out how to calculate the time. I looked at some javascript clocks people had written but I didn't like the fact that they all seem based on some arbitrary date. I wanted something that could go all the way back to the beginning of Vana'diel time. The Vana'diel epoch (the Vana'diel big bang, if you will). I decided, I wanted to write the algorithim myself, differently from all the ways I've seen it done. Fortunately, I found a
great resource explaining some of the critical information needed to understand how Vana'diel time works. Thanks Miwarre!
I wanted to rapidly prototype a simple clock to test my algorithm and I figured I could do it easily and quickly enough using Applescript. I've posted the script here for anyone else trying to work with Vana'diel time.
When I re-wrote this for Cocoa, I didn't use the "seconds since epoch" constant I used here because I found a cleaner way with NSCalendarDate. The jist of it is that I can create an NSCalendarDate object using the "earth" date that corresponds to the Vana'diel epoch date and the effect is the same.
I have to give a big special thanks to my girlfriend who checked my work (by hand!) and found that I'd originally used the wrong value in the unix_seconds_since_epoch_at_vana_epoch (it was missing the extra 86400 seconds for the 1968 leap year). This has since been corrected in this script.
The Applescript simply returns the current Vana'diel date.
set unix_seconds_since_epoch to do shell script "date \"+%s\""
set vana_rate_mod to 25 -- Vana time runs 25 times faster than earth time.
set vana_seconds_per_day to 86400
set vana_days_per_week to 8
set vana_days_per_month to 30
--This value is derived from the amount of seconds that elapsed between the
--Vana'diel epoch (0001/01/01 00:00) which is 1967/02/09 15:00 and the
--UNIX epoch which is 1970/01/01 00:00. This includes a leap year (1968/02/29)
--which adds an extra 86400 seconds. Since all calculations are based off seconds
--since the UNIX epoch, we need to add this value to any UNIX seconds we use.
set unix_seconds_since_epoch_at_vana_epoch to 91270800
-- Find out the Vana'diel minutes since the Vana'diel epoch.
set vana_seconds_since_epoch to (unix_seconds_since_epoch + ¬
unix_seconds_since_epoch_at_vana_epoch) * vana_rate_mod
set vana_days_since_epoch to ¬
(vana_seconds_since_epoch / vana_seconds_per_day)
set vana_weeks_since_epoch to ¬
(vana_days_since_epoch / vana_days_per_week)
set vana_months_since_epoch to ¬
(vana_days_since_epoch / vana_days_per_month)
set v_year to round (vana_days_since_epoch / 360) rounding up
set v_month to round ((vana_months_since_epoch) mod 12) rounding up
set v_day to round (vana_days_since_epoch) mod 30 rounding up
set v_hour to round ((vana_seconds_since_epoch mod ¬
vana_seconds_per_day) / 3600) rounding down
set v_minute to round (((vana_seconds_since_epoch mod ¬
vana_seconds_per_day) mod 3600) / 60) rounding down
if v_minute is less than 10 then
set v_minute to "0" & v_minute
end if
set v_second to round (((vana_seconds_since_epoch mod ¬
vana_seconds_per_day) mod 3600) mod 60) rounding down
if v_second is less than 10 then
set v_second to "0" & v_second
end if
set v_wday to round (vana_days_since_epoch mod vana_days_per_week) rounding up
set week_days to {"Firesday", "Earthsday", "Watersday", "Windsday", ¬
"Iceday", "Lightningsday", "Lightsday", "Darksday"}
return (v_year & "/" & v_month & "/" & v_day & " " & ¬
v_hour & ":" & v_minute & ":" & v_second & " " & ¬
item (v_wday) of week_days) as string