<commit_before>"""
Performs conversions of netCDF time coordinate data to/from datetime objects.
"""
import math, numpy, re, time
from datetime import datetime as real_datetime
from datetime import tzinfo, timedelta
from calendar import monthrange

_units = ['days','hours','minutes','seconds','day','hour','minute','second']
_calendars = ['standard','gregorian','proleptic_gregorian','noleap','julian','all_leap','365_day','366_day','360_day']

__version__ = '1.0'

# Adapted from http://delete.me.uk/2005/03/iso8601.html
ISO8601_REGEX = re.compile(r"(?P<year>[0-9]{1,4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})"
    r"(((?P<separator1>.)(?P<hour>[0-9]{1,2}):(?P<minute>[0-9]{1,2})(:(?P<second>[0-9]{1,2})(\.(?P<fraction>[0-9]+))?)?)?"
    r"((?P<separator2>.?)(?P<timezone>Z|(([-+])([0-9]{1,2}):([0-9]{1,2}))))?)?)?)?"
)
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{1,2}):(?P<minutes>[0-9]{1,2})")

class datetime:
    """
Phony datetime object which mimics the python datetime object,
but allows for dates that don't exist in the proleptic gregorian calendar.
Doesn't do timedelta operations, doesn't overload + and -.

Has strftime, timetuple and __repr__ methods.  The format
of the string produced by __repr__ is controlled by self.format
(default %Y-%m-%d %H:%M:%S).

Instance variables are year,month,day,hour,minute,second,dayofwk,dayofyr
and format.
    """
    def __init__(self,year,month,day,hour=0,minute=0,second=0,dayofwk=-1,dayofyr=1):
        """dayofyr set to 1 by default - otherwise time.strftime will complain"""
        self.year=year
        self.month=month
        self.day=day
        self.hour=hour
        self.minute=minute
        self.dayofwk=dayofwk
        self.dayofyr=dayofyr
        self.second=second
        self.format='%Y-%m-%d %H:%M:%S'
    def strftime(self,format=None):
        if format is None:
            format = self.format
        return _strftime(self,format)
    def timetuple(self):
        return (self.year,self.month,self.day,self.hour,self.minute,self.second,self.dayofwk,self.dayofyr,-1)
    def __repr__(self):
        return self.strftime(self.format)
    def __eq__(self, date):
        return self.strftime('%Y-%m-%d %H:%M:%S') == date.strftime('%Y-%m-%d %H:%M:%S')


def JulianDayFromDate(date,calendar='standard'):

    """

creates a Julian Day from a 'datetime-like' object.  Returns the fractional
Julian Day (resolution 1 second).

if calendar='standard' or 'gregorian' (default), Julian day follows Julian
Calendar on and before 1582-10-5, Gregorian calendar after 1582-10-15.

if calendar='proleptic_gregorian', Julian Day follows gregorian calendar.

if calendar='julian', Julian Day follows julian calendar.

Algorithm:

<NAME> (1998) Astronomical Algorithms (2nd Edition). Willmann-Bell,
Virginia. p. 63

    """<commit_msg>Implement <> comparison for datetimes<commit_after>"""
Performs conversions of netCDF time coordinate data to/from datetime objects.
"""
import math, numpy, re, time
from datetime import datetime as real_datetime
from datetime import tzinfo, timedelta
from calendar import monthrange

_units = ['days','hours','minutes','seconds','day','hour','minute','second']
_calendars = ['standard','gregorian','proleptic_gregorian','noleap','julian','all_leap','365_day','366_day','360_day']

__version__ = '1.0'

# Adapted from http://delete.me.uk/2005/03/iso8601.html
ISO8601_REGEX = re.compile(r"(?P<year>[0-9]{1,4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})"
    r"(((?P<separator1>.)(?P<hour>[0-9]{1,2}):(?P<minute>[0-9]{1,2})(:(?P<second>[0-9]{1,2})(\.(?P<fraction>[0-9]+))?)?)?"
    r"((?P<separator2>.?)(?P<timezone>Z|(([-+])([0-9]{1,2}):([0-9]{1,2}))))?)?)?)?"
)
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{1,2}):(?P<minutes>[0-9]{1,2})")

class datetime:
    """
Phony datetime object which mimics the python datetime object,
but allows for dates that don't exist in the proleptic gregorian calendar.
Doesn't do timedelta operations, doesn't overload + and -.

Has strftime, timetuple and __repr__ methods.  The format
of the string produced by __repr__ is controlled by self.format
(default %Y-%m-%d %H:%M:%S).

Instance variables are year,month,day,hour,minute,second,dayofwk,dayofyr
and format.
    """
    def __init__(self,year,month,day,hour=0,minute=0,second=0,dayofwk=-1,dayofyr=1):
        """dayofyr set to 1 by default - otherwise time.strftime will complain"""
        self.year=year
        self.month=month
        self.day=day
        self.hour=hour
        self.minute=minute
        self.dayofwk=dayofwk
        self.dayofyr=dayofyr
        self.second=second
        self.format='%Y-%m-%d %H:%M:%S'
    def strftime(self,format=None):
        if format is None:
            format = self.format
        return _strftime(self,format)
    def timetuple(self):
        return (self.year,self.month,self.day,self.hour,self.minute,self.second,self.dayofwk,self.dayofyr,-1)
    def __repr__(self):
        return self.strftime(self.format)
    def __eq__(self, date):
        return self.strftime('%Y-%m-%d %H:%M:%S') == date.strftime('%Y-%m-%d %H:%M:%S')
    
    def __lt__(self, other):
        if isinstance(other, (datetime, real_datetime)):
            return self.strftime('%Y-%m-%d %H:%M:%S') < other.strftime('%Y-%m-%d %H:%M:%S')
        return NotImplemented
    
    def __gt__(self, other):
        if isinstance(other, (datetime, real_datetime)):
            return self.strftime('%Y-%m-%d %H:%M:%S') > other.strftime('%Y-%m-%d %H:%M:%S')
        return NotImplemented


def JulianDayFromDate(date,calendar='standard'):

    """

creates a Julian Day from a 'datetime-like' object.  Returns the fractional
Julian Day (resolution 1 second).

if calendar='standard' or 'gregorian' (default), Julian day follows Julian
Calendar on and before 1582-10-5, Gregorian calendar after 1582-10-15.

if calendar='proleptic_gregorian', Julian Day follows gregorian calendar.

if calendar='julian', Julian Day follows julian calendar.

Algorithm:

<NAME> (1998) Astronomical Algorithms (2nd Edition). Willmann-Bell,
Virginia. p. 63

    """
{'fraction_non_alphanumeric': 0.1800262812089356, 'fraction_numerical': 0.03252299605781866, 'mean_word_length': 4.345917471466199, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6365152', 'n_tokens_mistral': 2310, 'n_tokens_neox': 2114, 'n_words': 455}