Difference Between Two Times (python)

2019-01-20 06:37发布

问题:

Just want to know if i can set the variable a sign off time to midnight.

i want sign off to be a raw_input and midnight to be fixed value

so far i have this:

#!/usr/bin/python
from datetime import datetime
from Tkinter import *
import math
#Variablesr
FMT = '%H%M' #Time Format
rate1 = 35.34 #Base Hourly Rate
rate2 = 35.34 #Base Hourly Rate
rate3 = 35.34 #Base Hourly Rate
rate4 = 35.34 #Base Hourly Rate
rate5 = 35.34 #Base Hourly Rate
rate6 = 50 #Base Hourly Rate
rate7 = 70 #Base Hourly Rate

Midnight = 0000,FMT
amp = 2.40 #Morning shift penalties
pmp = 2.50 #Afternoon shift penalties
ns = 4.4 #Night shift penalties
cabAll = 8.34 #Cab Allowance

signOnSun1 = raw_input("What time did you sign on Sunday: ");
signOffSun1 = raw_input("What time did you sign off Sunday: ");

diff = (datetime.strptime(signOffSun1, FMT) - datetime.strptime (Midnight, FMT))
print diff

回答1:

You don't see to use signOnSun1 so not exactly sure what you want but this should be closer to what you want :

from datetime import datetime
#Variablesr
FMT = '%H:%M' #Time Format use HH:MM
rate1 = 35.34 #Base Hourly Rate
rate2 = 35.34 #Base Hourly Rate
rate3 = 35.34 #Base Hourly Rate
rate4 = 35.34 #Base Hourly Rate
rate5 = 35.34 #Base Hourly Rate
rate6 = 50 #Base Hourly Rate
rate7 = 70 #Base Hourly Rate

Midnight = "00:00" # make midnight a string

amp = 2.40 #Morning shift penalties
pmp = 2.50 #Afternoon shift penalties
ns = 4.4 #Night shift penalties
cabAll = 8.34 #Cab Allowance
# make sure user know format to use
signOnSun1 = raw_input("What time did you sign on Sunday, enter in format HH:MM: ")
signOffSun1 = raw_input("What time did you sign off Sunday, enter in format HH:MM: ")
# use Midnight string and FMT
diff = (datetime.strptime(signOffSun1, FMT) - datetime.strptime(Midnight,FMT))
print diff

Really you should make sure the user enters correct data using a try/except block and you will get caught if you comparing times before and after midnight

If all times are up to midnight you can hardcode the dates setting midnight to one day after:

FMT = '%H:%M-%Y-%m-%d' #Time Format
rate1 = 35.34 #Base Hourly Rate
rate2 = 35.34 #Base Hourly Rate
rate3 = 35.34 #Base Hourly Rate
rate4 = 35.34 #Base Hourly Rate
rate5 = 35.34 #Base Hourly Rate
rate6 = 50 #Base Hourly Rate
rate7 = 70 #Base Hourly Rate

Midnight = "00:00-1900-01-02"

amp = 2.40 #Morning shift penalties
pmp = 2.50 #Afternoon shift penalties
ns = 4.4 #Night shift penalties
cabAll = 8.34 #Cab Allowance

signOnSun1 = raw_input("What time did you sign on Sunday, enter in format HH:MM: ")
signOffSun1 = raw_input("What time did you sign off Sunday, enter in format HH:MM: ")
diff = datetime.strptime(Midnight, FMT) - datetime.strptime("{}-1900-01-01".format(signOnSun1), FMT)
print diff


回答2:

If you are dealing with number of hours people work then you should take DST transitions (and the changes in UTC offset for other reasons) into account otherwise the result can be wrong (by an hour usually).

It is not trivial to find midnight correctly. See How do I get the UTC time of “midnight” for a given timezone?

To get correct results, you should specify a date in addition to the time e.g., assume the last Sunday. And you need to know the local timezone and (for portability) you need a historical timezone database such as provided by pytz module. tzlocal module can find your local timezone:

from datetime import datetime, timedelta
from tzlocal import get_localzone # $ pip install tzlocal
from pytz import AmbiguousTimeError

DAY = timedelta(1)
local_timezone = get_localzone() # get pytz timezone
time_format = "%H:%M"

def asktime(prompt, format):
    while True:
        try:
            return datetime.strptime(raw_input(prompt), format)
        except ValueError:
            print('Invalid time format, expected %s. Try again.' % format)

def disambiguate(time, date):
    d = datetime.combine(date, time).replace(tzinfo=None)
    try:
        return local_timezone.localize(d, is_dst=None)
    except AmbiguousTimeError:
        is_dst = yes_or_no('Was it summer time (%s)?' % d)
        return local_timezone.localize(d, is_dst=is_dst)
    # allow NonExistentTimeError to propagate

# find last Sunday
sunday = datetime.now(local_timezone)
while sunday.weekday() != 6: # Sunday is 6
    sunday -= DAY

# get 'sign on', 'sign off' times
#NOTE: assume, no 24h+ shifts
signon = asktime("What time did you sign on Sunday: ", time_format)
signoff = asktime("What time did you sign off Sunday: ", time_format)
if signoff < signon: # signon is a day before (Saturday)
   signon = disambiguate(signon, sunday.date() - DAY)
signoff = disambiguate(signoff, sunday)
print("Signon time %s" % signon)
print("Signoff time %s" % signoff)
diff = signoff - signon
print("The difference %s" % diff)

If 'sign on', 'sign off' times are during DST transition ("fall back") then the same local time may occur twice. Then (in addition to a date) you need to know whether it was a summer time during ('sign on', 'sign off'), to make the time unambiguous.

Where yes_or_no() is a small utility function:

def yes_or_no(prompt):
    while True:
        answer = raw_input(prompt)
        if answer.lower() in {'yes', 'no'}:
            return answer == 'yes'
        print("Please, answer 'yes' or 'no'. Try again.")

Everything is much simpler if you don't need to deal with the local timezone and you can ask for UTC time:

signon = asktime("What UTC time did you sign on Sunday: ", time_format)
signoff = asktime("What UTC time did you sign off Sunday: ", time_format)
# support 24h+ shifts
while signoff < signon: # signon is on a previous date
   signon -= DAY
diff = signoff - signon
print(diff)

And that is why it is recommended to work with UTC time instead of the local time if possible (if you can ask people to provide time in UTC).


If you can't install tzlocal module and can't use UTC time then you could use time.mktime() to disambiguate the local time (it may be less reliable than the above method that uses the tz database), see my answer to "Find if 24 hrs have passed between datetimes - Python".