Ticks between Unix epoch and GPS epoch
Categories:
Understanding the Time Difference: Unix Epoch vs. GPS Epoch

Explore the fundamental differences between Unix and GPS time epochs, calculate the offset, and learn how to convert between these critical timekeeping systems.
In the world of computing and navigation, accurate timekeeping is paramount. Two widely used time systems, Unix Time and GPS Time, serve different purposes and have distinct starting points, known as epochs. Understanding the relationship and the precise offset between these epochs is crucial for applications that integrate data from both systems, such as timestamping satellite data or synchronizing network operations with GPS receivers.
Defining the Epochs
An epoch is a specific point in time used as a reference for measuring time. All time values in a particular system are then counted as units (e.g., seconds) from that epoch. The choice of epoch is arbitrary but fundamental to the system's design.
Unix Epoch: January 1, 1970, 00:00:00 UTC
The Unix epoch is defined as January 1, 1970, at 00:00:00 Coordinated Universal Time (UTC). Unix time, also known as POSIX time or epoch time, is a system for describing a point in time, defined as the number of seconds that have elapsed since the Unix epoch, excluding leap seconds. This makes it a simple, linear count of seconds, widely used in operating systems and programming languages.
GPS Epoch: January 6, 1980, 00:00:00 UTC
The GPS epoch is defined as January 6, 1980, at 00:00:00 UTC. GPS Time (GPST) is an atomic time scale maintained by the atomic clocks aboard GPS satellites. Unlike UTC, GPS Time does not incorporate leap seconds. This means that GPS Time runs continuously without adjustments, making it ideal for precise navigation and timing applications where discontinuities caused by leap seconds would be problematic. As a result, GPS Time gradually drifts away from UTC.
flowchart TD A[Unix Epoch: 1970-01-01 00:00:00 UTC] --> B{Time progresses} B --> C[GPS Epoch: 1980-01-06 00:00:00 UTC] C --> D{Leap Seconds Introduced in UTC} D --> E[GPS Time (Continuous) vs. UTC (Leap Seconds)] E --> F[Growing Offset between GPST and UTC]
Conceptual flow of time progression and divergence between Unix/UTC and GPS Time.
Calculating the Initial Offset
To find the initial difference between the Unix epoch and the GPS epoch, we calculate the number of days and then seconds between January 1, 1970, and January 6, 1980. This initial calculation does not account for leap seconds that occurred after the Unix epoch but before the GPS epoch.
import datetime
unix_epoch = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
gps_epoch = datetime.datetime(1980, 1, 6, 0, 0, 0, tzinfo=datetime.timezone.utc)
initial_offset_duration = gps_epoch - unix_epoch
initial_offset_seconds = initial_offset_duration.total_seconds()
print(f"Unix Epoch: {unix_epoch}")
print(f"GPS Epoch: {gps_epoch}")
print(f"Initial Offset (seconds): {initial_offset_seconds}")
# Expected output: Initial Offset (seconds): 315964800.0
Python code to calculate the initial second difference between Unix and GPS epochs.
Accounting for Leap Seconds
The critical difference arises because UTC, the basis for Unix time, incorporates leap seconds to stay aligned with Earth's rotation, while GPS Time does not. Between the Unix epoch (1970-01-01) and the GPS epoch (1980-01-06), there were several leap seconds introduced into UTC. These leap seconds must be added to the initial offset to get the true difference in seconds between a Unix timestamp and a GPS timestamp at any given moment.
Leap Seconds Between 1970 and 1980
The leap seconds introduced between January 1, 1970, and January 6, 1980, are:
- June 30, 1972
- December 31, 1972
- December 31, 1973
- December 31, 1974
- December 31, 1975
- December 31, 1976
- December 31, 1977
- December 31, 1978
This totals 8 leap seconds. Therefore, the actual offset between Unix time and GPS time at the GPS epoch (1980-01-06 00:00:00 UTC) is the initial calculated difference plus these 8 leap seconds.
initial_offset_seconds = 315964800 # From previous calculation
leap_seconds_1970_1980 = 8
total_offset_at_gps_epoch = initial_offset_seconds + leap_seconds_1970_1980
print(f"Total Offset at GPS Epoch (seconds): {total_offset_at_gps_epoch}")
# Expected output: Total Offset at GPS Epoch (seconds): 315964808.0
Calculating the total offset including leap seconds up to the GPS epoch.
Current Offset and Conversion
As of the last leap second insertion (December 31, 2016), there have been 18 additional leap seconds since the GPS epoch. This means the current total offset between GPS Time and UTC is 18 seconds. Therefore, to convert a GPS timestamp to a Unix timestamp, you would typically subtract the current total number of leap seconds from the GPS time, and then subtract the initial offset.
Conversely, to convert a Unix timestamp to a GPS timestamp, you would add the initial offset and then add the current total number of leap seconds.
graph TD A[Unix Timestamp (seconds since 1970-01-01 UTC)] -->|Add Initial Offset (315964800)| B[Time since Unix Epoch, aligned with GPS Epoch start] B -->|Add Current Leap Seconds (e.g., 18)| C[GPS Timestamp (seconds since 1980-01-06 GPST)] C -->|Subtract Current Leap Seconds (e.g., 18)| D[Time since GPS Epoch, aligned with Unix Epoch start] D -->|Subtract Initial Offset (315964800)| A
Conversion process between Unix and GPS timestamps.
import datetime
# Constants
UNIX_EPOCH_DATETIME = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
GPS_EPOCH_DATETIME = datetime.datetime(1980, 1, 6, 0, 0, 0, tzinfo=datetime.timezone.utc)
INITIAL_OFFSET_SECONDS = (GPS_EPOCH_DATETIME - UNIX_EPOCH_DATETIME).total_seconds()
# Current number of leap seconds (as of late 2016, this value can change over time)
CURRENT_LEAP_SECONDS = 18 # This value needs to be updated periodically
def unix_to_gps(unix_timestamp):
"""Converts a Unix timestamp to a GPS timestamp."""
return unix_timestamp - INITIAL_OFFSET_SECONDS + CURRENT_LEAP_SECONDS
def gps_to_unix(gps_timestamp):
"""Converts a GPS timestamp to a Unix timestamp."""
return gps_timestamp + INITIAL_OFFSET_SECONDS - CURRENT_LEAP_SECONDS
# Example Usage:
# Let's say we have a Unix timestamp for 2023-01-01 00:00:00 UTC
example_unix_datetime = datetime.datetime(2023, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
example_unix_timestamp = example_unix_datetime.timestamp()
print(f"Example Unix Timestamp: {example_unix_timestamp}")
converted_gps_timestamp = unix_to_gps(example_unix_timestamp)
print(f"Converted GPS Timestamp: {converted_gps_timestamp}")
# Verify conversion back
converted_back_unix_timestamp = gps_to_unix(converted_gps_timestamp)
print(f"Converted back to Unix Timestamp: {converted_back_unix_timestamp}")
# Note: The 'timestamp()' method in Python returns seconds since Unix epoch, including leap seconds.
# GPS time does not include leap seconds. The conversion logic above accounts for this difference
# by adjusting for the cumulative leap seconds between the two systems.
Python functions for converting between Unix and GPS timestamps.