Saturday, January 31, 2009

Stardate

As promised, today was to be a celebration of one year of Reusable Code. That celebration was overshadowed by a catastrophic hard drive failure early this morning, but luckily I managed to perform a successful recovery with Windows Home Server (after much trial and error).

The function I'm going to share this week is my favorite: calculating the stardate for a given Gregorian calendar date. If you're not familiar with the various Star Trek television series, you might not know what a stardate is. It's a fictional method of measuring time, which is supposed to solve the problems of relativistic time dilation caused by travelling at high velocity. In reality, it progressed at the same rate as time here on Earth.

The method of stardate calculation used here is based on Star Trek: the Next Generation, Star Trek: Deep Space Nine, and Star Trek: Voyager. It does not take the Original Series into account. Also, it is calibrated with the airdates of the television series, not with real world dates. That is to say, if you pass in today's date, it does not return the stardate corresponding to today's date in the 21st century, but today's date in the 24th century Star Trek universe. This is intended to be beneficial for roleplaying games.

ASP

  1. function stardate(someDateTime)
  2.     dim season
  3.     dim episode
  4.     dim fractime
  5.     season = cStr(Year(someDateTime) - 1947)
  6.     episode = str_pad(Round(1000 / 366 * DatePart("y", someDateTime), 0), 3, "0", "left")
  7.     fractime = left(cStr((Hour(someDateTime) * 60 + Minute(someDateTime)) / 144), 1)
  8.     stardate = season & episode & "." & fractime
  9. end function

It is important to note here that for the above function, you will also need my str_pad() function.

PHP

  1. function stardate($timestamp)
  2. {
  3.     $season = date("Y", $timestamp) - 1947;
  4.     $episode = str_pad(round(1000 / 366 * (date("z", $timestamp) + 1)), 3, "0", STR_PAD_LEFT);
  5.     $fractime = substr((date("g", $timestamp) * 60 + date("i", $timestamp)) / 144, 0, 1);
  6.     return $season . $episode . "." . $fractime;
  7. }

I'm somewhat ashamed to admit that there are some "magic" numbers at play here. When I originally wrote this function, I had not intended to make it open source, but events over the past year have led me to the realization that if I did not, it would become lost in the sands of time.

Once upon a time I also wrote some code to calculate the difference between two stardates, but it was only written in PHP. I'll have to port it to ASP and perhaps have it ready for next Saturday's posting, but no promises.


No comments: