[LEAPSECS] negative leap second in 2029?

2024-03-31 Thread Paul Hirose
"Even a few years ago, the expectation was that leap seconds would 
always be positive, and happen more and more often," Duncan Agnew, a 
geophysicist at Scripps Institution of Oceanography at University of 
California's San Diego campus, said in a statement. "But if you look at 
changes in the Earth’s rotation, which is the reason for leap seconds, 
and break down what causes these changes, it looks like a negative one 
is quite likely. One second doesn’t sound like much, but in today’s 
interconnected world, getting the time wrong could lead to huge problems."


https://www.foxweather.com/earth-space/what-time-is-it-clock-adjustment
___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] future access to solar time?

2022-11-21 Thread Paul Hirose

The Astronomical Almanac (2019) says

∆UT = UT1 - UTC

DUT1 = predicted value of ∆UT, rounded to 0.1 s, given in some radio 
time signals


(Unfortunately, this scan cuts off part of the leftmost characters. But 
you can deduce them, except perhaps Ee and Eo: equation of the equinoxes 
and equation of the origins.)


https://archive.org/details/binder1_202003/page/n121/mode/2up?view=theater


IERS Bulletins A and B say "UT1-UTC" instead of ∆UT. I think that's a 
good idea. It prevents confusion about the sign.


The current version of Bulletin A estimates UT1 will lose about 0.1 s 
with respect to atomic time during the next year.


https://www.iers.org/IERS/EN/Publications/Bulletins/bulletins.html

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


[LEAPSECS] aircraft GPS receivers hit by leap second bug

2019-06-11 Thread Paul Hirose

[from Flying magazine]

Collins Aerospace notified its user base of a cascade of reports it had 
received beginning at 00:00Z on June 9 that certain GPS and GLU models 
were not operating properly. The specific models, the GPS-4000S sensor 
and the GLU-2100 multi-mode receiver (supporting ADS-B Out 
requirements), are installed in Collins Pro Line 21 and Pro Line Fusion 
avionics systems in many business jets, as well as in some aircraft used 
by regional and major airlines. In fact, Forbes reported on June 9 that 
a slew of airlines had cancelled flights on Sunday because of similar 
issues—including a group of Boeing 717s flown by Hawaiian Airlines.


When we contacted Collins Aerospace on the morning of June 10, we were 
sent the bulletin noted earlier, and advised that operators were 
encouraged to call in with their experience and contact information so 
that they could be informed of a resolution when it had been found. 
Later that day, Collins issued another letter to its user group, 
highlighting the exact problem: “We found that a software design error 
resulted in the system misinterpreting GPS time updates due to a ‘leap 
second’ event, which typically occurs once every 2.5 years within the 
U.S. Government GPS satellite almanac update. Our GPS-4000S-100 version 
software's timing calculations have reacted to this leap second by not 
tracking satellites upon power-up and subsequently failing. The U.S. 
Government distributed a regularly scheduled almanac update with this 
‘leap second’ on 0:00GMT, Sunday, June 9, 2019, and the failures began 
to occur soon after.”


Collins advises operators not to power up units until after the next 
scheduled update by the US government on June 16, 2019, at 00:15Z.


[end quote]

https://www.flyingmag.com/collins-receivers-struck-by-failure-modes/

The Avweb site has also picked up the story:
https://www.avweb.com/news/collins-gps-errors-spark-flight-delays/


Thinking I had missed a pending leap second, I checked the IERS site, 
but Bulletin C says the offset is still 37 seconds and nothing is 
scheduled. ???

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] leapseconds, converting between GPS time (week, second) and UTC

2019-01-21 Thread Paul Hirose

On 2019-01-16 1:35, Steve Allen wrote:

So starting 1970-01-01 DCF77 changed to broadcast Stepped Atomic Time
(SAT) with second markers that were 1 SI second apart except on
occasions when they were 1.2 SI seconds apart in order that the time
markers would stay close to UT2.


For fun (?) I wrote a rudimentary C# program to convert an epoch in the 
DCF77 scale to proleptic GPS week and second. It uses the JulianDate, 
Duration, Utc, and UtcTable classes in my SofaJpl fundamental astronomy 
DLL for Windows .NET Framework.


I don't know when DCF77 inserted the step adjustments, so I created a 
small table sufficient for an example. Beginning in January the rate 
offset becomes zero. There's a step adjustment (almost .2 s) at the end 
of the month. To make the example more interesting, I set the epoch 
within that step.


Calculations are performed in the TT scale, which my DLL favors since 
it's written for astronomy. However, the JulianDate class can represent 
TAI or any unstepped time scale. Scales with step adjustments require 
the Utc class and a defining table.


This example begins with a date and time in my fake DCF77 time scale and 
converts it to TT, then GPS week and seconds, then completes a round 
trip via TT to date and time in the original scale as well as UTC in the 
rubber second era.



// Simulated DCF77 time scale. First 2 lines from the real UTC table,
// the rest phony. Step adjustment at end of 1970 Jan 31.
string dcf77TableString =
@"1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 
0.002592 S
1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 
0.002592 S
1970 JAN  1TAI-UTC=   8.820 S + (MJD - 40587.) X 0.0 
 S
1970 FEB  1TAI-UTC=   8.200 S + (MJD - 40587.) X 0.0 
 S
1970 MAR  1TAI-UTC=   8.200 S + (MJD - 40587.) X 0.0 
 S";


// Load the DCF77 table from the string.
UtcTable dcf77Table = new UtcTable(
new System.IO.StringReader(dcf77TableString));

// Load the default UTC table. This is the USNO table.
Utc.LoadTableFromFile(@"C:\Users\Stan\Documents\astro\IERS\leapSecTable.txt");

// Specify desired time display precision (the unit is 1 / hours).
double timePrecision = 3.6e5; // .01 s

// base epoch of GPS time scale (TT)
JulianDate gpsBaseEpochTT = new Utc(1980, 1, 6, 0).TerrestrialTime;

// length of one week and the GPS cycle of 1024 weeks
Duration weekLength = new Duration(7);
Duration cycleLength = new Duration(7 * 1024);

// Set DCF77 epoch to 1970-01-31 23:59:60.05
Utc dcf77 = new Utc(1970, 1, 31, Angle.HmsToDays(23, 59, 60.05),
false, dcf77Table);

// Display DCF77 epoch.
Console.WriteLine("{0} DCF77 epoch",
dcf77.ToTimeFields(timePrecision));

// Convert to TT, display.
JulianDate tt = dcf77.TerrestrialTime;
Console.WriteLine("{0} TT", tt.ToTimeFields(timePrecision));

// elapsed time (possibly negative) since GPS time scale origin
Duration elapsedTime = tt - gpsBaseEpochTT;

// 1024-week cycle number (negative if before 1980)
int cycleNumber = (int)Math.Floor(elapsedTime / cycleLength);

// TT at beginning of applicable 1024-week cycle
JulianDate weekZeroTT = gpsBaseEpochTT + cycleNumber * cycleLength;

// elapsed time from start of cycle
elapsedTime = tt - weekZeroTT;

// GPS week number
int weekNumber = (int)Math.Floor(elapsedTime / weekLength);

// elapsed time from start of week
elapsedTime -= weekNumber * weekLength;

// convert elapsed time to seconds
double seconds = elapsedTime.ToSeconds();

// Show results.
Console.WriteLine("{0:d} = cycle number", cycleNumber);
Console.WriteLine("{0} = GPS week", weekNumber);
Console.WriteLine("{0:f2} seconds", seconds);

// Convert cycle number, week number, and seconds to DCF77 and UTC.

// elapsed time since start of applicable 1024-week cycle
elapsedTime = Duration.FromSeconds(seconds) + weekNumber * weekLength;

// Add the time in the whole cycles since GPS time origin
elapsedTime += cycleNumber * cycleLength;

// Convert to TT.
tt = elapsedTime + gpsBaseEpochTT;
Console.WriteLine("{0} TT", tt.ToTimeFields(timePrecision));

// Convert to epoch in the DCF77 scale.
dcf77 = new Utc(tt, dcf77Table);
Console.WriteLine("{0} DCF77 epoch", dcf77.ToTimeFields(timePrecision));

// Also convert to UTC.
dcf77 = new Utc(tt);
Console.WriteLine("{0} UTC", dcf77.ToTimeFields(timePrecision));


output:

1970-01-31T23:59:60.05 DCF77 epoch
1970-02-01T00:00:40.23 TT
-1 = cycle number
505 = GPS week
604789.05 seconds
1970-02-01T00:00:40.23 TT
1970-01-31T23:59:60.05 DCF77 epoch
1970-01-31T23:59:59.97 UTC

Hand computation confirms the TT and UTC are correct. I sure any GPS 
week calculator would reject the date as illegal, so that part I tested 
near the present time.

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] leapseconds, converting between GPS time (week, second) and UTC

2019-01-16 Thread Paul Hirose

On 2019-01-16 1:35, Steve Allen wrote:


Does it know that rubber seconds do not apply to timestamps in central
Europe made using DCF77 from 1970-01-01 to 1972-01-01?


All my DLL knows is what's in the UTC file. If the file indicates no 
rate offset in the years 1970-71 and some fractional second step 
adjustments, that's what you get. An existing file could be edited to 
match the DCF77 flavor of UTC. Then construct a UtcTable object from the 
file:


SofaJpl.UtcTable dcf77Table = new SofaJpl.UtcTable(filename);

Construct a Utc object with that table as a parameter.

SofaJpl.Utc utc = new SofaJpl.Utc(year, month, day, fracday, dcf77Table);

Variable "utc" will convert itself to TT based on the custom table. 
Then, to complete a round trip, create another Utc object from that TT 
and the custom table. When formatted as date/time you get the original UTC.

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] leapseconds, converting between GPS time (week, second) and UTC

2019-01-16 Thread Paul Hirose

On 2019-01-15 10:50, Tom Van Baak wrote:

For instance, in Python, if I do a datetime(2016,12,31,0,0,0) +
timedelta(hours=30) does it come out as 1/1/2017 6:00:00 or 5:59:59  (it
comes out 0600)


Here's a C# code fragment which performs a similar computation. To make 
the demonstration more interesting I arrange for the augmented UTC to 
fall in the middle of a leap second.


The program calls my SofaJpl fundamental astronomy DLL for the Windows 
.NET Framework. "Sofa" refers to the IAU SOFA (Standards of Fundamental 
Astronomy) library, and "Jpl" refers to the Jet Propulsion Laboratory 
planetary ephemerides. But there's no astronomy in this little example.



// Open the leap second table. The '@' prefix on the
// string causes the C# compiler to not interpret a backslash as an
// escape character.
SofaJpl.Utc.LoadTableFromFile(@"C:\Users\Stan\Documents\astro\IERS\leapSecTable.txt");

// Construct a Utc object at the initial epoch.
SofaJpl.Utc utc1 = new SofaJpl.Utc(2016, 12, 31, 0, 0, 0);

// Construct a JulianDate object at the same epoch (TT scale).
SofaJpl.JulianDate tt = utc1.TerrestrialTime;

// Construct a Duration object with the amount of time to add.
SofaJpl.Duration timeIncrement = SofaJpl.Duration.FromSeconds(86400.5);

// Add the time to TT.
tt += timeIncrement;

// Convert the incremented TT to a new Utc object.
SofaJpl.Utc utc2 = new SofaJpl.Utc(tt);

// The desired time display precision (the unit is 1 / hours).
double timePrecision = 36000.0; // .1 s precision

// Display the initial and final UTC epochs.
Console.WriteLine(utc1.ToTimeFields(timePrecision));
Console.WriteLine(utc2.ToTimeFields(timePrecision));


Output:
2016-12-31T00:00:00.0
2016-12-31T23:59:60.5

The leap second table follows the USNO format with some extensions. 1) 
For easy updates by hand, the Julian date field is ignored and may be 
blank. 2) The final line must have the same TAI-UTC as the previous 
line, but a later date. This line defines the final epoch of the table. 
An exception occurs if you exceed it.


http://maia.usno.navy.mil/ser7/tai-utc.dat

The "rubber second" era is supported. That accounted for about 90% of 
the workload to create the UTC implementation!


JulianDate and Duration objects both represent whole days and fractional 
days in separate double precision variables. Operators are defined if 
they make sense. For instance, if you subtract one JulianDate from 
another the result is a Duration. You can add two Durations but addition 
of two JulianDates is undefined. For convenience, the Duration class 
includes the fixed offsets TTMinusGps and TTMinusTai. Time conversions 
with variable offsets such as TTToTdb() are in the JulianDate class.


By design, the Utc class has limited facilities. You can create a Utc 
object from date and time components or a JulianDate in the TT scale. 
The inverse operations are available too. But as shown in the example, 
any time math requires explicit conversion to a JulianDate object in the 
TT scale, then conversion back to a Utc object if the user needs to see 
the result in UTC. These conversions are lossless since a Utc object 
internally stores its value as a JulianDate in TT. (The DLL is intended 
for astronomy, where TT is more useful than TAI.)


By not defining addition or subtraction on Utc objects I avoid ambiguity 
about the exact meaning of these operations in a stepped time scale.


A TimeFields represents epoch as year, month, etc. (It's not called 
"DateTime" because the Windows .NET Framework already has such a class.) 
The main purpose of the class is to format JulianDate and Utc objects 
for output, rounded to the specified precision. For example, if a 
JulianDate is a few seconds from the end of the year, and precision is 
60 (= one minute), the conversion to a TimeFields rounds up to January 1 
00:00 in the next year.


It's possible to construct named TimeFields objects and extract the 
components individually for output. But for simplicity my example 
creates unnamed objects. By default they "stringize" themselves in ISO 
8601 format at the specified precision (.1 second in this case).



SofaJpl is CLS compliant and therefore can be called by any CLS 
language, as shown by the C#, C++/CLI, and Visual Basic demonstration 
programs at the web page. The DLL was created primarily for personal use 
on my Windows system, but anyone can download it for free. A full 
installation is almost exactly 1 megabyte.


http://home.earthlink.net/~s543t-24dst/SofaJpl_NET/index.html
___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] USNO press release

2016-07-10 Thread Paul Hirose

On 2016-07-08 12:16, I wrote:

Is there a mistake in this announcement?


http://www.usno.navy.mil/USNO/tours-events/2016_Leap_Second%20Press%20Release%20-%20Final.pdf


WASHINGTON, DC -- On December 31, 2016, a “leap second” will be added to
the world’s clocks at 23 hours, 59 minutes and 59 seconds Coordinated
Universal Time (UTC).


The mistake is in the first sentence. Nothing unusual happens at 
23:59:59. One second later, at 23:59:60, the leap second begins. In 
other words, UTC will do this:


23:59:59.9
23:59:60.0
23:59:60.1
...
23:59:60.9
00:00:00.0

I have informed the author of the press release.

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


[LEAPSECS] USNO press release

2016-07-08 Thread Paul Hirose

Is there a mistake in this announcement?


http://www.usno.navy.mil/USNO/tours-events/2016_Leap_Second%20Press%20Release%20-%20Final.pdf

WASHINGTON, DC -- On December 31, 2016, a “leap second” will be added to 
the world’s clocks at 23 hours, 59 minutes and 59 seconds Coordinated 
Universal Time (UTC). This corresponds to 6:59:59 pm Eastern Standard 
Time, when the extra second will be inserted at the

U.S. Naval Observatory’s Master Clock Facility in Washington, DC.
___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] Civil timekeeping before 1 January 1972

2015-05-05 Thread Paul Hirose

On 2015-03-06 18:02, Harlan Stenn wrote:

When we get a bit more down the road with NTF's General Timestamp API,
I'd appreciate your taking a look at what we're doing and helping out in
any way you are up for.  One of the issues that will need more attention
is pre-1972 stuff.


The rubber time era can be tricky. I just finished a major rewrite of my 
UTC implementation in the C# language. The goal was improved accuracy 
before 1972. Although the old version passed all my tests at 1 
microsecond accuracy, it began failing when I tightened the error 
tolerance to 1 nanosecond.


A couple adjacent lines from the USNO table show the problem:

1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 
0.002592 S
1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 
0.002592 S


The last instant of the first line is 1968 Jan 31 23:59:59.9, since a 
step adjustment shortens the last minute. The first instant of the 
second line is 1968 Feb 1 00:00:00. These UTC epochs are equivalent and 
should convert to the same TAI.


But if you do the math, the second line yields a TAI 3 ns after the 
first line. In other words, there's a 3 ns slice of TAI with no UTC 
equivalent.


The reason is the rate correction, which in both lines is (MJD - 39126.) 
* 0.002592 s, where MJD is UTC in the form of a modified Julian date. In 
the first line the expression in parentheses yields a true amount of 
rubber time since the base epoch MJD 39126.


In the second line that's not the case. Due to the step adjustment, 
subtracting 39126 from UTC yields a value .1 s greater than the actual 
elapsed time. That's about 1.16e-6 days. Multiply by the .002592 s/day 
that TAI gains on UTC, and you get the 3 ns discrepancy.


I don't believe 3 ns is significant for any time stamp from that era. 
Anyway, the number of decimal places in the USNO table (4.3131700 etc.) 
implies accuracy to only 100 ns. However, my implementation is capable 
of time scale conversions accurate to 1 ns with a comfortable margin. I 
wanted to realize that potential.


The solution was to leave the step adjustments as-is and make subtle 
adjustments to the rates. This was more difficult than I expected. The 
user is responsible for loading the USNO text file at run time, so none 
of the work can be done in advance. Moreover, my implementation is 
designed to support experimental modifications to the UTC table, even 
wild stuff like re-introduction of rate offsets. Thus nothing can be 
assumed.


My solution is to make one pass through the USNO file to construct a 
preliminary table. Then a pass through the table puts in the step 
adjustments, which are implied by the USNO data but not listed. A final 
pass makes the rate adjustments. At the user's option the last can be 
omitted for a literal version of the USNO table. It was a lot a trouble 
to get there, but I'm now accurate to a nanosecond.


You probably won't get that crazy, but testing for discontinuity as you 
cross from one table entry to the next is still a must. That's 
especially true pre-72, where it's easy to make a mistake. One of my 
tests is to compute TAI for two epochs one microsecond either side of 
the boundary between table entries. For instance, for the lines I 
included above, I'd begin with UTC epochs 1968 Jan 31 23:59:59.9 - 1 us, 
and Feb 1 00:00:00 + 1 us. Convert both UTCs to TAI, and verify the TAIs 
differ by 2 us.


(Formally, the correct value isn't exactly 2 us due to the rate 
difference between TAI and UTC. But that's insignificant over such a 
short span.)


Also, you should convert both TAIs back to UTC and verify accurate round 
trips.


It might seem that you could begin with UTC epochs Jan 31 23:59:59.9 and 
Feb 1 00:00:00, convert to TAI, and verify zero difference (within a 
given tolerance). The problem is that both TAIs can map to the same 
table entry when you round trip them to UTC, and so the other entry 
doesn't get tested as expected. (In my implementation each entry does 
both UTC - TAI and the reverse.)


Of course an accurate round trip UTC - TAI - UTC doesn't prove TAI is 
correct. You have to check that separately.


I don't take any position on whether or not pre-72 is really UTC. 
However, both IERS and USNO seem to recognize it as such, so I assume 
users of my software may expect that as well.


Similar decisions will face programmers if leap seconds are discontinued 
but the time scale keeps the same name. If you subsequently release a 
software package that converts between UTC and other scales, you'll have 
to decide whether or not to support the leap second era.

___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs


Re: [LEAPSECS] My FOSDEM slides

2015-03-06 Thread Paul Hirose

On 2015-03-06 11:04, Brooks Harris wrote:

The rubber-band era is
just entirely irrelevant. Its historically interesting, and may be
required for some special application concerning that period, but for
practical UTC-like timekeeping its just an historical curiosity.

This fact is somewhat more apparent looking at the IERS publication
Leap_Second_History.dat, at
https://hpiers.obspm.fr/eoppc/bul/bulc/Leap_Second_History.dat. There we
see *no values* before 1 1 1972 - the rubber-band era is gone.
That's correct - the rubber band era no long exists.


Since the name of the document is leap second history, the rate 
offsets and fractional second step adjustments before 1972 aren't 
applicable. They can be found elsewhere at the IERS site:


http://hpiers.obspm.fr/eop-pc/index.php?index=UTClang=en

I distribute a Windows astronomical toolbox DLL which includes time 
scale conversions. Since astronomy often requires analysis of old data, 
the DLL can deal with pre-1972 UTC. I won't get into the dispute over 
whether or not that's bona fide UTC! However, the IERS and USNO 
recognize it as such, so I assume the user will expect time conversions 
to work in that era. (I have never needed that capability myself.)


___
LEAPSECS mailing list
LEAPSECS@leapsecond.com
https://pairlist6.pair.net/mailman/listinfo/leapsecs