Metric Time in Tau Station

If you’ve been following Tau Station’s progress, you know we’re creating a science fiction universe in Perl for people to enjoy. As of this writing, the time in Tau Station is 194.18/89:189 GCT.

A digital clock displaying Galactic Coordinated Time of 194.18/89:189
A digital clock displaying Galactic Coordinated Time of 194.18/89:189. The numbers are in the order year.day/segment:unit

“GCT” stands for “Galactic Coordinated Time” and that’s a variant of metric time. Our software developers wish we had that in the real world, but alas, we don’t.

The GCT time listed above is roughly 194 cycles and 18 days after the “Catastrophe,” the apocalyptic event that effectively serves as our “epoch.” There are 100 days in a year (note: these are now called “cycles” instead of years), 100 “segments” in a day (14.4 minutes each), and 1000 units in a segment (.864 seconds each).

We love the fact that figuring out the display time for GCT is this simple once you calculate the seconds which have elapsed since the start of the Catastrophe (note there are 86,400 seconds per day):

my $days = sprintf "%9.5f" => $elapsed_seconds / 86_400;
$days =~ m{^
    (?<cycle>\d+)
    (?<day>\d\d)
    \.
    (?<segment>\d\d)
    (?<unit>\d\d\d)
}ax;
my $gct = "$+{cycle}.$+{day}/$+{segment}:$+{unit} GCT";

So for the above code, if the number of seconds since the Catastrophe is 1,677,792,259, we divide that by 86,400 and get roughly 19418.89189. The regular expression then matches “194”, “18”, “89”, and “189”, which we then use to created our GCT of 194.18/89:189 GCT.

Due to imprecision in normal dates, we don’t get an exact round-trip conversion between regular DateTime objects and GCT, but so far we’ve not found them more than a second off.

Figuring out durations (D0.00/12.500 is a duration of 12 segments and 500 units) is similarly simple:

my $days = sprintf "%9.5f" => $duration_in_seconds / 86_400;
$days =~ m{^
    (?<cycles>\d+)
    (?<days>\d\d)
    \.
    (?<segments>\d\d)
    (?<units>\d\d\d)
}ax;
my $duration => "D$+{cycles}.$+{days}/$+{segments}:$+{units}";

Of course, since that means we often need to know the total number of seconds, we have this nasty bit of code to figure that out:

sub period (%args) {
    my $seconds = delete $args{seconds} // 0;
    $seconds += ( delete $args{minutes}  // 0 ) * 60;
    $seconds += ( delete $args{hours}    // 0 ) * 3_600;
    $seconds += ( delete $args{days}     // 0 ) * 86_400;

    # solar year
    $seconds += ( delete $args{years}    // 0 ) * 31_556_925.97474;
    $seconds += ( delete $args{units}    // 0 ) * .864;
    $seconds += ( delete $args{segments} // 0 ) * 864;
    if ( keys %args ) {
        my $unknown = join ', ' => sort keys %args;
        croak("Unknown keys to Veure::Util::Time::period: $unknown");
    }
    return round($seconds);
}

Metric time is lovely and easy. Regular time sucks.

We wanted to write code for the DBIx::Class ORM to use GCT objects instead of DateTimeobjects, but found too many assumptions about the use of DateTime in the DBIx::Class code, so we’ve decided not to go that for for now. We have even considered changing the length of the day slightly. That’s actually fairly trivial to do, once you use metric time. Since the Martian day is slightly longer than an Earth day, maybe we can get NASA to adopt metric time for Mars instead of Mars Coordinated Time.