I wrote a quick little support script which provides a set of functions generally related to the daycycle and the sun.
daycycles.cs (106 raw LOC)
float getDayCycleTime()
Returns the current progress of the daycycle as a floating point value between 0 and 1 while properly accounting for daycycle length and offset. The start of a cycle (0) is the point where the sun sets (elevation at 0 degrees).
int getDayCycleStage(float time)
Using time as the progress of the cycle, returns the "stage" of the daycycle as an integer, which can be either 0, 1, 2 or 3. This represents each quarter of the cycle (dawn, day, dusk and night).
str getDayCycleStageName(int stage)
Returns a friendly name for the stage. 0 => dawn, 1 => day, 2 => dusk, 3 => night.
int getMSToNextDayCycleStage(float time)
Using time as the progress of the cycle, returns the precise total number of milliseconds until the next quarter of the cycle is reached as an integer.
str getDayCycleTimeString(float time[, bool mod12])
Formats the cycle progress time as a friendly string. For example, given 0.65, it returns "15:36". If mod12 is true, the time is formatted using 12 hour time - instead of "15:36", "3:36 PM" is returned.
Vector3F getSunVector()
Returns an unit vector pointing directly to the sun's current elevation and azimuth. Works both with the daycycle enabled and disabled.
bool isPointInShadow(Vector3F pos[, SimObject avoid])
Returns whether or not an object is casting a shadow on the position pos.
void syncDayCycle()
Assuming the daycycle is enabled and the daycycle length is 86400, adjusts the daycycle offset so that the in-game daycycle is synced with the host's timezone.
Yes, all functions in this are pinpoint accurate and do not crash servers like Lugnut's.