B
    q\                 @   s  d dl Z d dlZd dlZd dlZd dlZd dlmZmZ d dlZ	d dl
mZ d dlmZ d dlmZ d dlmZ ddlmZmZmZmZ d	d
dddddddddddddddddddddd d!d"d#d$d%d&gZdgZe Ze Zd'd'd(d(d)d*Zd+d, ZG d-d. d.eZG d/d	 d	ed0Z G d1d
 d
e Z!G d2d de Z"G d3d de Z#G d4d de Z$G d5d de$Z%G d6d de$Z&G d7d de$Z'G d8d de$Z(G d9d de Z)G d:d; d;e)Z*G d<d de)Z+G d=d$ d$ej,Z-G d>d de)Z.G d?d de.Z/G d@d de/Z0G dAd de/Z1G dBd& d&e0Z2G dCd de.Z3G dDd de Z4G dEd de4Z5G dFd de4Z6G dGd de.Z7G dHd  d e7Z8G dId! d!e7Z9G dJdK dKeZ:G dLd de e:d0Z;G dMd de;Z<G dNd de;Z=G dOd% d%e;e)Z>ddPl?m@Z@mAZAmBZBmCZC dS )Q    N)OrderedDictdefaultdict)lazyproperty)AstropyDeprecationWarning)units)_erfa   )day_fracquantity_day_fractwo_sumtwo_product
TimeFormatTimeJDTimeMJDTimeFromEpochTimeUnix
TimeCxcSecTimeGPSTimeDecimalYearTimePlotDate
TimeUniqueTimeDatetime
TimeStringTimeISOTimeISOTTimeFITSTimeYearDayTimeTimeEpochDateTimeBesselianEpochTimeJulianEpochTimeDeltaFormatTimeDeltaSecTimeDeltaJDTimeEpochDateStringTimeBesselianEpochStringTimeJulianEpochStringTIME_FORMATSTIME_DELTA_FORMATSTimezoneInfoTimeDeltaDatetimeTimeDatetime64ttutctai)ZTDTZETZGMTZUTZIATc             C   sn   g }x`| D ]X}|d }xdD ]\}}| ||}qW d|krX|d t|d |d f}|| q
W t|S )a  
    Iterate through each of the sub-formats and try substituting simple
    regular expressions for the strptime codes for year, month, day-of-month,
    hour, minute, second.  If no % characters remain then turn the final string
    into a compiled regex.  This assumes time formats do not have a % in them.

    This is done both to speed up parsing of strings and to allow mixed formats
    where strptime does not quite work well enough.
    r   ))z%Yz(?P<year>\d\d\d\d))z%mz(?P<mon>\d{1,2}))z%dz(?P<mday>\d{1,2}))z%Hz(?P<hour>\d{1,2}))z%Mz(?P<min>\d{1,2}))z%Sz(?P<sec>\d{1,2})%r   $   )replacerecompileappendtuple)subfmtsZnew_subfmtsZsubfmt_tupleZ	subfmt_inZstrptime_coderegex r8   3lib/python3.7/site-packages/astropy/time/formats.py_regexify_subfmts,   s    


r:   c                   s$   e Zd ZdZeZ fddZ  ZS )TimeFormatMetaz
    Metaclass that adds `TimeFormat` and `TimeDeltaFormat` to the
    `TIME_FORMATS` and `TIME_DELTA_FORMATS` registries, respectively.
    c                sJ   t  | |||}d|kr0|jdkr0|| j|j< d|krFt|d |_|S )Nnameastropy_timer6   )super__new__r<   	_registryr:   r6   )mclsr<   basesmemberscls)	__class__r8   r9   r?   R   s    zTimeFormatMeta.__new__)__name__
__module____qualname____doc__r&   r@   r?   __classcell__r8   r8   )rE   r9   r;   J   s   r;   c               @   s   e Zd ZdZdddZdd Zedd Zejd	d Zd
d Z	edd Z
edd Zedd Zedd Zdd Zdd Zdd Zd ddZedd ZdS )!r   a  
    Base class for time representations.

    Parameters
    ----------
    val1 : numpy ndarray, list, number, str, or bytes
        Values to initialize the time or times.  Bytes are decoded as ascii.
    val2 : numpy ndarray, list, or number; optional
        Value(s) to initialize the time or times.  Only used for numerical
        input, to help preserve precision.
    scale : str
        Time scale of input value(s)
    precision : int
        Precision for seconds as floating point
    in_subfmt : str
        Select subformat for inputting string times
    out_subfmt : str
        Select subformat for outputting string times
    from_jd : bool
        If true then val1, val2 are jd1, jd2
    Fc             C   sJ   || _ || _|| _|| _|r*|| _|| _n| ||\}}| || d S )N)scale	precision	in_subfmt
out_subfmtjd1jd2_check_val_typeset_jds)selfval1val2rK   rL   rM   rN   from_jdr8   r8   r9   __init__x   s    zTimeFormat.__init__c             C   s
   t | jS )N)lenrO   )rS   r8   r8   r9   __len__   s    zTimeFormat.__len__c             C   s   |  | j| _| jS )z
Time scale)_check_scale_scale)rS   r8   r8   r9   rK      s    zTimeFormat.scalec             C   s
   || _ d S )N)r[   )rS   valr8   r8   r9   rK      s    c             C   s   | j rtjj|| jdd}|S )NF)maskcopy)maskednpZmaarrayr]   )rS   valuer8   r8   r9   mask_if_needed   s    zTimeFormat.mask_if_neededc             C   s@   d| j kr6t| j| j d< | j d jr6d| j d j_| j d S )Nr]   F)cacher`   ZisnanrP   shapeflagsZ	writeable)rS   r8   r8   r9   r]      s
    
zTimeFormat.maskc             C   s*   d| j kr tt| j| j d< | j d S )Nr_   )rd   boolr`   anyr]   )rS   r8   r8   r9   r_      s    
zTimeFormat.maskedc             C   s   | j rt| jS | jS )N)r_   r`   Z
nan_to_numrP   )rS   r8   r8   r9   
jd2_filled   s    zTimeFormat.jd2_filledc             C   s   t tS )zA
        Return the cache associated with this instance.
        )r   dict)rS   r8   r8   r9   rd      s    zTimeFormat.cachec             C   sN  |j tjkott|}|dkp@|j tjko@tt| }|rJ|sZtd| j	t
|dddk	rtj|dd}|dk	rtj|dd}yt||\}}W n  tjk
r   tdY nX dt
| dd }|dkr"t||\}}||| 7 }t||\}}nt
|dddk	r"td|dkr6t|}d	d
 }||||fS )z?Input value validation, typically overridden by derived classesNz1Input values for {0} class must be finite doublesunitF)r^   zJonly quantities with time units can be used to instantiate Time instances.g      ?z$Cannot mix float and Quantity inputsc             S   s   t | tjrt| S | S )z
            Remove ndarray subclasses since for jd1/jd2 we want a pure ndarray
            or a Python or numpy scalar.
            )
isinstancer`   ZndarrayZasarray)r\   r8   r8   r9   asarray_or_scalar   s    z5TimeFormat._check_val_type.<locals>.asarray_or_scalar)dtyper`   doubleallZisfiniterh   Zisinf	TypeErrorformatr<   getattruZQuantityr
   Z
UnitsErrorZUnitConversionErrorr   r   
zeros_like)rS   rT   rU   Zok1Zok2ZfactorZcarryrm   r8   r8   r9   rQ      s2    &



zTimeFormat._check_val_typec             C   sD   t | jdr|dkr| jj}|dkr(d}|tkr@td|t|S )a  
        Return a validated scale value.

        If there is a class attribute 'scale' then that defines the default /
        required time scale for this format.  In this case if a scale value was
        provided that needs to match the class default, otherwise return
        the class default.

        Otherwise just make sure that scale is in the allowed list of
        scales.  Provide a different error message if `None` (no value) was
        supplied.
        epoch_scaleNr,   z+Scale value '{0}' not in allowed values {1})hasattrrE   rv   TIME_SCALESScaleValueErrorrr   )rS   rK   r8   r8   r9   rZ      s    
zTimeFormat._check_scalec             C   s   t dS )zl
        Set internal jd1 and jd2 from val1 and val2.  Must be provided
        by derived classes.
        N)NotImplementedError)rS   rT   rU   r8   r8   r9   rR      s    zTimeFormat.set_jdsNc             C   s   |  | jS )aV  
        Return time representation from internal jd1 and jd2.  This is
        the base method that ignores ``parent`` and requires that
        subclasses implement the ``value`` property.  Subclasses that
        require ``parent`` or have other optional args for ``to_value``
        should compute and return the value directly.
        )rc   rb   )rS   parentr8   r8   r9   to_value  s    zTimeFormat.to_valuec             C   s   t d S )N)rz   )rS   r8   r8   r9   rb     s    zTimeFormat.value)F)N)rF   rG   rH   rI   rW   rY   propertyrK   setterrc   r]   r_   ri   r   rd   rQ   rZ   rR   r|   rb   r8   r8   r8   r9   r   a   s   
2

)	metaclassc               @   s(   e Zd ZdZdZdd Zedd ZdS )r   z
    Julian Date time format.
    This represents the number of days since the beginning of
    the Julian Period.
    For example, 2451544.5 in JD is midnight on January 1, 2000.
    jdc             C   s"   |  | j t||\| _| _d S )N)rZ   r[   r	   rO   rP   )rS   rT   rU   r8   r8   r9   rR     s    zTimeJD.set_jdsc             C   s   | j | j S )N)rO   rP   )rS   r8   r8   r9   rb      s    zTimeJD.valueN)rF   rG   rH   rI   r<   rR   r}   rb   r8   r8   r8   r9   r     s   c               @   s(   e Zd ZdZdZdd Zedd ZdS )r   z
    Modified Julian Date time format.
    This represents the number of days since midnight on November 17, 1858.
    For example, 51544.0 in MJD is midnight on January 1, 2000.
    Zmjdc             C   s:   |  | j t||\}}|tj7 }t||\| _| _d S )N)rZ   r[   r	   erfaDJM0rO   rP   )rS   rT   rU   rO   rP   r8   r8   r9   rR   -  s    
zTimeMJD.set_jdsc             C   s   | j tj | j S )N)rO   r   r   rP   )rS   r8   r8   r9   rb   7  s    zTimeMJD.valueN)rF   rG   rH   rI   r<   rR   r}   rb   r8   r8   r8   r9   r   %  s   
c               @   s(   e Zd ZdZdZdd Zedd ZdS )r   z
    Time as a decimal year, with integer values corresponding to midnight
    of the first day of each year.  For example 2000.5 corresponds to the
    ISO time '2000-07-02 00:00:00'.
    decimalyearc          	   C   s.  |  | j t||\}}t|t}t|| \}}||| 7 }|| tj}t|t}t|}	t|}
t	|}t	|}t	|}| j
 d}t|||	|
|||\}}t||d |	|
|||\}}t||| j
dd}t||| j
dd}||| |  }t|j|j\| _| _d S )Nasciir   r   )rK   rr   )rZ   r[   r   r`   Ztruncastypeintro   	ones_likeru   rK   upperencoder   dtf2dTimer	   rO   rP   )rS   rT   rU   Zsum12Zerr12iy_startZextraZy_fracr\   imonidayihriminisecrK   	jd1_start	jd2_startjd1_endjd2_endZt_startZt_endZt_fracr8   r8   r9   rR   D  s*    




zTimeDecimalYear.set_jdsc          	   C   s   | j  d}t|d| j| j\}}}}t|}t|}t	|}t	|}	t	| j}
| j  d}t
||||||	|
\}}t
||d ||||	|
\}}| j| | j|  }|| ||  }|||  }|S )Nr   r   r   )rK   r   r   r   d2dtfrO   ri   r`   r   ru   r   rP   )rS   rK   r   imsidsihmsfsr   r   r   r   r   r   r   r   r   dtZdt_endr   r8   r8   r9   rb   c  s"    



zTimeDecimalYear.valueN)rF   rG   rH   rI   r<   rR   r}   rb   r8   r8   r8   r9   r   <  s   c                   s<   e Zd ZdZd
 fdd	Zdd Zddd	ZeeZ  Z	S )r   z
    Base class for times that represent the interval from a particular
    epoch as a floating point multiple of a unit time interval (e.g. seconds
    or days).
    Fc       	   	      s@   || _ t| j| j| j| jd}|| _t ||||||| d S )N)rK   rr   )	rK   r   	epoch_val
epoch_val2rv   epoch_formatepochr>   rW   )	rS   rT   rU   rK   rL   rM   rN   rV   r   )rE   r8   r9   rW     s    
zTimeFromEpoch.__init__c       	   
   C   s   t ||d| j d\}}| jj| }| jj| }ytt||| jdd| j}W n< t	k
r } zt
d| j| j| j|W dd}~X Y nX t |jj|jj\| _| _dS )z
        Initialize the internal jd1 and jd2 attributes given val1 and val2.
        For an TimeFromEpoch subclass like TimeUnix these will be floats giving
        the effective seconds since an epoch time (e.g. 1970-01-01 00:00:00).
        g      ?)divisorr   )rK   rr   zSCannot convert from '{0}' epoch scale '{1}'to specified scale '{2}', got error:
{3}N)r	   rk   r   rO   rP   rs   r   rv   rK   	Exceptionry   rr   r<   _time)	rS   rT   rU   dayZfracrO   rP   tmerrr8   r8   r9   rR     s    zTimeFromEpoch.set_jdsNc          
   C   s   | j | jkr~|d krtdyt|| j}W n< tk
rh } ztd| j| j| j |W d d }~X Y nX |jj	|jj
 }}n| j	| j
 }}|| jj	 || jj
  | j }| |S )Nz/cannot compute value without parent Time objectzSCannot convert from '{0}' epoch scale '{1}'to specified scale '{2}', got error:
{3})rK   rv   
ValueErrorrs   r   ry   rr   r<   r   rO   rP   r   rk   rc   )rS   r{   r   r   rO   rP   Ztime_from_epochr8   r8   r9   r|     s    
zTimeFromEpoch.to_value)F)N)
rF   rG   rH   rI   rW   rR   r|   r}   rb   rJ   r8   r8   )rE   r9   r   }  s
   '
c               @   s.   e Zd ZdZdZdej ZdZdZ	dZ
dZdS )r   a  
    Unix time: seconds from 1970-01-01 00:00:00 UTC.
    For example, 946684800.0 in Unix time is midnight on January 1, 2000.

    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.
    Zunixg      ?z1970-01-01 00:00:00Nr,   iso)rF   rG   rH   rI   r<   r   DAYSECrk   r   r   rv   r   r8   r8   r8   r9   r     s   

c               @   s.   e Zd ZdZdZdej ZdZdZ	dZ
dZdS )r   z
    Chandra X-ray Center seconds from 1998-01-01 00:00:00 TT.
    For example, 63072064.184 is midnight on January 1, 2000.
    Zcxcsecg      ?z1998-01-01 00:00:00Nr+   r   )rF   rG   rH   rI   r<   r   r   rk   r   r   rv   r   r8   r8   r8   r9   r     s   
c               @   s.   e Zd ZdZdZdej ZdZdZ	dZ
dZdS )r   a  GPS time: seconds from 1980-01-06 00:00:00 UTC
    For example, 630720013.0 is midnight on January 1, 2000.

    Notes
    =====
    This implementation is strictly a representation of the number of seconds
    (including leap seconds) since midnight UTC on 1980-01-06.  GPS can also be
    considered as a time scale which is ahead of TAI by a fixed offset
    (to within about 100 nanoseconds).

    For details, see http://tycho.usno.navy.mil/gpstt.html
    Zgpsg      ?z1980-01-06 00:00:19Nr-   r   )rF   rG   rH   rI   r<   r   r   rk   r   r   rv   r   r8   r8   r8   r9   r     s   
c               @   s(   e Zd ZdZdZdZdZdZdZdZ	dS )r   a'  
    Matplotlib `~matplotlib.pyplot.plot_date` input:
    1 + number of days from 0001-01-01 00:00:00 UTC

    This can be used directly in the matplotlib `~matplotlib.pyplot.plot_date`
    function::

      >>> import matplotlib.pyplot as plt
      >>> jyear = np.linspace(2000, 2001, 20)
      >>> t = Time(jyear, format='jyear', scale='utc')
      >>> plt.plot_date(t.plot_date, jyear)
      >>> plt.gcf().autofmt_xdate()  # orient date labels at a slant
      >>> plt.draw()

    For example, 730120.0003703703 is midnight on January 1, 2000.
    Z	plot_dateg      ?g   PD:ANr,   r   )
rF   rG   rH   rI   r<   rk   r   r   rv   r   r8   r8   r8   r9   r     s   c               @   s   e Zd ZdZdS )r   z
    Base class for time formats that can uniquely create a time object
    without requiring an explicit format specifier.  This class does
    nothing but provide inheritance to identify a class as unique.
    N)rF   rG   rH   rI   r8   r8   r8   r9   r   "  s   c               @   s   e Zd ZdZdZdddZdS )TimeAstropyTimez
    Instantiate date from an Astropy Time object (or list thereof).

    This is purely for instantiating from a Time object.  The output
    format is the same as the first time instance.
    r=   Fc          	      s   |j d ttr,tfdd|j D s<td| j dkrJj |jr fdd|D }t	
dd |D }	t	
d	d |D }
nt j}|j|j }	}
jj}||	|
 |||d
d}|S )z
        Use __new__ instead of __init__ to output a class instance that
        is the same as the class of the first Time object in the list.
        r   c             3   s   | ]}t |t  kV  qd S )N)type).0r\   )val1_0r8   r9   	<genexpr>:  s   z*TimeAstropyTime.__new__.<locals>.<genexpr>z>Input values for {0} class must all be same astropy Time type.Nc                s   g | ]}t | jqS r8   )rs   r   )r   r\   )rK   r8   r9   
<listcomp>B  s    z+TimeAstropyTime.__new__.<locals>.<listcomp>c             S   s   g | ]}t |jqS r8   )r`   
atleast_1drO   )r   r\   r8   r8   r9   r   C  s    c             S   s   g | ]}t |jqS r8   )r`   r   rP   )r   r\   r8   r8   r9   r   D  s    T)rV   )flatrl   r   rp   rq   rr   r<   rK   re   r`   Zconcatenaters   r   rO   rP   rE   )rD   rT   rU   rK   rL   rM   rN   rV   valsrO   rP   r\   ZOutTimeFormatrS   r8   )rK   r   r9   r?   3  s"    

zTimeAstropyTime.__new__N)F)rF   rG   rH   rI   r<   r?   r8   r8   r8   r9   r   *  s   r   c               @   s6   e Zd ZdZdZdd Zdd Zd
dd	ZeeZ	dS )r   am  
    Represent date as Python standard library `~datetime.datetime` object

    Example::

      >>> from astropy.time import Time
      >>> from datetime import datetime
      >>> t = Time(datetime(2000, 1, 2, 12, 0, 0), scale='utc')
      >>> t.iso
      '2000-01-02 12:00:00.000'
      >>> t.tt.datetime
      datetime.datetime(2000, 1, 2, 12, 1, 4, 184000)
    datetimec             C   s,   t dd |jD s$td| j|d fS )Nc             s   s   | ]}t |tjV  qd S )N)rl   r   )r   r\   r8   r8   r9   r   b  s    z/TimeDatetime._check_val_type.<locals>.<genexpr>z3Input values for {0} class must be datetime objects)rp   r   rq   rr   r<   )rS   rT   rU   r8   r8   r9   rQ   `  s    
zTimeDatetime._check_val_typec             C   s   t j|ddddddgdgtgdt jg  t jg d}x|D ]~\}}}}}}	}
| }|jdk	rt||  jdd}|j	|d< |j
|d< |j|d< |j|d< |j|	d< |j|jd  |
d< q<W tj| j df|jd	d  \}}t||\| _| _dS )
z5Convert datetime object contained in val1 to jd1, jd2Nrefs_ok   )rf   	op_dtypes)tzinfo.g    .Ar   r   )r`   nditerobjectintcro   itemr   	utcoffsetr1   yearZmonthr   hourZminutesecondZmicrosecondr   r   rK   r   r   operandsr	   rO   rP   )rS   rT   rU   iteratorr\   iyimidr   r   dsecr   rO   rP   r8   r8   r9   rR   g  s     





zTimeDatetime.set_jdsNc             C   s<  |dk	r"| j dkr"td| j | j d}t|d| j| j	\}}}}|d }|d }	|d }
|d	 }t
j|||||	|
|dgd
gd|jg tg d}x|D ]\}}}}}}}}|dkrtd|||||||f|dk	rtj|||||||t d||d< qt||||||||d< qW | |jd S )a  
        Convert to (potentially timezone-aware) `~datetime.datetime` object.

        If ``timezone`` is not ``None``, return a timezone-aware datetime
        object.

        Parameters
        ----------
        timezone : {`~datetime.tzinfo`, None} (optional)
            If not `None`, return timezone-aware datetime.

        Returns
        -------
        `~datetime.datetime`
            If ``timezone`` is not ``None``, output will be timezone-aware.
        Nr,   z5scale is {}, must be 'utc' when timezone is supplied.r      hmsfr      )rf   r   <   zJTime {} is within a leap second but datetime does not support leap seconds)r   .)r[   ry   rr   rK   r   r   r   r   rO   ri   r`   r   rn   r   r   r   r(   Z
astimezonerc   r   )rS   Ztimezoner{   rK   iysr   r   r   ihrsiminsisecsifracsr   r   r   r   r   r   r   ifracsecoutr8   r8   r9   r|   ~  s.    


zTimeDatetime.to_value)NN)
rF   rG   rH   rI   r<   rQ   rR   r|   r}   rb   r8   r8   r8   r9   r   P  s   
0c               @   sV   e Zd ZdZejejejddej dej dfddZdd Zd	d
 Z	dd Z
dS )r(   a)  
    Subclass of the `~datetime.tzinfo` object, used in the
    to_datetime method to specify timezones.

    It may be safer in most cases to use a timezone database package like
    pytz rather than defining your own timezones - this class is mainly
    a workaround for users without pytz.
    )
utc_offsetdstr   Nc             C   sN   |dkr|dkr|dkrd}t |tj| _|| _t |tj| _dS )a  
        Parameters
        ----------
        utc_offset : `~astropy.units.Quantity` (optional)
            Offset from UTC in days. Defaults to zero.
        dst : `~astropy.units.Quantity` (optional)
            Daylight Savings Time offset in days. Defaults to zero
            (no daylight savings).
        tzname : string, `None` (optional)
            Name of timezone

        Examples
        --------
        >>> from datetime import datetime
        >>> from astropy.time import TimezoneInfo  # Specifies a timezone
        >>> import astropy.units as u
        >>> utc = TimezoneInfo()    # Defaults to UTC
        >>> utc_plus_one_hour = TimezoneInfo(utc_offset=1*u.hour)  # UTC+1
        >>> dt_aware = datetime(2000, 1, 1, 0, 0, 0, tzinfo=utc_plus_one_hour)
        >>> print(dt_aware)
        2000-01-01 00:00:00+01:00
        >>> print(dt_aware.astimezone(utc))
        1999-12-31 23:00:00+00:00
        r   NZUTC)r   	timedeltar|   rt   r   
_utcoffset_tzname_dst)rS   r   r   tznamer8   r8   r9   rW     s
    zTimezoneInfo.__init__c             C   s   | j S )N)r   )rS   r   r8   r8   r9   r     s    zTimezoneInfo.utcoffsetc             C   s
   t | jS )N)strr   )rS   r   r8   r8   r9   r     s    zTimezoneInfo.tznamec             C   s   | j S )N)r   )rS   r   r8   r8   r9   r     s    zTimezoneInfo.dst)rF   rG   rH   rI   rt   Zquantity_inputr   rW   r   r   r   r8   r8   r8   r9   r(     s   c               @   sL   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	dd Z
dd ZdS )r   z
    Base class for string-like time representations.

    This class assumes that anything following the last decimal point to the
    right is a fraction of a second.

    This is a reference implementation can be made much faster with effort.
    c             C   s$   |j jdkrtd| j|d fS )N)SUz*Input values for {0} class must be strings)rn   kindrq   rr   r<   )rS   rT   rU   r8   r8   r9   rQ     s    
zTimeString._check_val_typec       
   	      s
  d}d}y| d}W n tk
r.   d}Y n$X |d| ||d  }}t|}x|D ]\}}}t|tryt|| W n tk
r   wXY qX  fdd|D }	n6t	||  dkrqX 
   fddt||D }	|	d	 | |	d	< |	S W td
|| jdS )z@Read time from a single string, using a set of possible formats.)r   monmdayr   minsec)Nr   r   r   r   r   .g        Nc                s   g | ]}t  d | qS )Ztm_)rs   )r   	component)r   r8   r9   r     s   z+TimeString.parse_string.<locals>.<listcomp>c                s    g | ]\}}t  ||qS r8   )r   get)r   r   default)r   r8   r9   r     s    r   z"Time {0} does not match {1} format)rindexr   floatrl   r   timeZstrptimer   r2   match	groupdictziprr   r<   )
rS   timestrr6   Z
componentsdefaultsZidotfracsec_Zstrptime_fmt_or_regexr   r8   )r   r9   parse_string  s4    




zTimeString.parse_stringc          	   C   s   |  | j}|jjdkrtndd }tj|ddddddg|jgdtjg  tjg d}xR|D ]J\}}}}	}
}}||}| 	||\|d< |d< |	d< |
d< |d< |d< q^W t
j| j df|jd	d  \}}t||\| _| _dS )
z9Parse the time strings contained in val1 and set jd1, jd2r   c             S   s   t |  ddS )Nr   )encoding)r   r   )xr8   r8   r9   <lambda>&  s    z$TimeString.set_jds.<locals>.<lambda>Nr   )r   .r   r   )_select_subfmtsrM   rn   r   r   r`   r   r   ro   r   r   r   rK   r   r   r   r	   rO   rP   )rS   rT   rU   r6   	to_stringr   r\   r   r   r   r   r   r   rO   rP   r8   r8   r9   rR     s     4zTimeString.set_jdsc          
   c   s   | j  df}t|| j| j| j\}}}}| | j	d \}}}d|krTd}nd}d}	|d }
|d }|d	 }|d
 }xzt
||||
|||gD ]^\}}}}}}}|rt||| j}	t|t|t|t|t|t|t||	dV  qW dS )z
        Generator that yields a dict of values corresponding to the
        calendar date and time for the internal JD values.
        r   r   z{yday:TFNr   r   r   r   )r   r   r   r   r   r   r   yday)rK   r   r   r   r   rL   rO   ri   r   rN   r`   r   r   Z	timetupleZtm_ydayr   )rS   rK   r   r   r   r   r   str_fmtZhas_ydayr   r   r   r   r   r   r   r   r   r   r   r   r8   r8   r9   
str_kwargs2  s&    
&zTimeString.str_kwargsc             K   s   |j f |S )zWrite time to a string using a given format.

        By default, just interprets str_fmt as a format string,
        but subclasses can add to this.
        )rr   )rS   r   kwargsr8   r8   r9   format_stringQ  s    zTimeString.format_stringc             C   s   |  | j}|d \}}}| jdkrD|drD|dt| j d 7 }g }x(|  D ]}|t| j|f| qRW t	|
| jjS )Nr   z	{sec:02d}z.{fracsec:0zd})r   rN   rL   endswithr   r   r4   r   r`   ra   reshaperO   re   )rS   r6   r   r   outsr   r8   r8   r9   rb   Y  s    zTimeString.valuec                s:   t j  fdd| jD }t|dkr6td|S )zc
        Return a list of subformats where name matches ``pattern`` using
        fnmatch.
        c                s   g | ]} |d  r|qS )r   r8   )r   r   )fnmatchcasepatternr8   r9   r   s  s    z.TimeString._select_subfmts.<locals>.<listcomp>r   zNo subformats match {0})fnmatchr   r6   rX   r   rr   )rS   r   r6   r8   )r   r   r9   r   l  s
    zTimeString._select_subfmtsN)rF   rG   rH   rI   rQ   r   rR   r   r   r}   rb   r   r8   r8   r8   r9   r     s   )c                   s(   e Zd ZdZdZdZ fddZ  ZS )r   a7  
    ISO 8601 compliant date-time format "YYYY-MM-DD HH:MM:SS.sss...".
    For example, 2000-01-01 00: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
    r   ))date_hmsz%Y-%m-%d %H:%M:%Sz;{year:d}-{mon:02d}-{day:02d} {hour:02d}:{min:02d}:{sec:02d})date_hmz%Y-%m-%d %H:%Mz1{year:d}-{mon:02d}-{day:02d} {hour:02d}:{min:02d})datez%Y-%m-%dz{year:d}-{mon:02d}-{day:02d}c                s6   | dr(| jdkrtd|d d }t ||S )NZr,   z3Time input terminating in 'Z' must have scale='UTC'r   )r   rK   r   r>   r   )rS   r   r6   )rE   r8   r9   r     s
    

zTimeISO.parse_string)rF   rG   rH   rI   r<   r6   r   rJ   r8   r8   )rE   r9   r   y  s   
c               @   s   e Zd ZdZdZdZdS )r   a  
    ISO 8601 compliant date-time format "YYYY-MM-DDTHH:MM:SS.sss...".
    This is the same as TimeISO except for a "T" instead of space between
    the date and time.
    For example, 2000-01-01T00: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
    Zisot))r  z%Y-%m-%dT%H:%M:%Sz;{year:d}-{mon:02d}-{day:02d}T{hour:02d}:{min:02d}:{sec:02d})r  z%Y-%m-%dT%H:%Mz1{year:d}-{mon:02d}-{day:02d}T{hour:02d}:{min:02d})r  z%Y-%m-%dz{year:d}-{mon:02d}-{day:02d}N)rF   rG   rH   rI   r<   r6   r8   r8   r8   r9   r     s   c               @   s   e Zd ZdZdZdZdS )r   aq  
    Year, day-of-year and time as "YYYY:DOY:HH:MM:SS.sss...".
    The day-of-year (DOY) goes from 001 to 365 (366 in leap years).
    For example, 2000:001:00: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
    r   ))r  z%Y:%j:%H:%M:%Sz2{year:d}:{yday:03d}:{hour:02d}:{min:02d}:{sec:02d})r  z%Y:%j:%H:%Mz({year:d}:{yday:03d}:{hour:02d}:{min:02d})r  z%Y:%jz{year:d}:{yday:03d}N)rF   rG   rH   rI   r<   r6   r8   r8   r8   r9   r     s   c                   s8   e Zd ZdZdd Z fddZe fddZ  ZS )r*   
datetime64c             C   s$   |j jdkstd| j|d fS )NMz5Input values for {0} class must be datetime64 objects)rn   r   rq   rr   r<   )rS   rT   rU   r8   r8   r9   rQ     s    
zTimeDatetime64._check_val_typec                s2   |j jdkr|d}|d}t || d S )N)zdatetime64[M]zdatetime64[Y]zdatetime64[D]r   )rn   r<   r   r>   rR   )rS   rT   rU   )rE   r8   r9   rR     s    

zTimeDatetime64.set_jdsc                s$   | j }d| _ t j}|| _ |dS )N	   r  )rL   r>   rb   r   )rS   rL   Zret)rE   r8   r9   rb     s
    zTimeDatetime64.value)	rF   rG   rH   r<   rQ   rR   r}   rb   rJ   r8   r8   )rE   r9   r*     s   c                   sF   e Zd ZdZdZdZedd eD Zdd Ze fdd	Z	  Z
S )
r   u  
    FITS format: "[±Y]YYYY-MM-DD[THH:MM:SS[.sss]]".

    ISOT but can give signed five-digit year (mostly for negative years);

    The allowed subformats are:

    - 'date_hms': date + hours, mins, secs (and optional fractional secs)
    - 'date': date
    - 'longdate_hms': as 'date_hms', but with signed 5-digit year
    - 'longdate': as 'date', but with signed 5-digit year

    See Rots et al., 2015, A&A 574:A36 (arXiv:1409.7583).
    Zfits))r  z_(?P<year>\d{4})-(?P<mon>\d\d)-(?P<mday>\d\d)T(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d(\.\d*)?)z={year:04d}-{mon:02d}-{day:02d}T{hour:02d}:{min:02d}:{sec:02d})r  z,(?P<year>\d{4})-(?P<mon>\d\d)-(?P<mday>\d\d)z{year:04d}-{mon:02d}-{day:02d})Zlongdate_hmszc(?P<year>[+-]\d{5})-(?P<mon>\d\d)-(?P<mday>\d\d)T(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d(\.\d*)?)z>{year:+06d}-{mon:02d}-{day:02d}T{hour:02d}:{min:02d}:{sec:02d})Zlongdatez0(?P<year>[+-]\d{5})-(?P<mon>\d\d)-(?P<mday>\d\d)z{year:+06d}-{mon:02d}-{day:02d}c             c   s(   | ] }|d  |d d |d fV  qdS )r   r   z0(\((?P<scale>\w+)(\((?P<realization>\w+)\))?\))?r0   Nr8   )r   Zsubfmtr8   r8   r9   r     s   zTimeFITS.<genexpr>c          
   C   s  x6|D ]\}}}t ||}|rP qW td|| j| }|d dk	rtdt |d 	 }t
|| }|tkrtd|tt| jdkr|| _|| jkrtd| jt|d t|d t|d	 t|d
dt|ddt|ddgS )z)Read time and deprecated scale if presentz"Time {0} does not match {1} formatrK   Nz<FITS time strings should no longer have embedded time scale.z,Scale {0!r} is not in the allowed scales {1}zAInput strings for {0} class must all have consistent time scales.r   r   r   r   r   r   r   g        )r2   r   r   rr   r<   r   warningswarnr   r   FITS_DEPRECATED_SCALESr   lowerrx   sortedr[   rK   r   r   )rS   r   r6   r   r7   r   Z
fits_scalerK   r8   r8   r9   r     s.    


zTimeFITS.parse_stringc                sB   d| j kr:| j| j }| dk s.| dkr:d| j  | _ t jS )z<Convert times to strings, using signed 5 digit if necessary.Zlongg   QD:Ag    TA)rN   rO   rP   r   maxr>   rb   )rS   r   )rE   r8   r9   rb   5  s
    
zTimeFITS.value)rF   rG   rH   rI   r<   r6   r5   r   r}   rb   rJ   r8   r8   )rE   r9   r     s   
%c               @   s$   e Zd ZdZdd Zedd ZdS )r   zP
    Base class for support floating point Besselian and Julian epoch dates
    c             C   s>   |  | j tt| j}||| \}}t||\| _| _d S )N)rZ   r[   rs   r   epoch_to_jdr	   rO   rP   )rS   rT   rU   r  rO   rP   r8   r8   r9   rR   F  s    zTimeEpochDate.set_jdsc             C   s   t t| j}|| j| jS )N)rs   r   jd_to_epochrO   rP   )rS   r  r8   r8   r9   rb   L  s    zTimeEpochDate.valueN)rF   rG   rH   rI   rR   r}   rb   r8   r8   r8   r9   r   A  s   c                   s,   e Zd ZdZdZdZdZ fddZ  ZS )r   z;Besselian Epoch year as floating point value(s) like 1950.0Zbyearepb2jdepbc                s*   t |drt |drtdt ||S )z?Input value validation, typically overridden by derived classestork   z{Cannot use Quantities for 'byear' format, as the interpretation would be ambiguous. Use float with Besselian year instead. )rw   r   r>   rQ   )rS   rT   rU   )rE   r8   r9   rQ   X  s    z"TimeBesselianEpoch._check_val_type)	rF   rG   rH   rI   r<   r  r  rQ   rJ   r8   r8   )rE   r9   r   R  s
   c               @   s"   e Zd ZdZdZejZdZdZ	dS )r   z8Julian Epoch year as floating point value(s) like 2000.0Zjyearepj2jdepjN)
rF   rG   rH   rI   r<   r   ZDJYrk   r  r  r8   r8   r8   r9   r   b  s
   c               @   s$   e Zd ZdZdd Zedd ZdS )r#   zx
    Base class to support string Besselian and Julian epoch dates
    such as 'B1950.0' or 'J2000.0' respectively.
    c             C   s   | j }|jjdkrtndd }tj|d g|jtjgd}x|D ]x\}}y:||}|d |dd   }	}
t|
}|	 |kr~t	W n, t
t	tfk
r   t	d|| jY q>X ||d< q>W | | j tt| j}||jd	 \}}t||\| _| _d S )
Nr   c             S   s   t |  ddS )Nr   )r   )r   r   )r   r8   r8   r9   r   t  s    z-TimeEpochDateString.set_jds.<locals>.<lambda>)r   r   r   z"Time {0} does not match {1} format.r   )epoch_prefixrn   r   r   r`   r   ro   r   r   r   
IndexErrorUnicodeEncodeErrorrr   r<   rZ   r[   rs   r   r  r   r	   rO   rP   )rS   rT   rU   r  r   r   r\   yearsZtime_strZ
epoch_typeZyear_strr   r  rO   rP   r8   r8   r9   rR   p  s&    zTimeEpochDateString.set_jdsc                sZ   t t| j}|| j| j}| jd t| j d   fdd|jD }t	
|| jjS )Nz%.r   c                s   g | ]} | qS r8   r8   )r   r   )r   r8   r9   r     s    z-TimeEpochDateString.value.<locals>.<listcomp>)rs   r   r  rO   rP   r  r   rL   r   r`   ra   r   re   )rS   r  r  r   r8   )r   r9   rb     s
    zTimeEpochDateString.valueN)rF   rG   rH   rI   rR   r}   rb   r8   r8   r8   r9   r#   j  s   c               @   s    e Zd ZdZdZdZdZdZdS )r$   z6Besselian Epoch year as string value(s) like 'B1950.0'Z	byear_strr  r  BN)rF   rG   rH   rI   r<   r  r  r  r8   r8   r8   r9   r$     s
   c               @   s    e Zd ZdZdZdZdZdZdS )r%   z3Julian Epoch year as string value(s) like 'J2000.0'Z	jyear_strr  r  JN)rF   rG   rH   rI   r<   r  r  r  r8   r8   r8   r9   r%     s
   c               @   s   e Zd ZeZdS )TimeDeltaFormatMetaN)rF   rG   rH   r'   r@   r8   r8   r8   r9   r    s   r  c               @   s,   e Zd ZdZdd Zdd Zedd ZdS )	r    z)Base class for time delta representationsc             C   s$   |dk	r |t kr td|t |S )zU
        Check that the scale is in the allowed list of scales, or is `None`
        Nz+Scale value '{0}' not in allowed values {1})TIME_DELTA_SCALESry   rr   )rS   rK   r8   r8   r9   rZ     s    
zTimeDeltaFormat._check_scalec             C   s,   |  | j t||d| j d\| _| _d S )Ng      ?)r   )rZ   r[   r	   rk   rO   rP   )rS   rT   rU   r8   r8   r9   rR     s    zTimeDeltaFormat.set_jdsc             C   s   | j | j | j S )N)rO   rP   rk   )rS   r8   r8   r9   rb     s    zTimeDeltaFormat.valueN)rF   rG   rH   rI   rZ   rR   r}   rb   r8   r8   r8   r9   r      s   c               @   s   e Zd ZdZdZdej ZdS )r!   zTime delta in SI secondsr   g      ?N)rF   rG   rH   rI   r<   r   r   rk   r8   r8   r8   r9   r!     s   c               @   s   e Zd ZdZdZdZdS )r"   z,Time delta in Julian days (86400 SI seconds)r   g      ?N)rF   rG   rH   rI   r<   rk   r8   r8   r8   r9   r"     s   c               @   s0   e Zd ZdZdZdd Zdd Zedd Zd	S )
r)   z Time delta in datetime.timedeltar   c             C   s,   t dd |jD s$td| j|d fS )Nc             s   s   | ]}t |tjV  qd S )N)rl   r   r   )r   r\   r8   r8   r9   r     s    z4TimeDeltaDatetime._check_val_type.<locals>.<genexpr>z=Input values for {0} class must be datetime.timedelta objects)rp   r   rq   rr   r<   )rS   rT   rU   r8   r8   r9   rQ     s    
z!TimeDeltaDatetime._check_val_typec             C   sp   |  | j tj|d gdgtgtjg d}x |D ]\}}|  |d< q2W t|j	d dt
jd\| _| _d S )Nr   )rf   r   .r   g        )r   )rZ   r[   r`   r   r   ro   r   Ztotal_secondsr	   r   r   r   rO   rP   )rS   rT   rU   r   r\   r   r8   r8   r9   rR     s    
zTimeDeltaDatetime.set_jdsc             C   s`   t j| j| j d gdg| jjgtg d}x$|D ]\}}tj| d|d< q0W | 	|j
d S )Nr   )rf   r   )Zdays.r   )r`   r   rO   rP   rn   r   r   r   r   rc   r   )rS   r   r   r   r8   r8   r9   rb     s    zTimeDeltaDatetime.valueN)	rF   rG   rH   rI   r<   rQ   rR   r}   rb   r8   r8   r8   r9   r)     s
   )r   rx   r  ry   )Dr   r   r2   r   r  collectionsr   r   Znumpyr`   Zastropy.utils.decoratorsr   Zastropy.utils.exceptionsr   Zastropyr   rt   r   r   Zutilsr	   r
   r   r   __all__Z__doctest_skip__r&   r'   r
  r:   r   r;   r   r   r   r   r   r   r   r   r   r   r   r   r   r(   r   r   r   r   r*   r   r   r   r   r#   r$   r%   r  r    r!   r"   r)   Zcorer   rx   r  ry   r8   r8   r8   r9   <module>   sx   

 3AT&a3 "X(#