[Phil Ehrens] * GMT or UTC to GPS Description: Given a GMT or UNIX epoch time, return GPS time. If no argument is given, return current GPS time. Parameters: time - UNIX epoch seconds, or a date and time: "01/06/80 01:01:01" Usage: set gpstime [ gpsTime "04/20/99 01:20:59" ] or set gpstime [ gpsTime 91232121 ] or set gpstime [ gpsTime 01/20/01 ] or set gpstime [ gpsTime 01/20/2001 ] (of course, you can't calculate GPS time in the future unless you know when the leap seconds are...) or set gpstime [ gpsTime now ] Comments: This procedure must be manually updated when a new leap-second is added. see: ftp://tycho.usno.navy.mil/pub/series/ser14.txt The GPS epoch started at 0 at 02/06/80 00:00:00 GMT. Should put leap seconds in a separate file and check daily for updates. proc gpsTime { { time "" } } { ;## the difference between the UNIX epoch and GPS epoch. set epochdiff 315964819 ;## 1972-01-01 00:00:00 UTC was 1972-01-01 00:00:10 TAI. set offset 10 ;## assumes 00:00:00. set leapdates { 06/30/1972 12/31/1972 12/31/1973 12/31/1974 12/31/1975 12/31/1976 12/31/1977 12/31/1978 12/31/1979 06/30/1981 06/30/1982 06/30/1983 06/30/1985 12/31/1987 12/31/1989 12/31/1990 06/30/1992 06/30/1993 06/30/1994 12/31/1995 06/30/1997 01/01/1999 } ;## quick short-circuit for "now". if { [ regexp {^$|now} $time ] } { set time [ clock seconds ] set fudge [ expr $offset + [ llength $leapdates ] ] return [ expr $time - $epochdiff + $fudge ] } ;## build the lookup table in gmt seconds foreach date $leapdates { lappend leapsecs [ clock scan $date -gmt 1 ] } ;## canonicalise input to UNIX epoch seconds if { ! [ regexp {^-?[0-9]+$} $time ] } { if { [ catch { set time [ clock scan $time -gmt 1 ] } err ] } { return -error code $err } } foreach sec [ lsort -integer $leapsecs ] { if { $time <= $sec } { set index [ lsearch $leapsecs $sec ] break; } ;## if we fall off the end of the list set index [ llength $leapsecs ] } set offset [ expr $offset + $index ] set gpstime [ expr $time - $epochdiff + $offset ] return $gpstime } * GPS to UTC Description: Converts GPS epoch time to UNIX epoch time Parameters: time - GPS time in GPS seconds, leap second corrected Usage: set utctime [ utcTime gpsTime ] Comments: This is what happens when you adopt GPS time as your standard! grumble grumble... Yes, it is right -- try "clock format [ utcTime 0 ] -gmt 1" proc utcTime { { time "" } } { if { ! [ regexp {^-?[0-9]+$} $time ] } { return -code error "utcTime requires integer argument" } ;## the difference between the UNIX epoch and GPS epoch. set epochdiff 315964819 ;## 1972-01-01 00:00:00 UTC was 1972-01-01 00:00:10 TAI. set offset 10 ;## assumes 00:00:00. set leapdates { 06/30/1972 12/31/1972 12/31/1973 12/31/1974 12/31/1975 12/31/1976 12/31/1977 12/31/1978 12/31/1979 06/30/1981 06/30/1982 06/30/1983 06/30/1985 12/31/1987 12/31/1989 12/31/1990 06/30/1992 06/30/1993 06/30/1994 12/31/1995 06/30/1997 01/01/1999 } foreach date $leapdates { lappend leapsecs [ gpsTime $date ] } foreach sec [ lsort -integer $leapsecs ] { if { $time <= $sec } { set index [ lsearch $leapsecs $sec ] break; } ;## if we fall off the end of the list set index [ llength $leapsecs ] } set offset [ expr $offset + $index ] set utctime [ expr $time + $epochdiff - $offset ] return $utctime }