【问题标题】:Difference Between Two Times (python)两次之间的差异(python)
【发布时间】:2015-02-22 23:08:53
【问题描述】:

只是想知道我是否可以将变量的签出时间设置为午夜。

我希望签核为 raw_input,午夜为固定值

到目前为止我有这个:

#!/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

【问题讨论】:

  • 呃,这其中哪一部分不起作用?
  • Midnight 是一个元组,但应该是一个字符串
  • 所以当我周六在 1900 签到时。然后在那天晚上签到 0202。我收到此错误:diff = (datetime.strptime(signOffSun1, FMT) - datetime.strptime (Midnight, FMT)) TypeError: must be string, not tuple
  • 当我把它变成这样的字符串时:Midnight = str(0000) 它告诉我它的 %H%M 格式不正确
  • @DerenDevrimol -- tupleMidnight = 0000,FMT -- 逗号使它成为一个 2 项元组,所以只需去掉 ,FMT 部分并使用 '0000' (引号至关重要)必须是字符串)。然而,真正的问题会来,因为你问了一个非常误导性的问题:`“你是什么时候签的星期天:”!如果您现在说您“在 1900 年签署星期六”,那么这个棘手的问题没有正确答案——您从未按照要求在星期日签署!如果班次可以包括午夜,您需要允许输入日期,而不仅仅是时间。

标签: python datetime time difference


【解决方案1】:

你看不到使用signOnSun1,所以不确定你想要什么,但这应该更接近你想要的:

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

真的,你应该确保用户使用 try/except 块输入正确的数据,如果你比较午夜前后的时间,你会被抓到

如果所有时间都到午夜,您可以将日期设置为午夜后的一天:

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

【讨论】:

  • 绝对的天才。我所缺少的只是“0000”......现在我觉得很愚蠢
  • 不用担心,就像我说的那样,使用 try/except 和 while 循环来获取输入是个好主意。
【解决方案2】:

如果您要处理人们工作的小时数,那么您应该考虑 DST 转换(以及由于其他原因导致的 UTC 偏移量的变化),否则结果可能是错误的(通常是一个小时)。

正确找到午夜并非易事。见How do I get the UTC time of “midnight” for a given timezone?

要获得正确的结果,除了时间之外,您还应该指定一个日期,例如,假设是最后一个星期日。并且您需要知道本地时区,并且(为了可移植性)您需要一个历史时区数据库,例如 pytz 模块提供的。 tzlocal 模块可以找到你当地的时区:

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)

如果“登录”、“注销”时间是在 DST 转换期间(“回退”),则相同的本地时间可能会出现两次。然后(除了日期之外)您需要知道在('sign on','sign off')期间是否是夏季时间,以使时间明确。

yes_or_no() 是一个小实用函数:

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.")

如果你不需要处理当地时区,一切都会简单得多,你可以要求 UTC 时间:

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)

这就是为什么建议尽可能使用 UTC 时间而不是本地时间(如果您可以要求人们提供 UTC 时间)。


如果您无法安装tzlocal 模块并且无法使用UTC 时间,那么您可以使用time.mktime() 来消除本地时间的歧义(它可能不如上述使用tz 数据库的方法可靠),请参阅my answer to "Find if 24 hrs have passed between datetimes - Python".

【讨论】:

    猜你喜欢
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 2022-11-07
    • 2013-09-25
    • 2011-06-01
    • 2016-04-01
    相关资源
    最近更新 更多