From 223ae5a5e66fc6808bdb345caa7bfe567bb23024 Mon Sep 17 00:00:00 2001
From: "David A. Madore" <david+git@madore.org>
Date: Wed, 18 Apr 2012 19:56:43 +0200
Subject: Handle UTC between 1961 and 1972 ("rubber seconds").

---
 org/madore/ephem/Time.java | 50 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

(limited to 'org')

diff --git a/org/madore/ephem/Time.java b/org/madore/ephem/Time.java
index 3d2cb3e..b5af9c4 100644
--- a/org/madore/ephem/Time.java
+++ b/org/madore/ephem/Time.java
@@ -2,8 +2,11 @@ package org.madore.ephem;
 
 public final class Time {
 
-    public static final class LeapSecond {
+    public static abstract class UtcRegion {
 	public int mjd;
+    }
+
+    public static final class LeapSecond extends UtcRegion {
 	public int offset;
 	public LeapSecond(int mjd, int offset) {
 	    this.mjd = mjd;
@@ -11,7 +14,33 @@ public final class Time {
 	}
     }
 
-    public static final LeapSecond[] leapSecondsTable = new LeapSecond[] {
+    public static final class RubberSecond extends UtcRegion {
+	public double offset0;
+	public int mjd0;
+	public double scale0;
+	public RubberSecond(int mjd, double offset0, int mjd0, double scale0) {
+	    this.mjd = mjd;
+	    this.offset0 = offset0;
+	    this.mjd0 = mjd0;
+	    this.scale0 = scale0;
+	}
+    }
+
+    public static final UtcRegion[] leapSecondsTable = new UtcRegion[] {
+	// From <URL: http://maia.usno.navy.mil/ser7/tai-utc.dat >
+	new RubberSecond(37300, 1.4228180, 37300, 0.001296 ),
+	new RubberSecond(37512, 1.3728180, 37300, 0.001296 ),
+	new RubberSecond(37665, 1.8458580, 37665, 0.0011232),
+	new RubberSecond(38334, 1.9458580, 37665, 0.0011232),
+	new RubberSecond(38395, 3.2401300, 38761, 0.001296 ),
+	new RubberSecond(38486, 3.3401300, 38761, 0.001296 ),
+	new RubberSecond(38639, 3.4401300, 38761, 0.001296 ),
+	new RubberSecond(38761, 3.5401300, 38761, 0.001296 ),
+	new RubberSecond(38820, 3.6401300, 38761, 0.001296 ),
+	new RubberSecond(38942, 3.7401300, 38761, 0.001296 ),
+	new RubberSecond(39004, 3.8401300, 38761, 0.001296 ),
+	new RubberSecond(39126, 4.3131700, 39126, 0.002592 ),
+	new RubberSecond(39887, 4.2131700, 39126, 0.002592 ),
 	new LeapSecond(41317, 10),
 	new LeapSecond(41499, 11),
 	new LeapSecond(41683, 12),
@@ -40,8 +69,8 @@ public final class Time {
 	new LeapSecond(56109, 35),
     };
 
-    public static double utcToTt(int utcMjd, double utcSeconds) {
-	// Returns JD in TT
+    public static double utcOffset(int utcMjd, double utcSeconds) {
+	// Returns TAI-UTC in seconds
 	int i0 = 0;  int i1 = leapSecondsTable.length;
 	while ( i1-i0 > 1 ) {
 	    int i = (i0+i1)/2;
@@ -50,7 +79,18 @@ public final class Time {
 	    else
 		i1 = i;
 	}
-	return ( utcSeconds + leapSecondsTable[i0].offset + 32.184 )/86400. + utcMjd + 2400000.5;
+	double utcOffset;
+	if ( leapSecondsTable[i0] instanceof LeapSecond )
+	    utcOffset = ((LeapSecond)leapSecondsTable[i0]).offset;
+	else
+	    utcOffset = ((RubberSecond)leapSecondsTable[i0]).offset0
+		+ (utcMjd - ((RubberSecond)leapSecondsTable[i0]).mjd0) * ((RubberSecond)leapSecondsTable[i0]).scale0;
+	return utcOffset;
+    }
+
+    public static double utcToTt(int utcMjd, double utcSeconds) {
+	// Returns JD in TT
+	return ( utcSeconds + utcOffset(utcMjd, utcSeconds) + 32.184 )/86400. + utcMjd + 2400000.5;
     }
 
 }
-- 
cgit v1.2.3