implementing a calendar class

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • python101
    New Member
    • Sep 2007
    • 90

    implementing a calendar class

    I would like to write a class CalculationDate which can deal with a date in numerical formation and text format and I have a nextDate method that returns the next day of the year. This class is written with a unit test which can test the proper treatment of leap year.

    My question is how can I able to write a code to deal with the numerical formation and text format? I usually write a numerical one then write a function to convert it to text. If possible, can some one give an example code?
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Originally posted by python101
    I would like to write a class CalculationDate which can deal with a date in numerical formation and text format and I have a nextDate method that returns the next day of the year. This class is written with a unit test which can test the proper treatment of leap year.

    My question is how can I able to write a code to deal with the numerical formation and text format? I usually write a numerical one then write a function to convert it to text. If possible, can some one give an example code?
    isinstance() is the prefered way to handle parameters which may have different types:[CODE=python]
    >>> import time
    >>> timeStr = time.asctime()
    >>> timeStr
    'Tue Nov 13 09:57:26 2007'
    >>> timeTup = time.localtime( )
    >>> timeTup
    (2007, 11, 13, 10, 1, 43, 1, 317, 0)
    >>> class SmartTime(objec t):
    ... def DateAndTime(sel f, timeStrOrTup):
    ... if isinstance(time StrOrTup, str):
    ... return timeStrOrTup
    ... if isinstance(time StrOrTup, time.struct_tim e):
    ... return time.strftime(" %a %b %d %H:%M:%S %Y", timeStrOrTup)
    ...
    >>> st = SmartTime()
    >>> st.DateAndTime( timeStr)
    'Tue Nov 13 09:57:26 2007'
    >>> st.DateAndTime( timeTup)
    'Tue Nov 13 10:01:43 2007'
    >>> [/CODE]
    Last edited by bartonc; Nov 13 '07, 06:15 PM.

    Comment

    • bartonc
      Recognized Expert Expert
      • Sep 2006
      • 6478

      #3
      Originally posted by bartonc
      isinstance() is the prefered way to handle parameters which may have different types:[CODE=python]
      >>> import time
      >>> timeStr = time.asctime()
      >>> timeStr
      'Tue Nov 13 09:57:26 2007'
      >>> timeTup = time.localtime( )
      >>> timeTup
      (2007, 11, 13, 10, 1, 43, 1, 317, 0)
      >>> class SmartTime(objec t):
      ... def DateAndTime(sel f, timeStrOrTup):
      ... if isinstance(time StrOrTup, str):
      ... return timeStrOrTup
      ... if isinstance(time StrOrTup, time.struct_tim e):
      ... return time.strftime(" %a %b %d %H:%M:%S %Y", timeStrOrTup)
      ...
      >>> st = SmartTime()
      >>> st.DateAndTime( timeStr)
      'Tue Nov 13 09:57:26 2007'
      >>> st.DateAndTime( timeTup)
      'Tue Nov 13 10:01:43 2007'
      >>> [/CODE]
      And using the "varargs" syntax (p 338 of Learning Python by Mark Lutz), it might look like this:[CODE=python]
      >>> class SmartTime(objec t):
      ... def DateAndTime(sel f, *args):
      ... if isinstance(args[0], str):
      ... return args[0]
      ... if isinstance(args[0], time.struct_tim e):
      ... return time.strftime(" %a %b %d %H:%M:%S %Y", args[0])
      ... return time.strftime(" %a %b %d %H:%M:%S %Y", args)
      ...
      >>> st = SmartTime()
      >>> st.DateAndTime( 2007, 11, 13, 10, 1, 43, 1, 317, 0)
      'Tue Nov 13 10:01:43 2007'
      >>> st.DateAndTime( timeStr)
      'Tue Nov 13 09:57:26 2007'
      >>> st.DateAndTime( timeTup)
      'Tue Nov 13 10:01:43 2007'
      >>> [/CODE]

      Comment

      • python101
        New Member
        • Sep 2007
        • 90

        #4
        I only need the date like 11-11-2007, not the time. And this date is set by user, not accorded to the system time because if using the system time, it automatically recognizes the leap year, and there is no nextDate method is used

        Comment

        • python101
          New Member
          • Sep 2007
          • 90

          #5
          The way I explained the problem might no be clear.

          - The date (including month, day, and year for example Tues August 27, 2007) should be inputed by user.

          - The class should have some methods to figure out what is the text input what is the numeric input, and be be to do the nextDate() which returns the next day of the year, this has to deal with the leap year.
          Question: how can I write this?

          Comment

          • dazzler
            New Member
            • Nov 2007
            • 75

            #6
            if you want to know next day:

            import datetime

            now = datetime.date(2 003, 8, 6)
            difference1 = datetime.timede lta(days=1)
            difference2 = datetime.timede lta(weeks=-2)

            print "One day in the future is:", now + difference1

            print "Two weeks in the past is:", now + difference2

            hope that helps a little, here's some more reading: http://pleac.sourcefor ge.net/pleac_python/datesandtimes.h tml

            Comment

            • dazzler
              New Member
              • Nov 2007
              • 75

              #7
              Originally posted by python101
              The way I explained the problem might no be clear.

              - The date (including month, day, and year for example Tues August 27, 2007) should be inputed by user.

              - The class should have some methods to figure out what is the text input what is the numeric input, and be be to do the nextDate() which returns the next day of the year, this has to deal with the leap year.
              Question: how can I write this?
              you are giving user an option to write month names in "text input"? usually if months are not in numerical format in application the user can choose the month from a list of months, not to write month name himself, or did I misunderstood this =)

              Comment

              • dazzler
                New Member
                • Nov 2007
                • 75

                #8
                I'm just a noob, so sry if the code is not so nice looking
                but what you think about this? =)

                [code=python]
                import datetime

                while 1: #loop while user has typed a proper date value

                the_date = raw_input("Plea se give a date in DD.MM.YYYY format\n")
                date_table = the_date.split( '.') #splits "the_date" using . marks
                #date_table[0] = DD , date_table[1] = MM, etc...

                try: #checking if error happens when using datetime.date()
                now = datetime.date(i nt(date_table[2]), int(date_table[1]), int(date_table[0])) #int() converts string to int
                break #date value does exist, break from the while loop

                except: #if there's error here it means that the date doesn't exist
                print "You have type date in wrong format!, give day in (DD.MM.YYYY)\n"


                next_day = datetime.timede lta(days=1)

                print "next day is", now + next_day
                [/code]

                ok, the printed next day is in totally different date format... (I'm lazy) but I think that it's easy to fix... :-D

                Comment

                • python101
                  New Member
                  • Sep 2007
                  • 90

                  #9
                  Thank you very much for helping me out.

                  Can I do this thing in the class?
                  [code=python]
                  #assume I've already had CalculationDate class, when I run this class
                  >> CalculationDate (14,32,2004)
                  invalid date, please enter a gain 12/29/2004
                  [/code]

                  Comment

                  • KaezarRex
                    New Member
                    • Sep 2007
                    • 52

                    #10
                    To format the output, try something like this:
                    [CODE=python]>>> import datetime
                    >>> months = ["January", "February", "March", "April", "May", "June", "July", "August", "September" , "October", "November", "December"]
                    >>> dateA = datetime.date(2 007, 5, 4)
                    >>> print "%s %d, %d" % (months[dateA.month-1], dateA.day, dateA.year)
                    May 4, 2007[/CODE]
                    Last edited by KaezarRex; Nov 14 '07, 04:46 PM. Reason: fixed code

                    Comment

                    • KaezarRex
                      New Member
                      • Sep 2007
                      • 52

                      #11
                      Or this:
                      [CODE=python]>>> dateA = datetime.date(2 007, 5, 4)
                      >>> output = dateA.ctime().r eplace(" ", " ").split(" ")
                      >>> print "%s %s, %s" % (output[1], output[2], output[4])
                      May 4, 2007[/CODE]

                      Comment

                      • KaezarRex
                        New Member
                        • Sep 2007
                        • 52

                        #12
                        Or even better:
                        [CODE=python]>>> dateA.strftime( "%B %d, %Y")
                        'May 14, 2007'[/CODE]

                        Comment

                        • bvdet
                          Recognized Expert Specialist
                          • Oct 2006
                          • 2851

                          #13
                          Following is a class that does not use Python's datetime module:[code=Python]import re
                          patt = "[/.]"

                          class Dates(object):

                          monthDict = dict(zip(range( 1,13),['January', 'February', 'March', 'April', \
                          'May', 'June', 'July', 'August', 'September', \
                          'October', 'November', 'December']))
                          daysList1 = [31,28,31,30,31, 30,31,31,30,31, 30,31]
                          daysList2 = [31,29,31,30,31, 30,31,31,30,31, 30,31]

                          def __init__(self, dateStr):
                          # dateStr is in the format month/day/year (xx/xx/xxxx) or month.day.year
                          self.dateStr = dateStr
                          try:
                          self.month, self.day, self.year = [int(s) for s in re.split(patt, dateStr)]
                          except:
                          raise ValueError, "Invalid date format"
                          self.month_str = self.monthStr()
                          self.day_num = self.dayNo()

                          def isLeap(self, yr):
                          if not yr % 4:
                          return 1
                          return 0

                          def daysList(self, year):
                          return [self.daysList1, self.daysList2][self.isLeap(yea r)]

                          def monthStr(self):
                          # return the text representation of the month number
                          try:
                          return self.monthDict[self.month]
                          except KeyError:
                          raise ValueError, "Invalid month number"

                          def dayNo(self):
                          # return the day number in the year
                          if self.day < 1 or self.day > self.daysList(s elf.year)[self.month-1]:
                          raise ValueError, "Invalid day number"
                          return sum(self.daysLi st(self.year)[:self.month-1]) + self.day

                          def monthDayYr(self , day_num):
                          # return a tuple of month, day, year given a day number
                          # day number is with respect to the year of the instance
                          idx = 0
                          year = self.year
                          while day_num < 1:
                          day_num += sum(self.daysLi st(year))
                          year -= 1
                          while True:
                          if day_num <= self.daysList(y ear)[idx]:
                          return idx+1, day_num, year
                          day_num -= self.daysList(y ear)[idx]
                          idx += 1
                          if idx == 12:
                          idx = 0
                          year += 1

                          def nextDay(self):
                          return self+1

                          def preDay(self):
                          return self-1

                          def __add__(self, days):
                          return Dates('/'.join([str(item) for item in self.monthDayYr (self.dayNo() + days)]))

                          def __sub__(self, days):
                          return Dates('/'.join([str(item) for item in self.monthDayYr (self.dayNo() - days)]))

                          def __str__(self):
                          return "%s %d, %d" % (self.month_str , self.day, self.year)[/code]

                          Comment

                          • bartonc
                            Recognized Expert Expert
                            • Sep 2006
                            • 6478

                            #14
                            You guys do realize, don't you? All this and more is taken care of in the Calendar module.

                            Comment

                            • bvdet
                              Recognized Expert Specialist
                              • Oct 2006
                              • 2851

                              #15
                              Originally posted by bartonc
                              You guys do realize, don't you? All this and more is taken care of in the Calendar module.
                              Yes. Writing something myself is a lot more fun though.

                              Comment

                              Working...