Date-Time Calculations and Manipulations

There are two classes of date-time calculations.

  • Duration or interval calculations in days (or seconds), where the month, week and year boundaries don't matter. For example, the number of hours, days or weeks between two dates doesn't depend on months or year boundaries. Similarly, calculating a date 90 days in the future or past doesn't depen on month or year considerations. Even the difference between two times is properly a date-time calculation so that we can allow for rollover past midnight.

    We have two ways to do this.

    • We can use float seconds information, as produced by the time module. When we're using this representation, a day is 24*60*60 (86,400) seconds, and a week is 168*24*60*60 seconds. For the following examples, t1 and t2 and float seconds times.

      (t2-t1)/3600 is the number of hours between two times.

      (t2-t1)/86400 is the days between two dates.

      t1+90*86400 is the date 90 days in the future.

    • We can also use datetime objects for this, since datetime objects correctly handle arithmetic operations. When we're using this representation, we'll also work with datetime.timedelta objects; these have days, seconds and microseconds attributes. For the following examples, t1 and t2 and datetime objects.

      In a relatively simple case, the hours between two datetimes is (t2-t1).seconds/3600. This works when we're sure that there sill be less than 24 hours between the two datetimes.

      In the more general case, we have a two-part calculation: td= (t2-t1); td.days*86400+td.seconds is the seconds between two time periods, assuming that there may be more than a whole day between them.

      (t2-t1).days will create the timedelta between two datetimes; it extracts the days attribute of that timedelta object.

  • Calendar calculations where the month, week of month and day of week matter. For example, the number of months between two dates rarely involves the day of the month. A date that is 3 months in the future, will land on the same day of the month, except in unusual cases where it would be the 30th of February. For these situations, highly problem-specific rules have to be applied; there's no general principle.

    We have two ways to do this.

    • We can use struct_time objects as produced by the time module. We can replace any struct_time fields, and possibly create an invalid date. We may need to use time.mktime to validate the resulting struct_time object. In the following examples, t1 is a struct_time object.

      Adding some offset in months, correctly allowing for year-end rollover, is done as follows.

      monthSequence= (t1.tm_year*12 + t1.tm_mon-1) + offset
      futureYear, futureMonth0 = divmod( monthSequence, 12 )
      t1.tm_year= futureYear
      t1.tm_month= futureMonth0 + 1
    • We can also use datetime objects for this. In this case, we we'll use the replace method to replace a value in a datetime with other values. In the following examples, t1 is a datetime object.

      Adding some offset in months, correctly allowing for year-end rollover, is done as follows.

      monthSequence= (t1.year*12 + t1.month-1) + offset
      futureYear, futureMonth0 = divmod( monthSequence, 12 )
      t1= t1.replace( year=futureYear, month=futureMonth0+1 )

The following methods return information about a given datetime object. In the following definitions, dt is a datetime object.

dt. datedate

Return a new date object from the date fields of this datetime object.

dt. timetime

Return a new time object from the time fields of this datetime object.

dt. replace ( year= , month= , day= , hour= , minute= , second= , microsecond= ) → datetime

Return a new datetime object from the current datetime object after replacing any values provided by the keyword arguments.

dt. toordinal → int

Return the ordinal day number for this datetime.

dt. weekday → int

Return the day of the week. Monday = 0, Sunday = 6.

dt. isoweekday → int

Return the day of the week. Monday = 1, Sunday = 7.

dt. isocalendar → tuple

Return a tuple with ( ISO year, ISO week, ISO week day ).