U
    ڲg                     @   sx   d Z ddlZddlZddlZddlmZ ejdejjZ	dZ
dZedejZdd Zdd
dZG dd dejZdS )zHelpers for :mod:`datetime`.    N)timestamp_pb2z%Y-%m-%dT%H:%M:%S.%fZz%Y-%m-%dT%H:%M:%Sah  
    (?P<no_fraction>
        \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}  # YYYY-MM-DDTHH:MM:SS
    )
    (                                        # Optional decimal part
     \.                                      # decimal point
     (?P<nanos>\d{1,9})                      # nanoseconds, maybe truncated
    )?
    Z                                        # Zulu
c                 C   s   t tj| d S )a  Convert timestamp in microseconds since the unix epoch to datetime.

    Args:
        value (float): The timestamp to convert, in microseconds.

    Returns:
        datetime.datetime: The datetime object equivalent to the timestamp in
            UTC.
    )microseconds)
_UTC_EPOCHdatetime	timedelta)value r   :/tmp/pip-unpacked-wheel-zasgy6sz/proto/datetime_helpers.py_from_microseconds,   s    
r
   Tc                 C   s,   |s"| j dk	r"| jdd|   } | tS )a  Convert a datetime to an RFC3339 timestamp string.

    Args:
        value (datetime.datetime):
            The datetime object to be converted to a string.
        ignore_zone (bool): If True, then the timezone (if any) of the
            datetime object is ignored and the datetime is treated as UTC.

    Returns:
        str: The RFC3339 formatted string representing the datetime.
    Ntzinfo)r   replace	utcoffsetstrftime_RFC3339_MICROS)r   Zignore_zoner   r   r	   _to_rfc33399   s    r   c                       s`   e Zd ZdZdZdd Z fddZedd Zd	d
 Z	e
dd Zdd Ze
dd Z  ZS )DatetimeWithNanosecondszuTrack nanosecond in addition to normal datetime attrs.

    Nanosecond can be passed only as a keyword argument.
    )_nanosecondc                 O   sR   | dd}|dkr0d|kr$td|d |d< tjj| f||}|pJd|_|S )N
nanosecondr   microsecond1Specify only one of 'microsecond' or 'nanosecond'  )pop	TypeErrorr   __new__r   )clsargskwnanosinstr   r   r	   r   U   s    
zDatetimeWithNanoseconds.__new__c                    sx   d|k}d|k}| dd}| j}|r2|r2td|rB|d |d< t j||}|rb|jd |_n|rn||_n||_|S )a@  Return a date with the same value, except for those parameters given
        new values by whichever keyword arguments are specified. For example,
        if d == date(2002, 12, 31), then
        d.replace(day=26) == date(2002, 12, 26).
        NOTE: nanosecond and microsecond are mutually exclusive arguments.
        r   r   r   r   r   )r   r   r   superr   r   r   )selfr   r   Zms_providedZns_providedZprovided_nsZ
prev_nanosr   	__class__r   r	   r   `   s    zDatetimeWithNanoseconds.replacec                 C   s   | j p| jd S )z Read-only: nanosecond precision.r   )r   r   )r!   r   r   r	   r      s    z"DatetimeWithNanoseconds.nanosecondc                 C   s<   | j dkrt| S t| j ddd}d| t|S )zReturn an RFC3339-compliant timestamp.

        Returns:
            (str): Timestamp string according to RFC3339 spec.
        r   	   0z{}.{}Z)r   r   strrjustrstripformatr   _RFC3339_NO_FRACTION)r!   r   r   r   r	   rfc3339   s    
zDatetimeWithNanoseconds.rfc3339c              
   C   s   t |}|dkr$td|t jtj|dt}|d}|dkrPd}ndt	| }t
|d|  }| |j|j|j|j|j|j|tjjdS )	ak  Parse RFC3339-compliant timestamp, preserving nanoseconds.

        Args:
            stamp (str): RFC3339 stamp, with up to nanosecond precision

        Returns:
            :class:`DatetimeWithNanoseconds`:
                an instance matching the timestamp string

        Raises:
            ValueError: if `stamp` does not match the expected format
        Nz)Timestamp: {}, does not match pattern: {}Zno_fractionr   r   r$   
   r   r   )_RFC3339_NANOSmatch
ValueErrorr)   patternr   strptimegroupr*   lenintyearmonthdayhourminutesecondtimezoneutc)r   stampZ
with_nanosbarefractionr   Zscaler   r   r	   from_rfc3339   s6    
  
z$DatetimeWithNanoseconds.from_rfc3339c                 C   sP   | j dk	r| n| jtjjd}|t }t| }| jp@| j	d }t
j||dS )zReturn a timestamp message.

        Returns:
            (:class:`~google.protobuf.timestamp_pb2.Timestamp`): Timestamp message
        Nr   r   )secondsr   )r   r   r   r<   r=   r   r5   total_secondsr   r   r   Z	Timestamp)r!   r   deltarB   r   r   r   r	   timestamp_pb   s    z$DatetimeWithNanoseconds.timestamp_pbc              
   C   s@   t |jd }t|}| |j|j|j|j|j|j|j	t
jjdS )a&  Parse RFC3339-compliant timestamp, preserving nanoseconds.

        Args:
            stamp (:class:`~google.protobuf.timestamp_pb2.Timestamp`): timestamp message

        Returns:
            :class:`DatetimeWithNanoseconds`:
                an instance matching the timestamp message
        g    .Ar-   )r5   rB   r
   r6   r7   r8   r9   r:   r;   r   r   r<   r=   )r   r>   r   r?   r   r   r	   from_timestamp_pb   s    z)DatetimeWithNanoseconds.from_timestamp_pb)__name__
__module____qualname____doc__	__slots__r   r   propertyr   r+   classmethodrA   rE   rF   __classcell__r   r   r"   r	   r   L   s   "

(r   )T)rJ   calendarr   reZgoogle.protobufr   fromtimestampr<   r=   r   r   r*   compileVERBOSEr.   r
   r   r   r   r   r   r	   <module>   s   

