
    if                    ~   d Z ddlmZ ddlZddlZddlmZmZmZmZ ddl	m
Z
mZ ddlmZmZmZmZ ej"                  dd dk  rdd	lmZmZmZ n$ej,                  Zej,                  Zej,                  Z	 	 	 	 	 	 	 	 dd
ZddZ G d d      Z ej4                  d      Z	 d	 	 	 	 	 ddZdddZddZddZddZ ddZ!y)aP  
Large parts of this module are taken from the ``isodate`` package.
https://pypi.org/project/isodate/
Modifications are made to isodate features to allow compatibility with
XSD dates and durations that are not necessarily valid ISO8601 strings.

Copyright (c) 2024, Ashley Sommer, and RDFLib contributors
Copyright (c) 2021, Hugo van Kemenade and contributors
Copyright (c) 2009-2018, Gerhard Weis and contributors
Copyright (c) 2009, Gerhard Weis
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    )annotationsN)datedatetimetime	timedelta)ROUND_FLOORDecimal)ListTupleUnioncast   )r      r   )
parse_dateparse_datetime
parse_timec                z    | |z
  }||z
  }||z  j                  t              }|||z  z
  }||z  }t        |      |fS )z-
    A divmod function with boundaries.

    )to_integralr   int)vallowhighabdivmods          BC:\Projects\mas-dev\.venv\Lib\site-packages\rdflib/xsd_datetime.pyfquotmodr   5   sP     sA!CZAE&&{3CsQw;C 3JCs8S=    c                t    |dv ry|dv ry|dk  s|dkD  rt        d      | dz  d	k(  s| d
z  d	k7  r	| dz  d	k(  ryy)zO
    Determines the number of days of a specific month in a specific year.
    )   r            
         )      	   r      r!   r&   zMonth must be in 1..12i  r   d   r(         
ValueError)yearmonths     r   max_days_in_monthr3   I   s[     ''qyEBJ122	s
q0qQr   c                      e Zd ZdZ	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zd Zd Zd Z	d Z
d	 Zdd
ZeZd ZeZddZddZd Zd ZddZy)DurationaM  
    A class which represents a duration.

    The difference to datetime.timedelta is, that this class handles also
    differences given in years and months.
    A Duration treats differences given in year, months separately from all
    other components.

    A Duration can be used almost like any timedelta object, however there
    are some restrictions:
    - It is not really possible to compare Durations, because it is unclear,
    whether a duration of 1 year is bigger than 365 days or not.
    - Equality is only tested between the two (year, month vs. timedelta)
    basic components.

    A Duration can also be converted into a datetime object, but this requires
    a start date or an end date.

    The algorithm to add a duration to a date is defined at
    http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes
    c
           	     |   t        |t              st        t        |            }t        |	t              st        t        |	            }	t        |dd      \  }
}|| _        t        |	|
z         | _        t        |||||||      | _        | j
                  dk  r%| j                  j                  dk  rt        d      yy)zN
        Initialise this Duration instance with the given parameters.
        r   r&   5Duration cannot have negative years and negative daysN)

isinstancer	   strr   monthsyearsr   tdeltadaysr0   )selfr=   secondsmicrosecondsmillisecondsminuteshoursweeksr:   r;   	new_yearss              r   __init__zDuration.__init__p   s     &'*S[)F%)CJ'E$VQ3	6UY./
'<wu
 ::>dkk..2TUU 3>r   c                    | j                   S N)__dict__r>   s    r   __getstate__zDuration.__getstate__   s    }}r   c                :    | j                   j                  |       y rH   )rI   update)r>   states     r   __setstate__zDuration.__setstate__   s    U#r   c                .    t        | j                  |      S )zU
        Provide direct access to attributes of included timedelta instance.
        )getattrr<   )r>   names     r   __getattr__zDuration.__getattr__   s     t{{D))r   c                >   g }| j                   r|j                  d| j                   z         | j                  r1d}| j                  dk  rd}|j                  || j                  z         |j                  t        | j                               dj                  |      S )zW
        Return a string representation of this duration similar to timedelta.
        z%d yearsz	%d monthsr!   z%d monthz, )r;   appendr:   r9   r<   join)r>   paramsfmts      r   __str__zDuration.__str__   s{     ::MM*tzz12;;C{{a MM#+,c$++&'yy  r   c           
     .   d| j                   j                  | j                   j                  | j                  j                  | j                  j
                  | j                  j                  t        | j                        t        | j                        fz  S )z=
        Return a string suitable for repr(x) calls.
        z&%s.%s(%d, %d, %d, years=%s, months=%s))
	__class__
__module____name__r<   r=   r?   r@   r9   r;   r:   rJ   s    r   __repr__zDuration.__repr__   sn     8NN%%NN##KKKKKK$$

O;
 
 	
r   c                Z    t        | j                  | j                  | j                  f      S )zp
        Return a hash of this instance so that it can be used in, for
        example, dicts and sets.
        )hashr<   r:   r;   rJ   s    r   __hash__zDuration.__hash__   s"    
 T[[$++tzz:;;r   c                p    t        | j                   | j                         }| j                   |_        |S )zg
        A simple unary minus.

        Returns a new Duration instance with all it's negated.
        r;   r:   )r5   r;   r:   r<   )r>   negdurations     r   __neg__zDuration.__neg__   s0     djj[$++F"kk\r   c                   t        |t              r[t        | j                  |j                  z   | j                  |j                  z         }| j                  |j                  z   |_        |S t        |t
              r7t        | j                  | j                        }| j                  |z   |_        |S 	 t        | j                        j                         r#t        | j                        j                         st        d      t        |j                        | j                  z   }t        |dd      \  }}|j                  t        | j                        z   |z   }t        |t        |            }|j                  |kD  r|}n|j                  }|j!                  |t        |      |      }| j                  |z   S # t"        $ r Y t$        S w xY w)ze
        Durations can be added with Duration, timedelta, date and datetime
        objects.
        rc   >fractional years or months not supported for date calculationsr!      r1   r2   day)r8   r5   r;   r:   r<   r   float
is_integerr0   r	   r2   r   r1   r   r3   rj   replaceAttributeErrorNotImplemented)	r>   othernewdurationnewmonthcarrynewyearmaxdaysnewdaynewdts	            r   __add__zDuration.__add__   sx   
 eX&"jj5;;.t{{U\\7QK "&u||!;Ky)"DKKHK!%u!4K	 $**%002uT[[7I7T7T7V T  !( 4t{{ BH&xB7OE8 ::DJJ7%?G,Wc(mDGyy7" MMwc(mMPE;;&& 			s   4DF; ;	GGc                    t        |t              r=t        | j                  |z  | j                  |z        }| j
                  |z  |_        |S t        S )Nrc   )r8   r   r5   r;   r:   r<   ro   r>   rp   rq   s      r   __mul__zDuration.__mul__   sH    eS!"e);DKKRWDWXK!%u!4Kr   c                p   t        |t              r[t        | j                  |j                  z
  | j                  |j                  z
        }| j                  |j                  z
  |_        |S 	 t        | j                  | j                        }| j                  |z
  |_        |S # t
        $ r Y t        S w xY w)zj
        It is possible to subtract Duration and timedelta objects from Duration
        objects.
        rc   )r8   r5   r;   r:   r<   	TypeErrorro   rz   s      r   __sub__zDuration.__sub__   s    
 eX&"jj5;;.t{{U\\7QK "&u||!;K	"DKKHK!%u!4K 		s   -6B$ $	B54B5c                   t        |t              rt               }||_        || z
  S 	 t	        | j
                        j                         r#t	        | j                        j                         st        d      t        |j                        | j                  z
  }t        |dd      \  }}|j                  t        | j
                        z
  |z   }t        |t        |            }|j                  |kD  r|}n|j                  }|j!                  |t        |      |      }|| j                  z
  S # t"        $ r Y t$        S w xY w)zp
        It is possible to subtract Duration objects from date, datetime and
        timedelta objects.
        rg   r!   rh   ri   )r8   r   r5   r<   rk   r;   rl   r:   r0   r	   r2   r   r1   r   r3   rj   rm   rn   ro   )	r>   rp   tmpdurrr   rs   rt   ru   rv   rw   s	            r   __rsub__zDuration.__rsub__  s    eY'ZF!FMD= 	 $**%002uT[[7I7T7T7V T  !( 4t{{ BH&xB7OE8 ::DJJ7%?G,Wc(mDGyy7" MMwc(mMPE4;;&& 		s   DD/ /	E ?E c                &   t        |t              rT| j                  dz  | j                  z   |j                  dz  |j                  z   k(  r| j                  |j                  k(  ryy| j                  dk(  r| j                  dk(  r| j                  |k(  S y)z
        If the years, month part and the timedelta part are both equal, then
        the two Durations are considered equal.
        r&   TFr   r8   r5   r;   r:   r<   r>   rp   s     r   __eq__zDuration.__eq__8  s|    
 eX&

R$++-b 5<</++- ::?t{{a/;;%''r   c                &   t        |t              rT| j                  dz  | j                  z   |j                  dz  |j                  z   k7  s| j                  |j                  k7  ryy| j                  dk(  r| j                  dk(  r| j                  |k7  S y)z
        If the years, month part or the timedelta part is not equal, then
        the two Durations are considered not equal.
        r&   TFr   r   r   s     r   __ne__zDuration.__ne__I  s|    
 eX&

R$++-b 5<</, ::?t{{a/;;%''r   Nc                b    ||t        d      ||t        d      ||| z   |z
  S ||| z
  z
  S )z
        Convert this duration into a timedelta object.

        This method requires a start datetime or end datetime, but raises
        an exception if both are given.
        zstart or end requiredzonly start or end allowedr/   )r>   startends      r   totimedeltazDuration.totimedeltaZ  sS     =S[455899DLE))cDj!!r   )	r   r   r   r   r   r   r   r   r   )r=   rk   r?   rk   r@   rk   rA   rk   rB   rk   rC   rk   rD   rk   r:   Union[Decimal, float, int, str]r;   r   )rp   z*Union[Duration, timedelta, date, datetime])rp   Union[Duration, timedelta])rp   z Union[timedelta, date, datetime])NN)r]   r\   __qualname____doc__rF   rK   rO   rS   rY   r^   ra   re   rx   __radd__r{   __rmul__r~   r   r   r   r    r   r   r5   r5   Y   s    0 2312VV V 	V
 V V V V 0V /V8$*!
<'R H H*'R"""r   r5   a  ^(?P<sign>[+-])?P(?!\b)(?P<years>[0-9]+([,.][0-9]+)?Y)?(?P<months>[0-9]+([,.][0-9]+)?M)?(?P<weeks>[0-9]+([,.][0-9]+)?W)?(?P<days>[0-9]+([,.][0-9]+)?D)?((?P<separator>T)(?P<hours>[0-9]+([,.][0-9]+)?H)?(?P<minutes>[0-9]+([,.][0-9]+)?M)?(?P<seconds>[0-9]+([,.][0-9]+)?S)?)?$c           
        t        | t              st        d|       t        j	                  |       }|s| j                  d      rt        | dd       }|r`|j                  dk(  rQ|j                  dk(  rBt        |j                  |j                  |j                  |j                  |j                        S t        |j                  |j                  |j                  |j                  |j                  |j                  |j                        S t!        d| z         |j#                         }|j%                         D ]^  \  }}|d	vs|d
||<   |dv r%t'        ||   dd j)                  dd            ||<   ;t+        ||   dd j)                  dd            ||<   ` |rG|d   dk(  r?|d   dk(  r7t        |d   |d   |d   |d   |d         }|d   dk(  rt        d      |z
  }|S t        t-        t&        |d         t-        t&        |d         |d   |d   |d   |d   |d         }|d   dk(  rt        d      |z
  }|S )a  
    Parses an ISO 8601 durations into datetime.timedelta or Duration objects.

    If the ISO date string does not contain years or months, a timedelta
    instance is returned, else a Duration instance is returned.

    The following duration formats are supported:
      -``PnnW``                  duration in weeks
      -``PnnYnnMnnDTnnHnnMnnS``  complete duration specification
      -``PYYYYMMDDThhmmss``      basic alternative complete date format
      -``PYYYY-MM-DDThh:mm:ss``  extended alternative complete date format
      -``PYYYYDDDThhmmss``       basic alternative ordinal date format
      -``PYYYY-DDDThh:mm:ss``    extended alternative ordinal date format

    The '-' is optional.

    Limitations:  ISO standard defines some restrictions about where to use
    fractional numbers and which component and format combinations are
    allowed. This parser implementation ignores all those restrictions and
    returns something when it is able to find all necessary components.
    In detail:
    - it does not check, whether only the last component has fractions.
    - it allows weeks specified with all other combinations
    The alternative format does not support durations with years, months or
    days set to 0.
    zExpecting a string: Pr!   Nr   )r=   r?   r@   rB   rC   )r=   r?   r@   rB   rC   r:   r;   z Unable to parse duration string )	separatorsign0nrc   ,.r;   r:   r=   rC   rB   r?   rD   )r=   rC   rB   r?   rD   r   -)r;   r:   r=   rC   rB   r?   rD   )r8   r9   r}   ISO8601_PERIOD_REGEXmatch
startswithr   r1   r2   r   rj   secondmicrosecondminutehourr5   r0   	groupdictitemsr	   rm   rk   r   )
dur_stringas_timedelta_if_possibler   durdtgroupskeyr   rets           r   parse_xsd_durationr   x  s_   : j#&.zn=>> &&z2E  %":ab>2E'EJJ!Oq@P !!LL!&!2!2!LL**   !LL!&!2!2!LL** ;;**  ;jHII__FLLNS++{"s))%fSk#2&6&>&>sC&HIs $F3K$4$<$<S#$FGs #  F7Oq$8VH=MQR=R/9%9%/
 &>S A,$C J ww0!12/9%9%/
 &>S 1+#CJr   c                   |sJg }d}d}t        | t              r| j                  dk(  r| j                  dk(  rnd}| j                  dz  | j                  z   }|dk  rd}t	        |      }t        |d      \  }}|r|j                  t        |      dz          | j                  r|j                  t        |      dz          | j                  } | j                  dz  | j                  z   dz  | j                  z   }|dk  r'|rt        d	      |rt        d
      d}t	        |      }|dk(  rnt        |d      \  }	}t        |	d      \  }
}	t        |
d      \  }}
t        |d      \  }}|r|j                  t        |      dz          |s|
s|	s|r|j                  d       |r|j                  t        |      dz          |
r|j                  t        |
      dz          |	s|rM|r&|j                  d|	|fz  j                  d             n|j                  d|	z         |j                  d       |r|rdnddj                  |      z   S |rdS dS | j                  dk  rdt	        | j                  dz         dS d| j                  dz   dS )NFr   Tr&   YMiQ i@B r7   z@Duration cannot have positive years and months but negative days<      DTHz%d.%06d0z%dSz-Pr    z-P0DP0Dr#   W)r8   r5   r;   r:   absdivmodrU   r9   r<   r=   r?   r@   r0   rstriprV   )tdtin_weeksr   minushas_year_or_monthr:   rE   
new_monthsusecsr?   rB   rC   r=   s                r   duration_isoformatr     sp   !c8$yyA~#**/$(!R#**4A: E [F )/vr(:%	:JJs9~34::JJs:45**Cxx%'3;;6'ACDTDTT19 K  # V  EJEA:#E73NGU%gr2GW#GR0NE7 +KD%

3t9s?+7e

3JJs5zC/0JJs7|c12e

I%0@$@#H#H#MN

4'>2JJsO!Dsbggcl:: #6--88a<CHHM*+1--388q=/##r   c                   | j                   dk(  r| j                  d      }n| j                  d      }| j                  |S | j                  d      }|dk(  r|dz   S |d   }|dk(  s|dk(  r|d	d  }|}nd}||d d
 z   dz   |d
d  z   }||z   S )Nr   z%Y-%m-%dT%H:%M:%Sz%Y-%m-%dT%H:%M:%S.%fz%zz+0000Z+r   r!      :)r   strftimetzinfo)dt	no_tz_stroffset_string
first_charr   tz_parts         r   xsd_datetime_isoformatr     s    	~~KK 34	KK 67		yyD)G#s?""1%

c 1)!"-MDDr**S0=3DD7""r   c                   | j                  d      s| j                  d      r| dd } | j                  d      r| dd } d}nd}d	| v r| j                  d	      d
   } nH| j                  d      }|d
kD  r| d| } n,| j	                  dd      }t        |      dkD  rd|d   v r|d
   } d| vrt        d      t        |s|       S d| z         S )a;  
    XSD Dates have more features than ISO8601 dates, specifically
    XSD allows timezones on dates, that must be stripped off.
    Also, XSD requires dashed separators, while ISO8601 is optional.
    RDFLib test suite has some date strings with times, the times are expected
    to be dropped during parsing.
    r   zNr   r   r!   TFr   r   r   r   z0XSD Date string must contain at least two dashes)endswithr   splitrfindrsplitlenr0   r   )date_stringr   has_plussplit_partss       r   parse_xsd_dater   1  s     C K$8$8$=!#2&c"!!"o
k "'',Q/$$S)a<%ix0K%,,S!4K;!#{2(>)!n
+KLLkHHS;5FHHr   c                   | j                  d      s| j                  d      r| dd } | j                  d      r| dd } d}nd}| j                  d	      }|d
kD  r| d| } n,| j                  dd      }t	        |      dkD  rd|d   v r|d
   } t	        |       dk  rt        d      | j                  d      } 	 t        |s| nd| z         }t        |dd      S # t
        $ r t        d      w xY w)z
    XSD gYear has more features than ISO8601 dates, specifically
    XSD allows timezones on a gYear, that must be stripped off.
    r   r   Nr   r   r!   TFr   r   r   r(   z2gYear string must be at least 4 numerals in lengthr   z$gYear string must be a valid integer)	r   r   r   r   r   r0   lstripr   r   )gyear_stringr   r   r   ys        r   parse_xsd_gyearr   T  s   
 S!\%:%:3%?#CR(s##AB'!!#&H!|#IX."))#q1{aC;r?$:&q>L
<1MNN&&s+LAEl0BD 1a=  A?@@As   6C C*c                   | j                  d      s| j                  d      r| dd } | j                  d      r| dd } d}nd}| j                  d	      }|d
kD  r| d| } n,| j                  dd      }t	        |      dkD  rd|d   v r|d
   } | j                  dd      }t	        |      dk  rt        d      t	        |d
         dk  rt        d      t	        |d         dk  rt        d      |d
   j                  d      }|d   j                  d      }	 t        |s|nd|z         }	 t        |      }t        ||d      S # t        $ r t        d      w xY w# t        $ r t        d      w xY w)z
    XSD gYearMonth has more features than ISO8601 dates, specifically
    XSD allows timezones on a gYearMonth, that must be stripped off.
    r   r   Nr   r   r!   TFr   r   r   r   z+XSD gYearMonth string must contain one dashr(   z:gYearMonth Year part must be at least 4 numerals in lengthz:gYearMonth Month part must be exactly 2 numerals in lengthr   z,gYearMonth Year part must be a valid integerz-gYearMonth Month part must be a valid integer)
r   r   r   r   r   r   r0   r   r   r   )	
gym_stringr   r   r   year_month_partsyear_stringmonth_stringr   ms	            r   parse_xsd_gyearmonthr   s  s   
 3:#6#6s#;_
S!^
$H!|	*
 ''Q/{aC;r?$:$QJ!''Q/
q FGG
A!#UVV	a 	!A	%UVV"1%,,S1K#A&--c2LI5s[/@BJ 1a=  IGHHI  JHIIJs   E *E EE/)r   r	   r   Union[Decimal, int]r   r   returnzTuple[int, Decimal])r1   r   r2   r   r   r   )T)r   r9   r   boolr   r   )F)r   r   r   r   r   r9   )r   r   )r   r9   )r   r9   )r   r9   )"r   
__future__r   resysr   r   r   r   decimalr   r	   typingr
   r   r   r   version_infoisodater   r   r   fromisoformatr   r3   r5   compiler   r   r   r   r   r   r   r   r   r   <module>r      s   !F # 	 
 4 4 ( + +BQ*$>> ##J++N##J	*2E( N" N"b "rzz-
  7;^^/3^^B@$F#* IF>'r   