[Tutor] time question

Kevin McCormick kev@sat.net
Fri, 24 Aug 2001 12:56:22 -0500


Rob Andrews wrote:
> 
> Okay, I'll admit my ignorance. (It's pretty well documented by now.
> heehee)
> 
> I'm working on an application to track the progress of someone who has
> quit smoking (or to provide info for someone thinking of quitting), and
> the whole application is based around the passage of time for its
> calculations.
> 
> If anyone wishes to risk going blind by actually reading this
> alpha-release-wannabe source file, it's located here:
> 
> http://www.lowerstandard.com/python/pyQuit.py
> 
> But fortunately I have a nice, specific question. After user input, I
> have the quit time stored thusly:
> 
> >>> import time
> >>> quitTime
> (2001, 8, 22, 9, 45, -1, -1, -1, -1)
> 
> I then convert this to a float, and determine the difference between the
> current time and the quitting time:
> 
> >>> quitTime1 = time.mktime(quitTime)
> >>> currentTime = time.time()
> >>> quitTime1
> 998491499.0
> >>> currentTime
> 998578178.33000004
> >>> timeDifference = currentTime - quitTime1
> >>> timeDifference
> 86679.330000042915
> 
> At this point, I face the slightly tedious task of converting this time
> difference (expressed in seconds) into something more tangible. I'd like
> to report "You have been nicotine free for 6 weeks, 5 hours, and 4
> minutes." (for example). So far, this means a several-step process of
> dividing the seconds down into years, then the remainder down to (lunar)
> months, then to weeks, days, and minutes.
> 
> Does anyone know a way to do this more directly, elegantly, or briefly?
> 
> Rob
> --
> A mind is a terrible thing. And it must be stopped. Before it kills
> someone.
> Useless Python!
> http://www.lowerstandard.com/python
> 
> _______________________________________________
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor


It seems to me that you need some way to identify the start time as a
number and the end time as a larger number.  I have copied my
"dateSerial" functions for your review.  If you assign the "dateSerial"
as the start date, plus the seconds from midnight, and also "dateSerial"
the end date, minus the seconds until midnight (or the day before plus
seconds), you could perform your calculation.  Python has modules that
do similar things, but I'm just a long-time newbie.

import string
import math
from types import *

#=============

dytmoD = {'M1':0, 'M2':31, 'M3':59, 'M4':90, 'M5':120, 'M6':151,
'M7':181,
          'M8':212, 'M9':243, 'M10':273, 'M11':304, 'M12':334 }

dayNames = ((2, 'Mon', 'Monday'), (3, 'Tue', 'Tuesday'), (4, 'Wed',
'Wednesday'), (5, 'Thur', 'Thursday'),
            (6, 'Fri', 'Friday'),(7, 'Sat', 'Saturday'), (1, 'Sun',
'Sunday'),(2, 'Mon', 'Monday'))

moNames = {'M1':(1, 'J', 'Jan', 'January', 31, 0), 'M2':(2, 'F', 'Feb',
'February', 28, 31),
           'M3':(3, 'M', 'Mar', 'March', 31, 59), 'M4':(4, 'A', 'Apr',
'April', 30, 90),
           'M5':(5, 'M', 'May', 'May', 31, 120), 'M6':(6, 'J', 'Jun',
'June', 30, 151),
           'M7':(7, 'J', 'Jul', 'July', 31, 181), 'M8':(8, 'A', 'Aug',
'August', 31, 212),
           'M9':(9, 'S', 'Sep', 'September', 30, 243), 'M10':(10, 'O',
'Oct', 'October', 31, 273),
           'M11':(11, 'N', 'Nov', 'November', 30, 304), 'M12':(12, 'D',
'Dec', 'December', 31, 334)}


#============       
def MakeDate(YYYYMMDD, listItems=0):
    """
    takes a date string in the YYYYMMDD format and parses out the year,
month, and day
    calls dateSerial(yr, mo, dy) to get the serial number date
    calls DayOfWeek(serial) to get the day of the week
    return value:
      if listItems = 0 -> only serial is returned as a single item
      if listItems > 0,...4 -> returns a tuple of (serial, tickDate,
wkDay, strDate, tplDate)
    """
    yr = int(YYYYMMDD[:2])
    if yr < 35:
        yr = yr + 2000
    else:
        yr = yr + 1900
        
    mo = int(YYYYMMDD[2:4])
    dy = int(YYYYMMDD[4:])

    
    tplDate = (yr, mo, dy)
    strDate = '%d/%d/%d' % (mo, dy, yr)
    tickDate = moNames['M%d' % mo][1] + '%d' % dy
    serial = dateSerial(yr, mo, dy)
    wkDay = DayOfWeek(serial)

    lVal = (serial, tickDate, wkDay, strDate, tplDate)

    if listItems > 4:
        return lVal
    else:
        return lval[listItems - 1]       

#============
def isLeapYear(yr):
    return (0 == (yr % 4))

#============
def dateSerial(yr, mo, dy):
    moId = 'M%d' % mo
    baseYear = 1900
    # assume base year of 1900 so that 1-1-1900 is day 1
    sy = (yr - baseYear) * 365  # 365 days to a year
    # Leap Year occurs every four years, except for years ending in 00,
    # in which case only if the year is divisible by 400.
    # for any year add: - (yr/100 - baseYear/100) + (yr/400 -
baseYear/400)
    # but since this is for centuries 1900 to 2000, it is superfluous
    sly = (yr - baseYear) / 4
    #
    sm = dytmoD[moId]
    if isLeapYear(yr) and mo < 3:
        sm = sm - 1 

    return sy + sly + sm + dy + 1

#============
def DayOfWeek(dSerial, Onum1abrev2word=0):
    """
    Argument is a serial number date.
    Onum1abrev2word -> 0=integer, 1=abbreviation, 2=word
    which is taken from the dayNames=((1, 'Sun', 'Sunday'),(2, 'Mon',
'Monday'),...) tuple
    Returns the day of the week where Sunday=1, Monday=2, ..., Saturday
= 7
    
    """
    try:
        rt = int(Onum1abrev2word)
    except ValueError:
        'Onum1abrev2word: %d must be 0, 1, or 2' % Onum1abrev2word
    try:
        dNum = int(dSerial)
    except ValueError:
        'dSerial: %s must be an integer as from dateSerial()' % dSerial

    # assuming that 1/1/1900 was a Monday --verified with '$ cal 1, 1900
    if dSerial < 7:
        dw = dNum - 1
    else:
        dw = (dNum % 7) - 2   # in order to correctly access dayNames[]
tuple
    #print dSerial, dw, dayNames[dw]
    return dayNames[dw][rt]