sot / chandra_time

Convert between various time formats relevant to Chandra.
https://sot.github.io/Chandra.Time
BSD 3-Clause "New" or "Revised" License
4 stars 1 forks source link

Bug in date representation within leap second #21

Open taldcroft opened 8 years ago

taldcroft commented 8 years ago

I suspect this might be a bug in Axtime3.

In [4]: DateTime('2015-06-30 23:59:60.5').date  # WRONG
Out[4]: '2015:182:00:00:00.500'

In [5]: DateTime('2015-06-30 23:59:60.5').secs  # CORRECT
Out[5]: 552096067.684

In [6]: DateTime(DateTime('2015-06-30 23:59:60.5').secs).date  # CORRECT (??)
Out[6]: '2015:181:23:59:60.500'

In [7]: DateTime('2015-07-01 00:00:00.5').secs  # CORRECT
Out[7]: 552096068.684

In [8]: DateTime('2015-07-01 00:00:00.5').date  # CORRECT
Out[8]: '2015:182:00:00:00.500'

In [9]: DateTime(DateTime('2015-07-01 00:00:00.5').secs).date
Out[9]: '2015:182:00:00:00.500'

In [10]: DateTime('2012-06-30 23:59:60.5').date
Out[10]: '2012:183:00:00:00.500'

Similar behavior is seen in the 2012-06-30 leap second. CxoTime does not show this problem. :-)

jeanconn commented 8 years ago

How is this using the axtime cmdline thing?

jskrist commented 5 years ago

I think I recently ran into this issue while optimizing the conversion code that changes FOT MATLAB times (UTC times with a base of '1990:001:00:00:00.000') to Ska times (tt times with a different base). The current code uses: ska_time = Chandra.Time.convert(MATLAB_utc_sec, fmt_in="secs", sys_in="utc", fmt_out="secs", sys_out="tt")

And I found that near leap seconds the resulting times do not match the MATLAB equivalent. It looks to me like the leap second is being applied earlier than it should be when using the convert method. When I plotted the difference between the MATLAB and python values I found a consistent offset for each leap second:

leapsecondOffset

Each time the leap second is being applied at the '23:58:58.000' second (2 minutes and 2 seconds before the actual leap second should be applied).

However, if I pass the raw number of seconds from the base to the DateTime constructor (as described in the issue) I get the expected (correct) datetime. In summary:

taldcroft commented 5 years ago

One thing to note is that the 23:58:58.000 is actually about 63 seconds early, which is suspiciously close to the 64.184 sec offset between tt and utc.

Another is this:

# convert() function matches "UTC" secs=0 with "TT" secs=0.  
# Only diverges after first leap second.
>>> convert(0.0, fmt_in="secs", sys_in="utc", fmt_out="secs", sys_out="tt")
0.0
jskrist commented 5 years ago

Thanks. I was able to confirm my MATLAB based conversion a slightly different way (I think). I used:

from Chandra.Time import DateTime
near_leap_sec_times = DateTime(["1998:365:23:59:57.000", "1998:365:23:59:58.000", "1998:365:23:59:59.000", "1999:001:00:00:00.000", "1999:001:00:00:01.000", "1999:001:00:00:02.000"])
time_secs = near_leap_sec_times.secs

to get the raw seconds from Datetime that I was trying to reproduce in MATLAB and then compared these values which are the same +- 1.5e-8s, which I consider to be equal.

I also found that if I send the time_secs variable into the convert function then they are off in the same way I noted they where when using the MATLAB_utc_sec variable.

jeanconn commented 5 years ago

@taldcroft when you brought up the original issue, was your thought to just set Chandra.Time to use cxotime for these calculations?

taldcroft commented 5 years ago

Can't say what was in my head four years ago. The best answer is to get more serious about migrating to cxotime, but it isn't clear if that should be a priority. Even I got lazy about that.

The other answer is to just ignore this, as operations like DateTime('2015-06-30 23:59:60.5').date are rarely or never in the "critical-for-accuracy" category. In other words, we use YEAR:DOY not YY-MM-DD for critical times.