时间和日期 (astropy.time
)#
介绍#
这个 astropy.time
Package提供了操作时间和日期的功能。特别强调支持天文学中使用的时间标度(例如,UTC、TAI、UT1、TDB)和时间表示法(例如,JD、MJD、ISO 8601),这些时间标度和时间表示法需要计算恒星时和重心改正。这个 astropy.time
基于快速和内存效率的封装 PyERFA 用包装纸包裹着 ERFA 时间和日历例程。
所有的时间操作和算术运算都在内部使用两个64位浮点来表示时间。浮点算法来自 [1] 是为了使 Time
这个物体在宇宙年龄段内保持亚纳秒级的精度。
入门#
常用的使用方法 astropy.time
is to create a Time
object by supplying one or more input time values as well as the time format 和 time scale 这些价值观。输入时间可以是单个标量,例如 "2010-01-01 00:00:00"
或者是一个列表或者一个 numpy
如下所示的值数组。通常,任何输出值都具有与输入相同的形状(标量或数组)。
实例#
创建一个 Time
对象:
>>> import numpy as np
>>> from astropy.time import Time
>>> times = ['1999-01-01T00:00:00.123456789', '2010-01-01T00:00:00']
>>> t = Time(times, format='isot', scale='utc')
>>> t
<Time object: scale='utc' format='isot' value=['1999-01-01T00:00:00.123' '2010-01-01T00:00:00.000']>
>>> t[1]
<Time object: scale='utc' format='isot' value=2010-01-01T00:00:00.000>
这个 format
参数指定如何解释输入值(例如,ISO、JD或Unix时间)。默认情况下,将使用相同的格式表示输出时间。您可以稍后根据需要更改此格式,但因为这仅用于表示,所以不会影响内部表示(始终是两个64位值, jd1
和 jd2
属性),也不对该对象进行任何计算。
这个 scale
参数指定 time scale 值(例如,UTC、TT或UT1)。这个 scale
参数是可选的,默认为UTC,除非 Time from Epoch Formats 。可以将其更改(例如,从UTC更改为TDB),这将导致相应地调整内部值。
我们可以把上面写为:
>>> t = Time(times, format='isot')
当可以明确地确定输入的格式时 format
不需要参数,因此我们可以进一步简化:
>>> t = Time(times)
现在我们可以通过请求相应的 Time
属性::
>>> t.jd
array([2451179.50000143, 2455197.5 ])
>>> t.mjd
array([51179.00000143, 55197. ])
可通过表示输出的全部功率 to_value
method which also allows controlling the subformat . 例如,使用 numpy.longdouble
作为更高精度的输出类型:
>>> t.to_value('mjd', 'long')
array([51179.00000143, 55197. ], dtype=float128)
可以通过设置 format
属性:
>>> t.format = 'fits'
>>> t
<Time object: scale='utc' format='fits' value=['1999-01-01T00:00:00.123'
'2010-01-01T00:00:00.000']>
>>> t.format = 'isot'
我们也可以转换成不同的时间尺度,例如从UTC到TT。它使用与上面相同的属性机制,但现在返回一个新的 Time
对象:
>>> t2 = t.tt
>>> t2
<Time object: scale='tt' format='isot' value=['1999-01-01T00:01:04.307' '2010-01-01T00:01:06.184']>
>>> t2.jd
array([2451179.5007443 , 2455197.50076602])
注意ISO(ISOT)和JD表示 t2
不同于 t
因为它们是相对于TT时间尺度来表达的。当然,从数字或字符串来看,你无法分辨出是这样的:
>>> print(t2.fits)
['1999-01-01T00:01:04.307' '2010-01-01T00:01:06.184']
您可以使用 numpy
数组设置项语法::
>>> t2 = t.tt.copy() # Copy required if transformed Time will be modified
>>> t2[1] = '2014-12-25'
>>> print(t2)
['1999-01-01T00:01:04.307' '2014-12-25T00:00:00.000']
这个 Time
对象还支持缺少值,这对于 表操作 如连接和堆放:
>>> t2[0] = np.ma.masked # Declare that first time is missing or invalid
>>> print(t2)
[ ——— '2014-12-25T00:00:00.000']
最后,还有一些可能的例子。有关详细信息,请参阅下面的API文档。
>>> dt = t[1] - t[0]
>>> dt
<TimeDelta object: scale='tai' format='jd' value=4018.00002172>
这里,注意时间刻度到TAI的转换。时间差只能有一天等于86400秒的刻度。
>>> import numpy as np
>>> t[0] + dt * np.linspace(0., 1., 12)
<Time object: scale='utc' format='isot' value=['1999-01-01T00:00:00.123' '2000-01-01T06:32:43.930'
'2000-12-31T13:05:27.737' '2001-12-31T19:38:11.544'
'2003-01-01T02:10:55.351' '2004-01-01T08:43:39.158'
'2004-12-31T15:16:22.965' '2005-12-31T21:49:06.772'
'2007-01-01T04:21:49.579' '2008-01-01T10:54:33.386'
'2008-12-31T17:27:17.193' '2010-01-01T00:00:00.000']>
>>> t.sidereal_time('apparent', 'greenwich')
<Longitude [6.68050179, 6.70281947] hourangle>
您还可以使用基于时间的 Quantity
对于时间算术:
>>> import astropy.units as u
>>> Time("2020-01-01") + 5 * u.day
<Time object: scale='utc' format='iso' value=2020-01-06 00:00:00.000>
从5.1版开始, Time
对象也可以直接传递给 numpy.linspace
创建偶采样时间数组,包括对非标量的支持 start
和/或 stop
点-给出兼容的形状。
>>> stop = ['1999-01-05T00:00:00.123456789', '2010-05-01T00:00:00']
>>> tstp = Time(stop, format='isot', scale='utc')
>>> np.linspace(t, tstp, 4, endpoint=False)
<Time object: scale='utc' format='isot' value=[['1999-01-01T00:00:00.123' '2010-01-01T00:00:00.000']
['1999-01-02T00:00:00.123' '2010-01-31T00:00:00.000']
['1999-01-03T00:00:00.123' '2010-03-02T00:00:00.000']
['1999-01-04T00:00:00.123' '2010-04-01T00:00:00.000']]>
使用 astropy.time
#
时间对象基础#
在 astropy.time
以时间为单位表示的时间与时间的关系。在“日期”和“时间”之间没有区别,因为这两个概念(在一般用法中的松散定义)只是时间上某个时刻的不同表示。
时间格式#
时间格式指定如何表示时间的某一瞬间。可在中找到当前可用的格式 Time.FORMATS
下表列出了dict和。这些格式中的每一种都是作为一个从基派生的类来实现的 TimeFormat
班级。对于中未提供的专用时间格式,用户可以调整和扩展此类结构 astropy.time
.
格式 |
等级 |
示例参数 |
---|---|---|
拜耳 |
1950.0 |
|
byear_str |
'B1950.0' |
|
cxcsec公司 |
63072064.184 |
|
日期时间 |
日期2,时间 |
|
十进制年 |
2000.45 |
|
适合 |
‘2000-01-01T00:00:00.000’ |
|
全球定位系统 |
630720013.0 |
|
国际标准化组织 |
'2000-01-01 00:00:00.000' |
|
isot公司 |
‘2000-01-01T00:00:00.000’ |
|
法学博士 |
2451544.5 |
|
jyear公司 |
2000.0 |
|
jyear_str |
'J2000.0' |
|
美赞臣 |
51544.0 |
|
plot_date |
730120.0003703703 |
|
UNIX |
946684800.0 |
|
unix_tai |
946684800.0 |
|
白天 |
2000:001:00:00:00.000 |
|
基督教青年会 |
{'year':2010,'月':3,'日':1} |
|
日期时间64 |
np.日期时间64('2000-01-01T01:01:01') |
备注
这个 TimeFITS
格式实现了大部分的FITS标准 [2], 包括对 LOCAL
时间刻度。但是请注意,FITS支持一些不推荐使用的时间刻度名称;这些名称在初始化时被转换为正式名称。此外,任何特定的实现信息,例如 UT(NIST)
仅在时间刻度不变的情况下存储。
更改格式#
可以通过设置 format
属性:
>>> t = Time('2000-01-02')
>>> t.format = 'jd'
>>> t
<Time object: scale='utc' format='jd' value=2451545.5>
请注意,在更改格式时,当前输出子格式(请参阅下面的部分)可能不存在于新格式中。在这种情况下,将不保留子格式::
>>> t = Time('2000-01-02', format='fits', out_subfmt='longdate')
>>> t.value
'+02000-01-02'
>>> t.format = 'iso'
>>> t.out_subfmt
u'*'
>>> t.format = 'fits'
>>> t.value
'2000-01-02T00:00:00.000'
子格式#
许多可用的时间格式类都支持子格式的概念。这允许在输入解析/验证和输出中对格式的基本主题进行变化。
- 下表说明了字符串格式的可用子格式
iso
,fits
和yday
格式:
格式 |
子格式 |
输入/输出 |
---|---|---|
|
date_hms |
2001-01-02 03:04:05.678 |
|
date_hm |
2001-01-02 03:04 |
|
日期 |
2001-01-02 |
|
date_hms |
2001-01-02T03:04:05.678 |
|
longdate_hms |
+02001-01-02T03:04:05.678 |
|
长枣 |
+02001-01-02 |
|
date_hms |
2001:032:03:04:05.678 |
|
date_hm |
2001:032:03:04 |
|
日期 |
2001:032 |
数字格式,如 mjd
, jyear
或 cxcsec
所有支持子格式: 'float'
, 'long'
, 'decimal'
, 'str'
和 'bytes'
. 在这里, 'long'
使用 numpy.longdouble
以提高精度(增强程度取决于平台),以及 'decimal'
实例 decimal.Decimal
完全精确。对于 'str'
和 'bytes'
子格式中,也会选择位数以便精确地表示时间值。
当在输入上使用时,这些格式允许使用单个输入值创建时间,该输入值精确地捕捉到 Time
. 相反,使用 Time
to_value
或 TimeDelta
to_value
可以具有比标准64位浮点更高的精度:
>>> tm = Time('51544.000000000000001', format='mjd') # String input
>>> tm.mjd # float64 output loses last digit but Decimal gets it
51544.0
>>> tm.to_value('mjd', subfmt='decimal')
Decimal('51544.00000000000000099920072216264')
>>> tm.to_value('mjd', subfmt='str')
'51544.000000000000001'
的子格式选项的完整列表 Time
包含它们的格式是:
格式 |
子格式 |
---|---|
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
日期,日期,日期 |
|
浮点、长、十进制、str、字节 |
|
日期,日期,日期,日期,日期 |
|
浮点、长、十进制、str、字节 |
|
日期,日期,日期 |
|
日期,日期,日期 |
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
日期,日期,日期 |
的子格式选项的完整列表 TimeDelta
包含它们的格式是:
格式 |
子格式 |
---|---|
|
浮点、长、十进制、str、字节 |
|
浮点、长、十进制、str、字节 |
|
多,你,d,小时,分钟,S |
历元格式的时间#
格式 cxcsec
, gps
, unix
和 unix_tai
它们的特殊之处在于它们提供了自特定参考日期以来以秒为单位的已用时间的浮点表示。这些格式有一个内在的时间刻度,用来计算自参考日期以来经过的秒数。
格式 |
规模 |
参考日期 |
---|---|---|
|
TT |
|
|
UTC |
|
|
TAI |
|
|
TAI |
|
与其他默认为UTC的格式不同,如果不是 scale
初始化时提供 Time
对象,则使用上述内部比例。这样做是为了提高计算效率。
时间尺度#
时间刻度(或 time standard )是“测量时间的规范:时间流逝的速率;或时间点;或两者兼而有之” [3], [4]. ::
>>> Time.SCALES
('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc', 'local')
规模 |
描述 |
---|---|
泰 |
国际原子时 |
tcb公司 |
重心坐标时间(TCB) |
tcg公司 |
地心坐标时间 |
tdb公司 |
质心动力学时间 |
tt |
陆地时间(TT) |
ut1型 |
世界时(UT1) |
UTC |
协调世界时(UTC) |
地方的 |
本地时间刻度(本地) |
维基百科 time standard 文章
备注
这个 local
时间刻度是指自由运行的时钟或模拟时间(即,表示没有适当定义的刻度的时间)。这意味着它不能转换为任何其他时间刻度,并且只有在以下情况下才能进行算术运算 Time
具有规模的实例 local
并且有了 TimeDelta
具有规模的实例 local
或 None
。
支持的时间尺度之间的转换系统(即 local
)如下图所示。有关详细信息,请参阅 Convert time scale 部分。

标量或数组#
A Time
对象可以保存单个时间值或时间值数组。区别完全是由输入时间的形式决定的。如果 Time
对象包含一个值,则任何格式输出都将是一个标量值,对于数组也是如此。
例子#
像其他数组和列表一样, Time
持有数组的对象是可下标的,根据需要返回标量或数组对象:
>>> from astropy.time import Time
>>> t = Time(100.0, format='mjd')
>>> t.jd
2400100.5
>>> t = Time([100.0, 200.0, 300.], format='mjd')
>>> t.jd
array([2400100.5, 2400200.5, 2400300.5])
>>> t[:2]
<Time object: scale='utc' format='mjd' value=[100. 200.]>
>>> t[2]
<Time object: scale='utc' format='mjd' value=300.0>
>>> t = Time(np.arange(50000., 50003.)[:, np.newaxis],
... np.arange(0., 1., 0.5), format='mjd')
>>> t
<Time object: scale='utc' format='mjd' value=[[50000. 50000.5]
[50001. 50001.5]
[50002. 50002.5]]>
>>> t[0]
<Time object: scale='utc' format='mjd' value=[50000. 50000.5]>
NumPy方法的类比和适用的NumPy函数#
为 Time
实例包含数组,许多相同的方法和属性 ndarray
可以使用实例。例如,您可以重塑 Time
实例,并使用 reshape()
, ravel()
, flatten()
, T
, transpose()
, swapaxes()
, diagonal()
, squeeze()
,或 take()
。相应的函数,以及影响形状的其他函数,例如 atleast_1d
和 rollaxis
,如预期般工作。(相关功能必须在中明确启用 astropy
源代码;如果一个 numpy
不支持您认为应该起作用的函数。)
实例#
重塑 Time
实例::
>>> t.reshape(2, 3)
<Time object: scale='utc' format='mjd' value=[[50000. 50000.5 50001. ]
[50001.5 50002. 50002.5]]>
>>> t.T
<Time object: scale='utc' format='mjd' value=[[50000. 50001. 50002. ]
[50000.5 50001.5 50002.5]]>
>>> np.roll(t, 1, axis=0)
<Time object: scale='utc' format='mjd' value=[[50002. 50002.5]
[50000. 50000.5]
[50001. 50001.5]]>
请注意,与 ndarray
方法,除了 flatten()
尝试使用新的数据视图,只有在不可能的情况下才复制数据(如 numpy
reshape()
)
还支持一些算术方法: min()
, max()
, ptp()
, sort()
, argmin()
, argmax()
和 argsort()
.
应用算术方法 Time
实例::
>>> t.max()
<Time object: scale='utc' format='mjd' value=50002.5>
>>> t.min()
<Time object: scale='utc' format='mjd' value=50000.0>
推断输入格式#
这个 Time
类初始值设定项不接受不明确的输入,但在输入不明确的情况下,它将自动进行推断。当时间作为对象和 ymdhms
,或字符串。在后一种情况下,不需要指定格式,因为可用的字符串格式没有重叠。但是,如果预先知道格式,如果提供格式,则字符串解析将更快。
例子#
要推断输入格式:
>>> from datetime import datetime, timezone
>>> t = Time(datetime(2010, 1, 2, 1, 2, 3))
>>> t.format
'datetime'
>>> t = Time('2010-01-02 01:02:03')
>>> t.format
'iso'
内部代表#
这个 Time
对象将时间的内部表示形式维护为一对表示儒略日的双精度数字。这两个数字之和就是相对于给定时间的儒略日期 time scale . 用户需要在人类时间尺度(约100年)内不超过微秒的精度,可以安全地忽略内部表示细节,并跳过本节。
这种表示是由基础的 ERFA C库实现。ERFA程序始终注意保持双对的整体精度。用户可以自由选择提供Total JD的方式,尽管在内部,一部分包含整数天,另一部分包含一天的小数,因为这确保了所有转换的最佳精度。内部JD对可通过 jd1
和 jd2
属性::
>>> t = Time('2010-01-01 00:00:00', scale='utc')
>>> t.jd1, t.jd2
(2455198.0, -0.5)
>>> t2 = t.tai
>>> t2.jd1, t2.jd2
(2455198., -0.49960648148148146)
创建时间对象#
允许的 Time
创建时间对象的参数如下所示:
- valnumpy ndarray、list、str或number
初始化表的数据。
- val2numpy ndarray、list、str或number;可选
初始化表的数据。
- format可选的STR
输入值的格式。
- scale可选的STR
输入值的时间刻度。
- precision0到9之间的整数(包括0和9)
以浮点形式输出秒时的十进制精度。
- in_subfmtSTR
Unix glob选择用于分析输入时间的子格式。
- out_subfmtSTR
Unix glob为输出时间选择子格式。
- 位置 :
EarthLocation
或元组,可选地球位置或元组,可选 如果是元组,三
Quantity
具有地心坐标长度单位的项目,或大地坐标的经度、纬度和可选高度的项目。可以是单个位置,也可以是每个输入时间的一个位置。
瓦尔#
这个 val
参数指定一个或多个输入时间,可以是单个字符串或数字,也可以是Python列表或 numpy
字符串数组或数字数组。要初始化 Time
对象,则它将基于指定的时间 must 一定要在场。
在大多数情况下,还需要指定 time scale 通过 scale
争论。这个 Time
同学们永远猜不到 time scale ,所以一个简单的例子是:
>>> t1 = Time(50100.0, scale='tt', format='mjd')
>>> t2 = Time('2010-01-01 00:00:00', scale='utc')
可以创建一个新的 Time
对象来自一个或多个现有时间对象。在这种情况下,除非明确指定,否则将从第一个对象推断格式和比例。:
>>> Time([t1, t2])
<Time object: scale='tt' format='mjd' value=[50100. 55197.00076602]>
瓦尔2#
这个 val2
参数适用于需要高精度的情况。回想一下时间的内在表征 astropy.time
是两个双精度数字,求和后得到儒略日期。如果提供,则 val2
参数与 val
设置第二个内部时间值。对 val2
由输入格式类确定。忽略所有字符串值格式 val2
所有的数字输入有效地将这两个值相加,以保持最高精度。例如::
>>> t = Time(100.0, 0.000001, format='mjd', scale='tt')
>>> t.jd, t.jd1, t.jd2
(2400100.500001, 2400101.0, -0.499999)
格式#
这个 format
参数设置时间 time format ,并且如上所述,除非可以根据输入时间明确地确定格式,否则它是必需的。
规模#
The scale
argument sets the time scale and is required except for time
formats such as plot_date
(TimePlotDate
) and unix
(TimeUnix
). These formats represent the duration
in SI seconds since a fixed instant in time is independent of time scale. See
the Time from Epoch Formats for more details.
精度#
这个 precision
当输出包含秒的值时,设置会影响字符串格式。必须是0到9之间的整数。从字符串输入时间值不起作用。默认精度为3。请注意,9位数的限制是由 ERFA 处理分数秒。实际上,这不应该是一个问题。**
>>> t = Time('B1950.0', precision=3)
>>> t.byear_str
'B1950.000'
>>> t.precision = 0
>>> t.byear_str
'B1950'
in_subfmt#
这个 in_subfmt
参数提供了一种选择一个或多个的机制 subformat 可供输入的可用子格式中的值。可以使用Unix风格的通配符选择多个允许的子格式,尤其是 *
和 ?
,如Python中所述 fnmatch 模块。
的默认值 in_subfmt
是 *
匹配任何可用的子格式。这样可以方便地输入具有未知或异构子格式的值:
>>> Time(['2000:001', '2000:002:03:04', '2001:003:04:05:06.789'])
<Time object: scale='utc' format='yday'
value=['2000:001:00:00:00.000' '2000:002:03:04:00.000' '2001:003:04:05:06.789']>
您可以显式指定 in_subfmt
为了严格要求某个子格式:
>>> t = Time('2000:002:03:04', in_subfmt='date_hm')
>>> t = Time('2000:002', in_subfmt='date_hm')
Traceback (most recent call last):
...
ValueError: Input values did not match any of the formats where the
format keyword is optional ['astropy_time', 'datetime',
'byear_str', 'iso', 'isot', 'jyear_str', 'yday']
out_subfmt#
这个 out_subfmt
参数类似于 in_subfmt
但它适用于输出格式。如果有多个匹配的子格式,则使用第一个匹配的子格式。
>>> Time('2000-01-01 02:03:04', out_subfmt='date').iso
'2000-01-01'
>>> Time('2000-01-01 02:03:04', out_subfmt='date_hms').iso
'2000-01-01 02:03:04.000'
>>> Time('2000-01-01 02:03:04', out_subfmt='date*').iso
'2000-01-01 02:03:04.000'
>>> Time('50814.123456789012345', format='mjd', out_subfmt='str').mjd
'50814.123456789012345'
也见 subformat 部分。
位置#
此可选参数使用 EarthLocation
对象或包含可初始化的任何形式的元组:具有地心坐标(X、Y、Z)的元组,或具有大地坐标(经度、纬度、高度;高度默认为零)的元组。它们用于对观测者位置敏感的时间刻度(目前,只有TDB,它依赖于 PyERFA 例行程序 erfa.dtdb
以确定Tdb和TT之间的时间偏差),以及在没有给出明确经度的情况下的恒星时间。
>>> t = Time('2001-03-22 00:01:44.732327132980', scale='utc',
... location=('120d', '40d'))
>>> t.sidereal_time('apparent', 'greenwich')
<Longitude 12. hourangle>
>>> t.sidereal_time('apparent')
<Longitude 20. hourangle>
备注
在未来的版本中,我们希望增加添加天文台对象和/或名称的可能性。
获取当前时间#
>>> nt = Time.now()
>>> ut = Time(datetime.now(tz=timezone.utc), scale='utc')
这两个人应该很亲近。
基于C的快速数据串解析器#
基于时间的日期字符串表示形式的时间格式,包括 TimeISO
, TimeISOT
和 TimeYearDayTime
,使用一个快速的基于C的数据解析器,对于大的时间数组,它可以将速度提高20倍或更多。
C解析器比基于Python的解析器(它依赖于 strptime
). 特别是月份或一年中的某一天之类的字段必须始终具有固定数量的ASCII数字。作为一个例子,Python解析器将接受 2000-1-2T3:04:5.23
而C解析器需要 2000-01-02T03:04:05.23
默认情况下,除非输入子格式 in_subfmt
参数与的默认值不同 '*'
. 如果fastc解析器无法解析日期值,则 Time
初始值设定项将自动传递给Python解析器。
在极少数需要显式控制使用哪个解析器的情况下,会有一个配置项 time.conf.use_fast_parser
可以设置。默认值是 'True'
,这意味着要尝试快速解析器,如果需要,可以使用Python解析器。请注意,配置值是字符串,而不是bool对象。
例如,要禁用C解析器,请使用:
>>> from astropy.time import conf
>>> date = '2000-1-2T3:04:5.23'
>>> t = Time(date, format='isot') # Succeeds by default
>>> with conf.set_temp('use_fast_parser', 'False'):
... t = Time(date, format='isot')
... print(t)
2000-01-02T03:04:05.230
要强制C解析器的用户(例如在测试中),请使用:
>>> with conf.set_temp('use_fast_parser', 'force'):
... try:
... t = Time(date, format='isot')
... except ValueError as err:
... print(err)
Input values did not match the format class isot:
ValueError: fast C time string parser failed: non-digit found where digit (0-9) required
使用时间对象#
可用的操作 Time
对象包括:
获取并设置值为的数组的时间值
Time
对象。设置缺失(屏蔽)值。
在特定的 time format .
为相同的时间值获取新的时间对象,但引用了不同的时间值 time scale .
算出 sidereal time and Earth rotation angle 对应的时间值(S)。
获取和设置值#
对于现有的 Time
对象的数组值,可以使用 numpy
获取单个项或项子集的数组项语法。返回值是 Time
具有所有相同属性的对象。
实例#
要获取项目或项目的子集:
>>> t = Time(['2001:020', '2001:040', '2001:060', '2001:080'],
... out_subfmt='date')
>>> print(t[1])
2001:040
>>> print(t[1:])
['2001:040' '2001:060' '2001:080']
>>> print(t[[2, 0]])
['2001:060' '2001:020']
也可以为值为的数组设置值 Time
对象:
>>> t = Time(['2001:020', '2001:040', '2001:060', '2001:080'],
... out_subfmt='date')
>>> t[1] = '2010:001'
>>> print(t)
['2001:020' '2010:001' '2001:060' '2001:080']
>>> t[[2, 0]] = '1990:123'
>>> print(t)
['1990:123' '2010:001' '1990:123' '2001:080']
设置时的新值(在右侧)可以是以下三种可能性之一:
标量字符串值或字符串值数组,其中每个值都是有效的时间格式,可以自动分析并用于创建
Time
对象。值或值数组,其中每个值都具有相同的值
format
作为Time
正在设置的对象。例如,浮动或numpy
对象的浮点数组format='unix'
.Time
具有相同的对象location
(但是scale
和format
不必相同)。右侧值将被转换为时间scale
比赛。
只要设置了任何项,则内部缓存(请参见 Caching )与 delta_tdb_tt
和/或 delta_ut1_utc
变换偏移(如果已设置)。
如果需要 Time
对象是不可变的,然后设置 writeable
属性到 False
. In this case, attempting to set a value will raise a ValueError: Time object is read-only
. See the section on Caching 举个例子。
缺少值#
这个 Time
和 TimeDelta
对象支持将值标记为丢失或无效的功能。这也被称为掩蔽,对 表操作 例如接合和堆叠。
例子#
在创建对象时,可以通过以下两种方式之一将一个或多个项目设置为缺少。首先使用一个数字掩码数组::
>>> dates = np.ma.array(['2001:020', '...', '2001:060'], mask=[False, True, False])
>>> print(Time(dates, out_subfmt="date"))
['2001:020' ——— '2001:060']
排名第二的是 astropy.utils.masked.Masked
班级:
>>> from astropy.utils.masked import Masked
>>> dates = Masked(['2001:020', '', '2001:060'], mask=[False, True, False])
>>> t = Time(dates, out_subfmt="date")
>>> print(t)
['2001:020' ——— '2001:060']
您也可以使用特殊的 numpy.ma.masked
将值设置为现有的 Time
对象::
>>> t = Time(["2001:020", "2001:040", "2001:060", "2001:080"], out_subfmt="date")
>>> t[2] = np.ma.masked
>>> print(t)
['2001:020' '2001:040' ——— '2001:080']
如果要获取未屏蔽的数据,可以通过使用 unmasked
属性,或使用选定的值填充任何掩码数据::
>>> print(t.unmasked)
['2001:020' '2001:040' '2001:060' '2001:080']
>>> t_filled = t.filled('1999:365')
>>> print(t_filled)
['2001:020' '2001:040' '1999:365' '2001:080']
您还可以通过指定另一个特定值来取消设置各个元素上的遮罩, numpy.ma.nomask
**
>>> t[2] = np.ma.nomask
>>> print(t)
['2001:020' '2001:040' '2001:060' '2001:080']
这两种方法之间的一个细微区别是,当您通过使用 numpy.ma.nomask
,掩码仍然存在于内部,因此任何输出都将具有掩码。相比之下,使用 unmasked
或 filled()
删除所有掩码,因此任何输出都不会被掩码。这个 masked
属性可用于检查内部是否正在使用掩码::
>>> t.masked
True
>>> t.value
MaskedNDArray(['2001:020', '2001:040', '2001:060', '2001:080'],
dtype='<U8')
>>> t_filled.masked
False
>>> t_filled.value
array(['2001:020', '2001:040', '1999:365', '2001:080'], dtype='<U8')
备注
设置掩码时,保留实际时间数据。但是,当 initializing 使用掩码数组,任何掩码时间输入数据都会在内部被覆盖,时间相当于 2000-01-01 12:00:00
(比例和格式与其他值相同)。这是为了确保掩码隐藏的无效数据不会引发错误或警告。因此,对于使用屏蔽数据的初始化,无法恢复原始屏蔽值:
>>> dates = Masked(['2001:020', '2001:040', '2001:060'],
... mask=[False, True, False])
>>> tm = Time(dates, out_subfmt="date")
>>> tm[2] = np.ma.masked
>>> print(tm)
['2001:020' ——— ———]
>>> print(tm.unmasked)
['2001:020' '2000:001' '2001:060']
一旦对象中的一个或多个值被屏蔽,任何操作都会将这些值作为屏蔽传播,并访问格式属性,如 unix
或 value
将返回一个 Masked
对象::
>>> t[1:3] = np.ma.masked
>>> t.isot
MaskedNDArray(['2001-01-20', ———, ———, '2001-03-21'],
dtype='<U10')
您可以查看 mask
,但请注意,它是只读的。设置和清除掩码始终是通过将项设置为 masked
和 nomask
,分别为。
>>> t.mask
array([False, True, True, False])
掩码数组类型的选择#
Time
内部使用Aspy的 Masked
类来表示掩码。可以使用NumPy的数据进行初始化 MaskedArray
类,但默认情况下,所有输出都将使用 Masked
。为了向后兼容,可以设置 masked_array_type
设置为“NumPy”以确保输出使用 MaskedArray
在可能的情况下(除 Quantity
)。
自定义格式类和屏蔽值#
对象编写了自定义时间格式的高级用户 TimeFormat
子类,则可能需要修改您的类 if you wish to support masked values ,尤其是如果您早先支持 missing values 通过设置 jd2
属性为 numpy.nan
。对于不需要掩码或缺失值的应用程序,不需要任何更改。
在Astopy 6.0之前,在 TimeFormat
子类对象通过设置 jd2
属性为 numpy.nan
(但这从未由用户直接完成)。从Astopy6.0开始, Masked
使用数组,这些数组被写入以正确地传播通过(几乎)所有NumPy和 ERFA 功能。
通常,只需极少的修改即可支持 Masked
数组。通常,在输入时不需要进行任何更改,因为格式将被赋予未屏蔽的值(任何屏蔽的输入值都将替换为默认值,以确保只传入有效值)。不过,在计算输出值时,可能需要注意掩码是否正确传播 jd1
至 jd2
在 value
财产。
获取表示#
时间的瞬间可以用不同的方式表示,例如ISO格式的日期字符串 ('1999-07-23 04:31:00'
)或1998年以来的秒数 (49091460.0
)或者改为朱利安日期 (51382.187451574
)
a的表示 Time
通过获取与格式名对应的object属性,可以使用特定格式的对象。可用格式名的列表在 time format 部分。
>>> t = Time('2010-01-01 00:00:00', format='iso', scale='utc')
>>> t.jd # JD representation of time in current scale (UTC)
2455197.5
>>> t.iso # ISO representation of time in current scale (UTC)
'2010-01-01 00:00:00.000'
>>> t.unix # seconds since 1970.0 (UTC)
1262304000.0
>>> t.datetime # Representation as datetime.datetime object
datetime.datetime(2010, 1, 1, 0, 0)
例子#
得到一个 Time
对象:
>>> import matplotlib.pyplot as plt
>>> jyear = np.linspace(2000, 2001, 20)
>>> t = Time(jyear, format='jyear')
>>> plt.plot_date(t.plot_date, jyear)
>>> plt.gcf().autofmt_xdate() # orient date labels at a slant
>>> plt.draw()
转换时间刻度#
一个新的 Time
对象,但引用了一个新的 time scale 可以创建获取与时间刻度名称相对应的对象属性。可用时间刻度名称的列表位于 time scale 第节和下图说明了时间尺度变换的网络。

实例#
创建一个 Time
具有新时间刻度的对象::
>>> t = Time('2010-01-01 00:00:00', format='iso', scale='utc')
>>> t.tt # TT scale
<Time object: scale='tt' format='iso' value=2010-01-01 00:01:06.184>
>>> t.tai
<Time object: scale='tai' format='iso' value=2010-01-01 00:00:34.000>
在这个过程中 format
以及其他对象属性,如 lon
, lat
和 precision
也会传播到新对象。
如 Time Object Basics 剖面图,a Time
对象只能通过显式设置其某些元素来更改。因此,更改时间刻度的过程首先制作原始对象的副本,然后将副本中的内部时间值转换为新的时间刻度。新的 Time
对象由属性access返回。
高速缓存#
将数组转换为不同的格式可能会耗费大量时间。为了避免重复计算,每个 Time
或 TimeDelta
实例在内部缓存这样的转换:
>>> t = Time(np.arange(1e6), format='unix', scale='utc')
>>> time x = t.tt
CPU times: user 263 ms, sys: 4.02 ms, total: 267 ms
Wall time: 267 ms
>>> time x = t.tt
CPU times: user 28 µs, sys: 9 µs, total: 37 µs
Wall time: 32.9 µs
更改输出精度或子格式等操作将清除缓存。要显式清除内部缓存,请执行以下操作:
>>> del t.cache
>>> time x = t.tt
CPU times: user 263 ms, sys: 4.02 ms, total: 267 ms
Wall time: 267 ms
为了确保转换(和缓存)版本与原始版本之间的一致性,将转换后的对象设置为不可写。例如::
>>> x = t.tt
>>> x[1] = '2000:001'
Traceback (most recent call last):
...
ValueError: Time object is read-only. Make a copy() or set "writeable" attribute to True.
如果需要修改对象,请先复制一个对象,例如, x = t.tt.copy()
.
转换偏移量#
跨越上图中一个橙色圆的时间比例变换需要一个额外的偏移时间值,该值取决于模型或观测。看见 SOFA Time Scale and Calendar Tools 了解更多细节。
这两个属性 delta_ut1_utc
和 delta_tdb_tt
提供一种显式设置这些偏移时间的方法。它们分别表示时间刻度偏移UT1-UTC和TDB-TT。例如:
>>> t = Time('2010-01-01 00:00:00', format='iso', scale='utc')
>>> t.delta_ut1_utc = 0.334 # Explicitly set one part of the transformation
>>> t.ut1.iso # ISO representation of time in UT1 scale
'2010-01-01 00:00:00.334'
对于UT1到UTC偏移量,您必须插值由 International Earth Rotation and Reference Systems (IERS) Service . astropy
将自动下载并使用IER的值,这些值涵盖从1973年1月1日到未来一年的时间。此外 astropy
从1962年到1962年的数据包,与一个数据包捆绑在一起 astropy
释放。
当 delta_ut1_utc
属性未显式设置,将使用IERS值(第一次开始下载几个Mb的文件)。有关如何在中使用IER值的详细信息 astropy
时间和坐标,以及要了解如何控制自动下载,请参阅 IERS数据访问 (astropy.utils.iers ) . 下面的示例说明如何转换为 UT1
随着自动下载功能的扩展:
>>> t = Time('2016:001')
>>> t.ut1
Downloading https://maia.usno.navy.mil/ser7/finals2000A.all
|==================================================================| 3.0M/3.0M (100.00%) 6s
<Time object: scale='ut1' format='yday' value=2016:001:00:00:00.082>
备注
这个 IERS_Auto
类包含一些机制,用于根据需要自动下载最新版本来确保IERS表保持最新。这意味着IERS表可以保证拥有最先进的地球自转确定性和预测值。作为一个用户 你的责任 了解IER预测的准确性,如果你的科学依赖于此。如果你要求 UT1-UTC
对于超出IERS表数据范围的时间,将提供最接近的可用值。
在TDB到TT偏移量的情况下,大多数用户只需提供 lon
和 lat
值时创建 Time
对象。如果 delta_tdb_tt
属性,则 PyERFA 例行程序 erfa.dtdb
将用于计算TDB到TT的偏移量。请注意,如果 lon
和 lat
未显式初始化,则将使用这两个值的0.0度。
例子#
下面的代码复制了 SOFA Time Scale and Calendar Tools 文件。它执行从UTC到所有支持的时间尺度(TAI、TCB、TCG、TDB、TT、UT1、UTC)的转换。这需要观察者的位置(这里是纬度和经度)。**
>>> import astropy.units as u
>>> t = Time('2006-01-15 21:24:37.5', format='iso', scale='utc',
... location=(-155.933222*u.deg, 19.48125*u.deg))
>>> t.utc.iso
'2006-01-15 21:24:37.500'
>>> t.ut1.iso
'2006-01-15 21:24:37.834'
>>> t.tai.iso
'2006-01-15 21:25:10.500'
>>> t.tt.iso
'2006-01-15 21:25:42.684'
>>> t.tcg.iso
'2006-01-15 21:25:43.323'
>>> t.tdb.iso
'2006-01-15 21:25:42.684'
>>> t.tcb.iso
'2006-01-15 21:25:56.894'
散列#
用户可以为标量(0维)生成唯一的哈希键 Time
或 TimeDelta
物体。密钥基于的元组 jd1
, jd2
, scale
和 location
(如果存在, None
否则)。
注意两个 Time
具有不同 scale
可以相等地比较,但仍然具有不同的哈希键。这是一个由性能决定的实际考虑,但在大多数情况下代表了一种理想的行为。
打印时间数组#
如果你 times
数组包含很多元素 value
参数将显示 Time
对象 t
当它被调用或打印时。要控制要显示的元素数,请设置 threshold
争论与 np.printoptions
如下:
>>> many_times = np.arange(1000)
>>> t = Time(many_times, format='cxcsec')
>>> with np.printoptions(threshold=10):
... print(repr(t))
... print(t.iso)
<Time object: scale='tt' format='cxcsec' value=[ 0. 1. 2. ... 997. 998. 999.]>
['1998-01-01 00:00:00.000' '1998-01-01 00:00:01.000'
'1998-01-01 00:00:02.000' ... '1998-01-01 00:16:37.000'
'1998-01-01 00:16:38.000' '1998-01-01 00:16:39.000']
恒星时与地球自转角#
表观或平均恒星时间可以用以下公式计算 sidereal_time()
。该方法返回一个 Longitude
以小时角为单位,默认情况下为与 Time
对象已初始化。就像比例变换一样, ERFA C库例程在幕后使用,它支持遵循不同IAU分辨率的计算。
同样,人们可以用以下公式计算地球自转角度 earth_rotation_angle()
。与恒星时间不同的是,恒星时间是指春分,是UT1和地球时间的复杂函数,而地球自转角是指中间天体原点(CIO),是UT1的线性函数。
对于最近的国际天文学联合会的进动模型以及地球自转角,结果包括了TIO定位器(S‘),该定位器将地球中间原点定位在中间天极的赤道上,并经过了严格的极移校正。
例子#
计算恒星时间:
>>> t = Time('2006-01-15 21:24:37.5', scale='utc', location=('120d', '45d'))
>>> t.sidereal_time('mean')
<Longitude 13.08952187 hourangle>
>>> t.sidereal_time('apparent')
<Longitude 13.08950368 hourangle>
>>> t.earth_rotation_angle()
<Longitude 13.08436206 hourangle>
>>> t.sidereal_time('apparent', 'greenwich')
<Longitude 5.08950368 hourangle>
>>> t.sidereal_time('apparent', '-90d')
<Longitude 23.08950368 hourangle>
>>> t.sidereal_time('apparent', '-90d', 'IAU1994')
<Longitude 23.08950365 hourangle>
时间三角洲#
使用支持时间算术 TimeDelta
班级。以下操作可用:
这个 TimeDelta
类派生自 Time
类并共享其许多属性。一个不同的是,时间刻度必须是一天正好是86400秒。因此,刻度不能是UTC。
Quantity
带有时间单位的对象也可以用来代替 TimeDelta
。
可用的时间格式有:
格式 |
等级 |
---|---|
秒 |
|
法学博士 |
|
日期时间 |
|
quantity_str |
实例#
使用 TimeDelta
对象在以下几个示例中进行了说明:
>>> t1 = Time('2010-01-01 00:00:00')
>>> t2 = Time('2010-02-01 00:00:00')
>>> dt = t2 - t1 # Difference between two Times
>>> dt
<TimeDelta object: scale='tai' format='jd' value=31.0>
>>> dt.sec
2678400.0
>>> from astropy.time import TimeDelta
>>> dt2 = TimeDelta(50.0, format='sec')
>>> t3 = t2 + dt2 # Add a TimeDelta to a Time
>>> t3.iso
'2010-02-01 00:00:50.000'
>>> t2 - dt2 # Subtract a TimeDelta from a Time
<Time object: scale='utc' format='iso' value=2010-01-31 23:59:10.000>
>>> dt + dt2
<TimeDelta object: scale='tai' format='jd' value=31.0005787037>
>>> import numpy as np
>>> t1 + dt * np.linspace(0, 1, 5)
<Time object: scale='utc' format='iso' value=['2010-01-01 00:00:00.000'
'2010-01-08 18:00:00.000' '2010-01-16 12:00:00.000' '2010-01-24 06:00:00.000'
'2010-02-01 00:00:00.000']>
>>> import astropy.units as u
>>> t1 + 1 * u.hour
<Time object: scale='utc' format='iso' value=2010-01-01 01:00:00.000>
用于表示时间增量的字符串的人类可读的多尺度格式可通过 quantity_str
格式化。请参阅 TimeDeltaQuantityString
有关更多详细信息的类文档字符串::
>>> TimeDelta(40.1 * u.hr).quantity_str
'1d 16hr 6min'
>>> t4 = TimeDelta("-1yr 2d 23hr 10min 5.6s")
>>> print(t4)
-368d 5hr 10min 5.6s
>>> t4.to_value(subfmt="d")
'-368.215d'
现已弃用的默认设置假定数字输入为天数:
>>> t1 + 5.0
<Time object: scale='utc' format='iso' value=2010-01-06 00:00:00.000>
TimeDeltaMissingUnitWarning: Numerical value without unit or explicit format passed to TimeDelta, assuming days
这个 TimeDelta
有一个 to_value
method which supports controlling the type of the output representation by providing either a format name and optional subformat 或者有效的 astropy
单位:
>>> dt.to_value(u.hr)
744.0
>>> dt.to_value('jd', 'str')
'31.0'
时间三角洲的时间尺度#
我们已经在上面显示了两个UTC时间的差是 TimeDelta
泰式的。这是因为除非用户知道两个时间差(由于闰秒,一天并不总是有86400秒),否则无法唯一定义UTC时间差。对于所有其他时间尺度 TimeDelta
继承第一个的比例 Time
对象。
实例#
为了得到一个 TimeDelta
对象:
>>> t1 = Time('2010-01-01 00:00:00', scale='tcg')
>>> t2 = Time('2011-01-01 00:00:00', scale='tcg')
>>> dt = t2 - t1
>>> dt
<TimeDelta object: scale='tcg' format='jd' value=365.0>
什么时候? TimeDelta
从中添加或减去对象 Time
对象,比例被适当地转换,最终的比例是 Time
对象:
>>> t2 + dt
<Time object: scale='tcg' format='iso' value=2012-01-01 00:00:00.000>
>>> t2.tai
<Time object: scale='tai' format='iso' value=2010-12-31 23:59:27.068>
>>> t2.tai + dt
<Time object: scale='tai' format='iso' value=2011-12-31 23:59:27.046>
TimeDelta
我不需要把时间转换成不同的比例尺
>>> dt.tt
<TimeDelta object: scale='tt' format='jd' value=364.999999746>
>>> dt.tdb
Traceback (most recent call last):
...
ScaleValueError: Cannot convert TimeDelta with scale 'tcg' to scale 'tdb'
TimeDelta
对象也可以具有未定义的比例,在这种情况下,假定它们的比例与其他对象的比例匹配 Time
或 TimeDelta
对象(如果是UTC时间,则为TAI):
>>> t2.tai + TimeDelta(365., format='jd', scale=None)
<Time object: scale='tai' format='iso' value=2011-12-31 23:59:27.068>
重心和日心光旅行时间修正#
光子到达天文台的时间对于精确的计时工作(例如双星或系外行星的日食/凌日计时)并不特别有用。这是因为天文台位置的变化导致光子早晚到达。解决方案是计算光子到达标准位置的时间;太阳系的重心或日心。
例子#
假设您从格林威治观察到了dwarf-nova-IP-Peg,并且有一个以MJD形式,以UTC时间刻度表示的时间列表。然后创建适当的 Time
和 SkyCoord
对象并计算到达重心的光行程时间,如下所示:
>>> from astropy import time, coordinates as coord, units as u
>>> ip_peg = coord.SkyCoord("23:23:08.55", "+18:24:59.3",
... unit=(u.hourangle, u.deg), frame='icrs')
>>> greenwich = coord.EarthLocation.of_site('greenwich')
>>> times = time.Time([56325.95833333, 56325.978254], format='mjd',
... scale='utc', location=greenwich)
>>> ltt_bary = times.light_travel_time(ip_peg)
>>> ltt_bary
<TimeDelta object: scale='tdb' format='jd' value=[-0.0037715 -0.00377286]>
如果你想要光到达太阳中心的时间,那么使用:
>>> ltt_helio = times.light_travel_time(ip_peg, 'heliocentric')
>>> ltt_helio
<TimeDelta object: scale='tdb' format='jd' value=[-0.00376576 -0.00376712]>
该方法返回一个 TimeDelta
对象,可以将其添加到时间中,以给出光子到达重心或太阳中心的时间。在这里,您应该小心使用的时间刻度;有关时间刻度的更多详细信息,请参阅 时间尺度 .
日心不是一个固定的点,因此重力在日心处不断变化。因此,使用像TDB这样的相对论时间标度并不特别合适,而且,历史上,校正到太阳中心的时间是在UTC时间刻度中给出的:
>>> times_heliocentre = times.utc + ltt_helio
对重心的修正比日心更精确,因为重心是重力恒定的固定点。为了获得最大的准确度,你希望你的重心校正时间在一个时间刻度上,总是以一个统一的速率打勾,理想情况下,它的滴答频率与时钟在重心上的滴答频率有关。因此,重心校正时间通常使用TDB时间刻度:
>>> time_barycentre = times.tdb + ltt_bary
默认情况下,使用地球和太阳的位置和速度计算光波传播时间 ERFA 例程,但您也可以使用JPL星历(从动力学模型派生)来获得更精确的计算。使用喷气推进实验室星历的一个例子是:
>>> ltt_bary_jpl = times.light_travel_time(ip_peg, ephemeris='jpl')
>>> ltt_bary_jpl
<TimeDelta object: scale='tdb' format='jd' value=[-0.0037715 -0.00377286]>
>>> (ltt_bary_jpl - ltt_bary).to(u.ms)
<Quantity [-0.00132325, -0.00132861] ms>
内置星历和JPL星历的差别通常是1/100毫秒,因此内置星历应该适合大多数用途。有关可用星历的更多详细信息,包括使用JPL星历的要求,请参阅 太阳系星历 .
与类时量的相互作用#
可能的话, Quantity
具有时间单位的对象被视为 TimeDelta
具有未定义比例的对象(尽管精度必须较低)。它们也可以用作构造的输入 Time
和 TimeDelta
对象,以及 TimeDelta
对象可以转换为 Quantity
任意时间单位的对象。
实例#
使用 Quantity
具有时间单位的对象:
>>> import astropy.units as u
>>> Time(10.*u.yr, format='gps') # time-valued quantities can be used for
... # for formats requiring a time offset
<Time object: scale='tai' format='gps' value=315576000.0>
>>> Time(10.*u.yr, 1.*u.s, format='gps')
<Time object: scale='tai' format='gps' value=315576001.0>
>>> Time(2000.*u.yr, format='jyear')
<Time object: scale='tt' format='jyear' value=2000.0>
>>> Time(2000.*u.yr, format='byear')
... # but not for Besselian year, which implies
... # a different time scale
...
Traceback (most recent call last):
...
ValueError: Input values did not match the format class byear:
ValueError: cannot use Quantities for 'byear' format, as the unit of year is defined as 365.25 days, while the length of year is variable in this format. Use float instead.
>>> TimeDelta(10.*u.yr) # With a quantity, no format is required
<TimeDelta object: scale='None' format='jd' value=3652.5>
>>> dt = TimeDelta([10., 20., 30.], format='jd')
>>> dt.to(u.hr) # can convert TimeDelta to a quantity
<Quantity [240., 480., 720.] h>
>>> dt > 400. * u.hr # and compare to quantities with units of time
array([False, True, True]...)
>>> dt + 1.*u.hr # can also add/subtract such quantities
<TimeDelta object: scale='None' format='jd' value=[10.04166667 20.04166667 30.04166667]>
>>> Time(50000., format='mjd', scale='utc') + 1.*u.hr
<Time object: scale='utc' format='mjd' value=50000.0416667>
>>> dt * 10.*u.km/u.s # for multiplication and division with a
... # Quantity, TimeDelta is converted
<Quantity [100., 200., 300.] d km / s>
>>> dt * 10.*u.Unit(1) # unless the Quantity is dimensionless
<TimeDelta object: scale='None' format='jd' value=[100. 200. 300.]>
编写自定义格式#
某些应用程序可能需要自定义 Time
格式,此功能可通过 TimeFormat
班级。当在代码中定义这样的子类时,格式类和相应的名称将自动注册到可用的时间格式集中。
实例#
新格式类的关键元素通过检查 jd
格式(这是最简单的格式之一):
class TimeJD(TimeFormat):
"""
Julian Date time format.
"""
name = 'jd' # Unique format name
def set_jds(self, val1, val2):
"""
Set the internal jd1 and jd2 values from the input val1, val2.
The input values are expected to conform to this format, as
validated by self._check_val_type(val1, val2) during __init__.
"""
self._check_scale(self._scale) # Validate scale.
self.jd1, self.jd2 = day_frac(val1, val2)
@property
def value(self):
"""
Return format ``value`` property from internal jd1, jd2
"""
return self.jd1 + self.jd2
如上所述 _check_val_type(self, val1, val2)
方法可能需要重写,以验证输入是否符合格式规范。默认情况下,它检查有效的float、float数组或 Quantity
输入。相比之下 iso
format类确保输入符合字符串的ISO格式规范。
一个比较常见且更易于实现的特殊情况是对日期格式进行了小更改的格式。例如,可以插入 T
在 yday
使用以下格式 TimeYearDayTimeCustom
班级。注意 subfmts
定义在标准基础上稍作修改 TimeISO
它继承的类:
>>> from astropy.time import TimeISO
>>> class TimeYearDayTimeCustom(TimeISO):
... """
... Year, day-of-year and time as "<YYYY>-<DOY>T<HH>:<MM>:<SS.sss...>".
... The day-of-year (DOY) goes from 001 to 365 (366 in leap years).
... For example, 2000-001T00:00:00.000 is midnight on January 1, 2000.
... The allowed subformats are:
... - 'date_hms': date + hours, mins, secs (and optional fractional secs)
... - 'date_hm': date + hours, mins
... - 'date': date
... """
... name = 'yday_custom' # Unique format name
... subfmts = (('date_hms',
... '%Y-%jT%H:%M:%S',
... '{year:d}-{yday:03d}T{hour:02d}:{min:02d}:{sec:02d}'),
... ('date_hm',
... '%Y-%jT%H:%M',
... '{year:d}-{yday:03d}T{hour:02d}:{min:02d}'),
... ('date',
... '%Y-%j',
... '{year:d}-{yday:03d}'))
>>> t = Time('2000-01-01')
>>> t.yday_custom
'2000-001T00:00:00.000'
>>> t2 = Time('2016-001T00:00:00')
>>> t2.iso
'2016-01-01 00:00:00.000'
另一个比较常见的特殊情况是一种表示自特定纪元以来的时间的格式。典型的例子是Unix时间,它是自1970-01-01 00:00:00 UTC以来的秒数,不包括闰秒。如果我们想要这个价值,但是 do 想数一数闰秒。这可以通过使用TAI刻度代替UTC刻度来实现。在这种情况下,我们继承了 TimeFromEpoch
类并定义一些类属性:
>>> from astropy.time.formats import erfa, TimeFromEpoch
>>> class TimeUnixLeap(TimeFromEpoch):
... """
... Seconds from 1970-01-01 00:00:00 TAI. Similar to Unix time
... but this includes leap seconds.
... """
... name = 'unix_leap'
... unit = 1.0 / erfa.DAYSEC # in days (1 day == 86400 seconds)
... epoch_val = '1970-01-01 00:00:00'
... epoch_val2 = None
... epoch_scale = 'tai' # Scale for epoch_val class attribute
... epoch_format = 'iso' # Format for epoch_val class attribute
>>> t = Time('2000-01-01')
>>> t.unix_leap
946684832.0
>>> t.unix_leap - t.unix
32.0
超过这一点可能需要查看 astropy
代码可以获得更多的指导,但是如果你被卡住了 astropy
开发商非常乐意提供帮助。如果你写了一个格式类,这是非常有用的,我们可能会想把它包括在核心!
时区#
当A Time
对象是从时区感知构造的 datetime
,没有时区信息保存在 Time
对象。然而, Time
对象可以转换为时区感知的datetime对象。
例子#
将 Time
对象到可识别时区的datetime对象::
>>> from datetime import datetime
>>> from astropy.time import Time, TimezoneInfo
>>> import astropy.units as u
>>> utc_plus_one_hour = TimezoneInfo(utc_offset=1*u.hour)
>>> dt_aware = datetime(2000, 1, 1, 0, 0, 0, tzinfo=utc_plus_one_hour)
>>> t = Time(dt_aware) # Loses timezone info, converts to UTC
>>> print(t) # will return UTC
1999-12-31 23:00:00
>>> print(t.to_datetime(timezone=utc_plus_one_hour)) # to timezone-aware datetime
2000-01-01 00:00:00+01:00
时区数据库包,比如 pytz 例如,可以更方便地使用来创建 tzinfo
对象用于指定时区而不是 TimezoneInfo
对象。
例子#
使用 dateutil 包中,您可以解析各种受支持格式的时间,以生成 datetime.datetime
对象,然后可以使用该对象初始化 Time
对象::
>>> from dateutil.parser import parse
>>> dtime = parse('2020-10-29T08:20:46.950+1100')
>>> Time(dtime)
<Time object: scale='utc' format='datetime' value=2020-10-28 21:20:46.950000>
自定义字符串格式 strftime
和 strptime
#
这个 Time
对象支持使用在Python标准库中定义的格式规范语言来表示输出字符串 time.strftime
. 可以使用 strftime
方法。
实例#
使用 strftime
方法:
>>> from astropy.time import Time
>>> t = Time('2018-01-01T10:12:58')
>>> t.strftime('%H:%M:%S %d %b %Y')
'10:12:58 01 Jan 2018'
相反,创建一个 Time
对象从可以使用Python标准库解析的自定义日期字符串 time.strptime
(使用上面链接的相同格式语言),使用 strptime
类方法:
>>> from astropy.time import Time
>>> t = Time.strptime('23:59:60 30 June 2015', '%H:%M:%S %d %B %Y')
>>> t
<Time object: scale='utc' format='isot' value=2015-06-30T23:59:60.000>
参考/API#
确认和许可#
此程序包利用 PyERFA 的包装器 ERFA ANSI C库。本网站的版权 ERFA 软件属于NumFOCUS基金会。该库是在“BSD-3条款”许可证的条款下提供的。
这个 ERFA 经允许,类库源自国际天文学联合会的《基础天文学标准》( SOFA )库,可从http://www.iausofa.org.获得