import math

class PartialDate:
  """partial date class for handling inaccurate dates"""
  def __init__(self):
    self.__init__(self,None)

  def __init__(self, date):
    from datetime import datetime
    if not date:
      date = datetime.now()
    elif isinstance(date, basestring) and date.find(":"):
      date = datetime.strptime(date.split(".")[0], "%Y-%m-%d %H:%M:%S")

    if isinstance(date, basestring):
      dateparts = date.split("-")
      self.year = int(dateparts[0])
      if len(dateparts) > 1:
        self.month = int(dateparts[1])
      else:
        self.month = 0
      if len(dateparts) > 2:
        self.day = int(dateparts[2])
      else:
        self.day = 0
      self.fraction = 0.0
    elif isinstance(date, datetime):
      self.year = date.year;
      self.month = date.month;
      self.day = date.day;
      self.fraction = date.hour/100.0 + date.minute/10000.0 + date.second/1000000.0
    elif isinstance(date, PartialDate):
      self.year = date.year
      self.month = date.month
      self.day = date.day
      self.fraction = date.fraction
    else:
      self.year = int(math.floor(date/10000.0))
      self.month = int(math.floor((date - self.year*10000)/100.0))
      self.day = int(math.floor(date - self.year*10000 - self.month*100))
      self.fraction = date - math.floor(date)

  def __lt__(self, other):
    if not isinstance(other, PartialDate):
      other = PartialDate(other)
    if self.year < other.year:
      return True
    if self.year > other.year:
      return False
    if not (self.month > 0 and other.month > 0):
      return False
    if self.month < other.month:
      return True
    if self.month > other.month:
      return False
    if not (self.day > 0 and other.day > 0):
      return False
    if self.day < other.day:
      return True
    if self.day > other.day:
      return False
    if not (self.fraction > 0 and other.fraction > 0):
      return True
    if self.fraction < other.fraction:
      return True
    return False

  def __le__(self, other):
    return self.__lt__(other) or self.__eq__(other)
    
  def __eq__(self, other):
    if not isinstance(other, PartialDate):
      other = PartialDate(other)
    if self.year != other.year:
      return False
    if not (self.month > 0 and other.month > 0):
      return True
    if self.month != other.month:
      return False
    if not (self.day > 0 and other.day > 0):
      return True
    if self.day != other.day:
      return False
    return True

  def __ne__(self, other):
    return not self.__eq__(other)

  def __gt__(self, other):
    if not isinstance(other, PartialDate):
      other = PartialDate(other)
    return other.__lt__(self)

  def __ge__(self, other):
    if not isinstance(other, PartialDate):
      other = PartialDate(other)
    return other.__le__(self)

  def __int__(self):
    return self.year*10000+self.month*100+self.day

  def __float__(self):
    return self.year*10000+self.month*100+self.day+self.fraction

  def __str__(self):
    out = str(self.year)
    if self.month > 0:
      out += "-%02d" % self.month
    if self.day > 0:
      out += "-%02d" % self.day
    return out
