scitash has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I am trying to convert from local time to GPS time (in weeks and days). It does not have to be so accurate that the 15 sec offset between UTC and GPS is accounted for. I've seen a solution going the other way, is there a simple method for going to GPS time? Thanks.

Replies are listed 'Best First'.
Re: Converting to GPS time
by dHarry (Abbot) on Mar 04, 2010 at 08:13 UTC

    local time = UTC + time offset, GPS = UTC without the correction for leap seconds.

    So you can correct your local time for the time offset and forget about the leap seconds. Or even simpler use gmtime().

    For example:

    #!/usr/local/bin/perl use strict; use warnings; my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my @weekDays = qw(Sun Mon Tue Wed Thu Fri Sat Sun); my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfW +eek, $dayOfYear) = gmtime(); my $year = 1900 + $yearOffset; my $GMTime = "$hour:$minute:$second, $weekDays[$dayOfWeek] $months[$mo +nth] $dayOfMonth, $year"; print $GMTime;

    I wonder why you're not interested in the leap second correction as accuracy is normally quite important?!

    Cheers

    Harry

      Hi Harry,

      Thanks for the help.

      The reason the 15 seconds was not a burning issue is that I just needed a script to access particular directories (they had been set up by someone else in the distant past), which contained the gps data. The directories themselves were set up by GPS week, but then there was overlap between weeks anyway. There was lots of duplication as you can imagine.

        You can calculate the GPS leap second offset with DateTime::LeapSecond.

        perl -e 'use lib qw{lib}; use DateTime::LeapSecond; print DateTime::LeapSecond::leap_seconds( (DateTime->now->utc_rd_value +s)[0] ) - DateTime::LeapSecond::leap_seconds( (DateTime->new(qw{year 1980 +month 1 day 6 time_zone UTC})->utc_rd_values)[0]), "\n";'
Re: Converting to GPS time
by Anonymous Monk on Mar 03, 2010 at 16:49 UTC

      DateTime does not currently support GPS Week calculations. The only package that I could find on CPAN which does support GPS Week is DateTime::Precise. (Which is not a "DateTime" object!)

      #Copyright (c) 2011 Michael R. Davis License BSD perl -e ' use DateTime; use Time::HiRes; use DateTime::Precise; my $dt=DateTime::Precise->new; printf "%s\n", $dt->asctime; my ($weeks, $seconds, $days)=$dt->gps_week_seconds_day; printf "Week: %s, Seconds: %s\n", $weeks, $seconds; print DateTime->new(qw{year 1980 month 1 day 6 time_zone UTC})->add(we +eks=>$weeks)->add(seconds=>$seconds), "\n"; '

      All of the Math is in DateTime::Precise::gps_week_seconds_day

      There is no license on DateTime::Precise. But, since the pre-fork is licensed "The Artistic License 2.0" this code should be as well. See RT 32186.

      sub gps_week_seconds_day { my $self = shift; my $epoch_seconds = $self->gps_seconds_since_epoch; my $week = int($epoch_seconds/Secs_per_week); my $seconds = $epoch_seconds - $week*Secs_per_week; my $day = int($seconds/Secs_per_day); ($week, $seconds, $day); }