U
    ‰dþ  ã                   @   sî   d Z ddlZdZed ed  dks(t‚e ddd¡Ze ddd	¡Ze ddd
¡ZdZG dd„ deƒZ	G dd„ de	ƒZ
G dd„ de	ƒZG dd„ de	ƒZG dd„ de	ƒZG dd„ de	ƒZdd„ Zdd„ Zdd„ ZdZdd „ Zd!d"„ Zd#d$„ ZdS )%a°  
Tools for working with dates and times in Excel files.

The conversion from ``days`` to ``(year, month, day)`` starts with
an integral "julian day number" aka JDN.
FWIW:

- JDN 0 corresponds to noon on Monday November 24 in Gregorian year -4713.

More importantly:

- Noon on Gregorian 1900-03-01 (day 61 in the 1900-based system) is JDN 2415080.0
- Noon on Gregorian 1904-01-02 (day  1 in the 1904-based system) is JDN 2416482.0

é    N)i«Ù$ iaß$ é   i¶  ip  ik  é   é   é   )i‚$- iÌ- c                   @   s   e Zd ZdZdS )ÚXLDateErrorz-A base class for all datetime-related errors.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú//tmp/pip-unpacked-wheel-zwq1az3t/xlrd/xldate.pyr   #   s   r   c                   @   s   e Zd ZdZdS )ÚXLDateNegativez``xldate < 0.00``Nr   r   r   r   r   r   '   s   r   c                   @   s   e Zd ZdZdS )ÚXLDateAmbiguouszGThe 1900 leap-year problem ``(datemode == 0 and 1.0 <= xldate < 61.0)``Nr   r   r   r   r   r   +   s   r   c                   @   s   e Zd ZdZdS )ÚXLDateTooLargezGregorian year 10000 or laterNr   r   r   r   r   r   /   s   r   c                   @   s   e Zd ZdZdS )ÚXLDateBadDatemodez#``datemode`` arg is neither 0 nor 1Nr   r   r   r   r   r   3   s   r   c                   @   s   e Zd ZdS )ÚXLDateBadTupleN)r   r	   r
   r   r   r   r   r   7   s   r   c                 C   sŠ  |dkrt |ƒ‚| dkrdS | dk r,t| ƒ‚t| ƒ}| | }tt|d ƒƒ}d|  kr`dksfn t‚|dkr„d } }}|d7 }nt|dƒ\}}t|dƒ\}}|t| kr´t| ƒ‚|dkrÌddd|||fS |d	k rä|dkrät| ƒ‚|t	|  }	|	d
 d d d d
 |	 d d
 d }
|
d d
 d d }|d d d }|dL }|dkrj|
d d |d ||||fS |
d d |d ||||fS dS )aU  
    Convert an Excel number (presumed to represent a date, a datetime or a time) into
    a tuple suitable for feeding to datetime or mx.DateTime constructors.

    :param xldate: The Excel number
    :param datemode: 0: 1900-based, 1: 1904-based.
    :raises xlrd.xldate.XLDateNegative:
    :raises xlrd.xldate.XLDateAmbiguous:

    :raises xlrd.xldate.XLDateTooLarge:
    :raises xlrd.xldate.XLDateBadDatemode:
    :raises xlrd.xldate.XLDateError:
    :returns: Gregorian ``(year, month, day, hour, minute, nearest_second)``.

    .. warning::

      When using this function to interpret the contents of a workbook, you
      should pass in the :attr:`~xlrd.book.Book.datemode`
      attribute of that workbook. Whether the workbook has ever been anywhere
      near a Macintosh is irrelevant.

    .. admonition:: Special case

        If ``0.0 <= xldate < 1.0``, it is assumed to represent a time;
        ``(0, 0, 0, hour, minute, second)`` will be returned.

    .. note::

        ``1904-01-01`` is not regarded as a valid date in the ``datemode==1``
        system; its "serial number" is zero.
    ©r   r   ç        )r   r   r   r   r   r   g     õ@r   i€Q r   é<   é=   é   ie/ i±: é   iS  éµ  i  iM  i @  é   é
   ik  é	   él  N)
r   r   ÚintÚroundÚAssertionErrorÚdivmodÚ_XLDAYS_TOO_LARGEr   r   Ú
_JDN_delta)ÚxldateÚdatemodeÚxldaysÚfracÚsecondsÚhourÚminuteÚsecondÚminutesÚjdnZyregÚmpÚdr   r   r   Úxldate_as_tuple;   s:     
(
r0   c                 C   s^   |r
t }n| dk rt}nt}t| ƒ}| | }tt|d ƒƒ}t|dƒ\}}|t ||d|¡ S )zá
    Convert an Excel date/time number into a :class:`datetime.datetime` object.

    :param xldate: The Excel number
    :param datemode: 0: 1900-based, 1: 1904-based.

    :returns: A :class:`datetime.datetime` object.
    r   g    p™”Aiè  r   )Ú
epoch_1904Ú
epoch_1900Úepoch_1900_minus_1r   r   r!   ÚdatetimeÚ	timedelta)r$   r%   ÚepochÚdaysÚfractionr(   Zmillisecondsr   r   r   Úxldate_as_datetime‚   s    r9   c                 C   s(   | d rdS | d rdS | d r$dS dS )Nr   r   éd   r   i  r   )Úyr   r   r   Ú_leap¤   s       r<   )Nr   é   r   r   r   r   r   r   r   r   r   r   c           
      C   sŠ  | \}}}|dkrt |ƒ‚|dkr6|dkr6|dkr6dS d|  krJdks`n td|||ff ƒ‚d|  krtdksŠn td	|||ff ƒ‚|dk s¶|t| krÊ|d
kr¶|dkr¶t|ƒsÊtd|||ff ƒ‚|d }|}|dkrð|d }|d }n|d }d| d d| d d  | d |d d d d  }|t|  }	|	dkrZtd|||ff ƒ‚|	dk r‚|dkr‚td|||ff ƒ‚t|	ƒS )aê  
    Convert a date tuple (year, month, day) to an Excel date.

    :param year: Gregorian year.
    :param month: ``1 <= month <= 12``
    :param day: ``1 <= day <= last day of that (year, month)``
    :param datemode: 0: 1900-based, 1: 1904-based.
    :raises xlrd.xldate.XLDateAmbiguous:
    :raises xlrd.xldate.XLDateBadDatemode:
    :raises xlrd.xldate.XLDateBadTuple:
      ``(year, month, day)`` is too early/late or has invalid component(s)
    :raises xlrd.xldate.XLDateError:
    r   r   r   il  i'  zInvalid year: %rr   r   zInvalid month: %ré   é   zInvalid day: %rr   r   r   r   r   iÓ  é   é    iT  é¸   r:   zInvalid (year, month, day): %rr   zBefore 1900-03-01: %r)r   r   Ú_days_in_monthr<   r#   r   Úfloat)
Z
date_tupler%   ÚyearÚmonthÚdayZYpÚMZMpr-   r&   r   r   r   Úxldate_from_date_tuple­   sL    

ÿÿÿÿ
ÿÿÿ
rI   c                 C   s‚   | \}}}d|  krdk rjn nHd|  kr6dk rjn n0d|  krNdk rjn n|d | d | d S t d|||ff ƒ‚dS )a-  
    Convert a time tuple ``(hour, minute, second)`` to an Excel "date" value
    (fraction of a day).

    :param hour: ``0 <= hour < 24``
    :param minute: ``0 <= minute < 60``
    :param second: ``0 <= second < 60``
    :raises xlrd.xldate.XLDateBadTuple: Out-of-range hour, minute, or second
    r   é   r   g      N@g      8@z"Invalid (hour, minute, second): %rN)r   )Z
time_tupler)   r*   r+   r   r   r   Úxldate_from_time_tupleÜ   s    

HrK   c                 C   s"   t | dd… |ƒt| dd… ƒ S )a+  
    Convert a datetime tuple ``(year, month, day, hour, minute, second)`` to an
    Excel date value.
    For more details, refer to other xldate_from_*_tuple functions.

    :param datetime_tuple: ``(year, month, day, hour, minute, second)``
    :param datemode: 0: 1900-based, 1: 1904-based.
    Nr   )rI   rK   )Zdatetime_tupler%   r   r   r   Úxldate_from_datetime_tupleì   s    
ÿÿrL   )r   r4   r#   r    r1   r2   r3   r"   Ú
ValueErrorr   r   r   r   r   r   r0   r9   r<   rC   rI   rK   rL   r   r   r   r   Ú<module>   s(   G"/