This is my php class implementation of the terran computational calendar:
		
TCDate.class.php
<?php 
class TCDate {
    public 
$utc_leap_seconds = array("1972-06-30T23:59:60+00:00""1972-12-31T23:59:60+00:00""1973-12-31T23:59:60+00:00""1974-12-31T23:59:60+00:00""1975-12-31T23:59:60+00:00""1976-12-31T23:59:60+00:00""1977-12-31T23:59:60+00:00""1978-12-31T23:59:60+00:00""1979-12-31T23:59:60+00:00""1981-06-30T23:59:60+00:00""1982-06-30T23:59:60+00:00""1983-06-30T23:59:60+00:00""1985-06-30T23:59:60+00:00""1987-12-31T23:59:60+00:00""1989-12-31T23:59:60+00:00""1990-12-31T23:59:60+00:00""1992-06-30T23:59:60+00:00""1993-06-30T23:59:60+00:00""1994-06-30T23:59:60+00:00""1995-12-31T23:59:60+00:00""1997-06-30T23:59:60+00:00""1998-12-31T23:59:60+00:00""2005-12-31T23:59:60+00:00""2008-12-31T23:59:60+00:00""2012-06-30T23:59:60+00:00");
    public 
$tc_leap_second_years = array(2,3,4,5,6,7,8,9,10,11,12,13,15,18,20,21,22,23,24,26,27,29,36,39,42);
    public 
$tc_epoch = -864000;
    public 
$date = array('date'=>0);

    private 
$unix_leap_seconds;
    private 
$min_tc_leap_second_year;
    private 
$max_tc_leap_second_year;

    public function 
__construct($date='now'$is_leap_second=false) {
        
$this->min_tc_leap_second_year min($this->tc_leap_second_years);
        
$this->max_tc_leap_second_year max($this->tc_leap_second_years);

        foreach(
$this->utc_leap_seconds as $utc_leap_second) {
            
$datetime = new DateTime($utc_leap_second);
            
$this->unix_leap_seconds[] = intval($datetime->format('U'));
        }

        
$tc_timestamp $this->toTCTimestamp($date$is_leap_second);
        
$this->date $this->tcTimestampToDate($tc_timestamp);
    }


    
//takes a UTC date string or a UNIX timestamp and converts it into a TC timestamp
    
public function toTCTimestamp($date='now'$is_leap_second=false) {

        if(
preg_match('/^[\-]?[\d]*$/',$date)) { //is timestamp
            
if ($is_leap_second$date--;
            
$datetime = new DateTime();
            
$datetime->setTimestamp($date);
        }
        else { 
//is utc date
            
if (strstr($date':59:60')) {
                
$is_leap_second true;
                
$date str_replace(':59:60',':59:59',$date);
            }
            
$sign "";
            
$test_date $date;
            
$test_date_timezone substr($date, -5);
            if(
substr($date01) == '-') {
                
$sign '-';
                
$test_date substr($date1);
            }
            
$test_date_timezone str_replace(array("+",":"), ''substr($date, -5));
            
$test_date substr($test_date0, -5);
            
$date_arr preg_split"/(\-|T|:)/"$test_date);
            if (
$date_arr[0] == intval($date_arr[0]) && $date_arr[0] > 9999){
                
$datetime = new DateTime();
                
$datetime->setDate($date_arr[0], $date_arr[1], $date_arr[2]);
                
$datetime->setTime($date_arr[3], $date_arr[4], $date_arr[5]);
                
$test_date_timezone intval(substr($test_date_timezone0, -2))*3600 intval(substr($test_date_timezone, -2))*60;
                
$datetime->setTimezone($this->getDateTimeZone($test_date_timezone));
            } else {
                try {
                    
$datetime = new DateTime($date);
                } catch(
Exception $e){
                    
$datetime = new DateTime('now');
                }
            }
        }

        
$unix_timestamp intval($datetime->format('U'));

        
$leap_seconds 0;
        foreach (
$this->unix_leap_seconds as $unix_leap_second) {
            if (
$unix_timestamp+== $unix_leap_second && $is_leap_second) {
                
$unix_timestamp++;
                break;
            }
            if (
$unix_timestamp $unix_leap_second) break;
            else 
$leap_seconds++;
        }

        return 
$unix_timestamp $this->tc_epoch $leap_seconds;
    }

    public function 
tcTimestampToUTC ($tc_timestamp) {
        list(
$unix_timestamp$is_leap_second) = $this->tcTimestampToUNIX($tc_timestamp);
        
$unix_timestamp -= $is_leap_second;
        
$datetime = new DateTime();
        
$datetime->setTimestamp($unix_timestamp);
        
$datetime->setTimezone($this->getDateTimeZone());
        
$date $datetime->format(DateTime::ATOM);
        if (
$is_leap_second$date str_replace('59:59''59:60'$date);
        return 
$date;
    }

    public function 
isLeapSecond($unix_timestamp=''$date=''$is_leap_second=0) {
        if (
in_array($date$this->utc_leap_seconds) || $is_leap_second) return 1;
        if (
in_array($unix_timestamp$this->unix_leap_seconds) && $date!='' && strstr($date':59:60')) return 1;
        return 
0;
    }

    
//returns a list of a unix_timestamp and whether or not it's the the first second of a 2 second timestamp second
    
public function tcTimestampToUNIX($tc_timestamp) {
        
$unix_timestamp $tc_timestamp $this->tc_epoch;

        foreach (
$this->unix_leap_seconds as $unix_leap_second) {
            if (
$unix_timestamp == $unix_leap_second) return array($unix_timestamp1);
            if (
$unix_timestamp $unix_leap_second$unix_timestamp--;
            if (
$unix_timestamp $unix_leap_second) break;
        }
        return array(
$unix_timestamp0);
    }

    public function 
tcTimestampToDate($tc_timestamp=0$year_base=''$offset=0) {
        
$designator 'TC'.($year_base == ''?''intval($year_base));
        list(
$unix_timestamp$is_leap_second) = $this->tcTimestampToUNIX($tc_timestamp);
        
$date = array('year'=>0,'month'=>0,'day'=>0,'hour'=>0,'minute'=>0,'second'=>0,'fraction'=>0,'designator'=>$designator,'year_base'=>($year_base == ''?''intval($year_base)),'offset'=>$offset'tc_timestamp'=>$tc_timestamp'unix_timestamp'=>$unix_timestamp'is_leap_second'=>$is_leap_second);
        list(
$date['year'], $seconds_left) = $this->getYear(intval($tc_timestamp)+intval($offset), $year_base);

        
$date['month'] = floor($seconds_left / (28*$this->s('day')));
        
$seconds_left -= $date['month'] * (28*$this->s('day'));

        
$date['day'] = floor($seconds_left $this->s('day'));
        
$seconds_left -= $date['day'] * $this->s('day');

        
$date['hour'] = floor($seconds_left $this->s('hour'));
        
$seconds_left -= $date['hour'] * $this->s('hour');

        
$date['minute'] = floor($seconds_left $this->s('minute'));
        
$seconds_left -= $date['minute'] * $this->s('minute');

        
$date['second'] = floor($seconds_left);
        
$seconds_left -= $date['second'];

        
$seconds_left explode('.'strval($seconds_left));
        if (isset(
$seconds_left[1])) $date['fraction'] = intval($seconds_left[1]);

        
$fraction = ($date['fraction'] != '.'.$date['fraction'] : '');
        
$date['datemod'] = 0
        
$date['date'] = "{$date['year']}.{$date['month']}.{$date['day']},{$date['hour']}.{$date['minute']}.{$date['second']}$fraction $designator";

        
$date['padded_date'] = $this->pad($date['year'])."-".$this->pad($date['month'])."-".$this->pad($date['day'])." ".$this->pad($date['hour']).":".$this->pad($date['minute']).":".$this->pad($date['second'])."$fraction $designator";

        return 
$date;
    }

    public function 
pad ($unit$num=2) {
        return 
str_pad($unit$num'0'STR_PAD_LEFT);
    }


    public function 
getYear($tc_timestamp=0$year_base='') {
        if (
$tc_timestamp 0) {
            
$offsets ceil(abs($tc_timestamp)/$this->s('128years'));
            list(
$year$seconds_left) = $this->getYear(($offsets*$this->s('128years')) + $tc_timestamp0);
            return array(
$year-($offsets*128), $seconds_left);
        }

        
$seconds_left $tc_timestamp;
        
$upper_limit ceil($this->max_tc_leap_second_year+1/128)*128;
        for (
$year=0$seconds_left >= && $year $upper_limit$year++) {
            
$seconds_left -= $this->sInYear($year$year_base);
        }

        if (
$seconds_left 0) {
            
$year--;
            
$seconds_left += $this->sInYear($year$year_base);
            return array(
$year$seconds_left);
        }

        
$_128_cycles floor($seconds_left $this->s('128years'));
        
$year += 128 $_128_cycles;
        
$seconds_left -= $_128_cycles $this->s('128years');


        
$first_4_cycles floor($seconds_left / (4*$this->s('year')));
        
        if (
$first_4_cycles 0) {
            
$year += 4;
            
$seconds_left -= $this->s('year');

            
$_4_cycles floor($seconds_left $this->s('4years'));
            
$year += $_4_cycles;
            
$seconds_left -= $_4_cycles $this->s('128years');

            if(
floor($seconds_left / ($this->s('year')+$this->s('day')) ) ) {
                
$year += 1;
                
$seconds_left -= $_4_cycles $this->s('128years');
            }
        }

        
$_1_cycles floor($seconds_left $this->s('year'));
        
$year += $_1_cycles;
        
$seconds_left -= $_1_cycles $this->s('year');

        return array(
$year$seconds_left);
    }

    
//returns the number of second in a specifc unit range or the TC timetamp corresponding to a UTC date or UNIX timestamp 
    
public function sInYear($year=0$year_base='') {
        
$seconds $this->s('year') + ($year%4==&& $year%128!=$this->s('day') : 0);
        if (
$year $this->min_tc_leap_second_year || ($year_base != '' && intval($year_base) < $year) || $year $this->max_tc_leap_second_year) {}
        else {
            
$leap_second_count_by_year array_count_values($this->tc_leap_second_years);
            if (isset(
$leap_second_count_by_year[$year])) $seconds += $leap_second_count_by_year[$year];
        }

        return 
$seconds;
    }

    
//returns the number of second in a specifc unit range or the TC timetamp corresponding to a UTC date or UNIX timestamp 
    
public function s($str='now') {
        switch (
$str) {
            case 
'default': return $this->toTCTimestamp($str);
            case 
'second': return 1;
            case 
'minute': return 60;
            case 
'hour': return 3600;
            case 
'day': return 86400;
            case 
'year': return 31536000;
            case 
'4years': return 126230400;
            case 
'128years': return 4039286400;
        }
    }

    private function 
getDateTimeZone($timezone="UTC") {
        if (
is_numeric($timezone)) $timezone  timezone_name_from_abbr(""intval($timezone), 0);
        
$date_timezone = new DateTimeZone("UTC");
        try {
            
$date_timezone = new DateTimeZone($timezone);
        } catch(
Exception $e){}
        return 
$date_timezone;
    }

    public function 
tcYearToTCTimestamp($year) {
        
$timestamp 0;
        if (
$year 0) {
            for (
$i=$year$i 0$i++) {
                
$timestamp -= $this->sInYear($i);
            }
        }
        else {
            for (
$i=0$i $year$i++) {
                
$timestamp += $this->sInYear($i);
            }
        }
        return 
$timestamp;
    }
}




function 
tcdate($date='now'$is_leap_second=0) {
    
$date = new TCDate($date$is_leap_second);
    return 
$date->date;
}
function 
tcdateToHTML($date=array(), $delimiters=array('.','.',',','.','.',' '), $units=''$pad=0$class="now") {
    if (empty(
$units)) $units=array('year','month','day','hour','minute','second','designator');
    
$i=0;
    
$html '';
    foreach(
$units as $unit) {
        
$delimiter = (isset($delimiters[$i])?$delimiters[$i]:'');
        if (isset(
$date[$unit])) $html .= "<span".($unit == 'designator' " data-tc_timestamp=\"{$date['tc_timestamp']}\"":"")." data-designator=\"{$date['designator']}\" data-class=\"$class\" data-unit=\"$unit\"".($pad " data-pad=\"$pad\"":'').">{$date[$unit]}</span>$delimiter";
        
$i++;
    }
    return 
$html;
}
?>