[AstroPy] How to compute TAI-UTC using Astropy?

Aldcroft, Thomas aldcroft at head.cfa.harvard.edu
Sun Aug 25 06:42:32 EDT 2019


On Sat, Aug 24, 2019 at 7:24 PM Russell Owen <rowen at uw.edu> wrote:

> Thank you for the suggestion, but I’m afraid I don’t see how it works..
> The given date I have to work from is a date in UTC. By specifying
> “Time(date, scale=“tai”)” I would be lying to the system: saying the date
> was TAI when it is UTC. I would expect that to give the wrong answer very
> near a UTC leap second.
>

I think the code works as expected within a leap second, at the expense of
an ERFA warning that you would need to catch:

In [2]: dts = [0, 0.5, 1.0, 1.5, 1.99, 2.0, 2.5, 3.0] * u.s
In [3]: dates_utc = Time(Time('2015-06-30 23:59:59') + dts, scale='utc')
In [4]: dates_tai = Time(dates_utc.iso, scale='tai')
WARNING: ErfaWarning: ERFA function "dtf2d" yielded 3 of "time is after end
of day (Note 5)" [astropy._erfa.core]
In [5]: for date_utc, date_tai in zip(dates_utc, dates_tai):
   ...:     print(f'{date_utc} {(date_utc - date_tai).sec:.2f}')
   ...:
2015-06-30 23:59:59.000 35.00
2015-06-30 23:59:59.500 35.00
2015-06-30 23:59:60.000 35.00
2015-06-30 23:59:60.500 35.00
2015-06-30 23:59:60.990 35.00
2015-07-01 00:00:00.000 36.00
2015-07-01 00:00:00.500 36.00
2015-07-01 00:00:01.000 36.00


>
> My code didn’t work at leap second either, but this code does:
>
> def tai_from_utc(utc):
>     """Return TAI in unix seconds, given UTC in unix seconds.
>     """
>     astropy_utc = astropy.time.Time(utc, scale="utc", format="unix")
>     dt_utc = astropy_utc.utc.to_datetime()
>     dt_tai = astropy_utc.tai.to_datetime()
>     tai_minus_utc = (dt_tai - dt_utc).total_seconds()
>     return utc + tai_minus_utc
>

On this, I would caution against using the astropy unix format for
calculations where the details matter.  From the TimeUnix API docs
<https://docs.astropy.org/en/stable/api/astropy.time.TimeUnix.html#astropy.time.TimeUnix>
:

*NOTE: this quantity is not exactly unix time and differs from the strict
POSIX definition by up to 1 second on days with a leap second. POSIX unix
time actually jumps backward by 1 second at midnight on leap second days
while this class value is monotonically increasing at 86400 seconds per UTC
day.*

I'm not sure about your test case, but the Python `datetime` does not
support leap seconds.  I got this exception trying to run your code within
a leap second, but maybe I did something differently:

ValueError: Time (array(2015, dtype=int32), array(6, dtype=int32),
array(30, dtype=int32), array(23, dtype=int32), array(59, dtype=int32),
array(60, dtype=int32), array(0, dtype=int32)) is within a leap second but
datetime does not support leap seconds

Cheers,
Tom


>
> It seems quite clumsy to have to use datetime objects *and* astropy. I’d
> welcome a cleaner solution!
>
> Regards,
>
> Russell
>
> On Aug 24, 2019, at 2:12 PM, Aldcroft, Thomas <
> aldcroft at head.cfa.harvard.edu> wrote:
>
> Hi Russell,
>
> I think what you want is:
>
> In [1]: from astropy.time import Time
> In [2]: date = '2019-08-24 00:00:00'
> In [3]: dt = Time(date, scale='utc') - Time(date, scale='tai')
> In [4]: dt.sec
> Out[4]: 36.99999999999779
>
> - Tom
>
> On Fri, Aug 23, 2019 at 6:46 PM Russell Owen <rowen at uw.edu> wrote:
>
>> We do some work with TAI times as unix seconds. Possibly controversial,
>> but it’s what we use.
>>
>> We sometimes need to convert normal unix times (UTC) to this standard.
>>
>> This naive solution does not work:
>>
>> def bogus_tai_from_utc(utc):
>>     “””Failed attempt to return TAI in unix seconds given UTC in unix
>> seconds.
>>
>>     This fails because given an astropy.time.Time astropy_time:
>>     astropy_time.tai.unix == astropy_time.utc.unix
>>     """
>>     return astropy.time.Time(utc, format=“unix”, scale=“utc”).tai.unix
>>
>> Is there a nice way to ask AstroPy the value of TAI-UTC in seconds, given
>> a UTC?
>> If so, this would be perfect:
>>
>> tai_from_utc(utc):
>>     tai_minus_utc = …? (presently 37 seconds)
>>     return utc + tai_minus_utc
>>
>> The following ugly code works, but has error at the microsecond level and
>> may not work at leap seconds:
>>
>> tai_minus_utc = (astropy_utc.tai.mjd - astropy_utc.utc.mjd)*24*60*60
>>
>> Regards,
>>
>> Russell
>> _______________________________________________
>> AstroPy mailing list
>> AstroPy at python.org
>> https://mail.python.org/mailman/listinfo/astropy
>>
> _______________________________________________
> AstroPy mailing list
> AstroPy at python.org
> https://mail.python.org/mailman/listinfo/astropy
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/astropy/attachments/20190825/3c0f3bf7/attachment-0001.html>


More information about the AstroPy mailing list