【问题标题】:Adding and subtracting dates without Standard Library在没有标准库的情况下添加和减去日期
【发布时间】:2009-10-20 16:02:46
【问题描述】:

我在有限的环境中开发 python 脚本。

我的问题是我必须能够完成日期时间的加法和减法。

例如我得到以下字符串:

"09/10/20,09:59:47-16"

格式为年/月/日,时:分:秒-毫秒。

如何在 Python 中为这个数字加上 30 秒?除了基本的加减法和字符串解析函数,我什么都不能用。

【问题讨论】:

  • 最好是作业。什么样的经理会说“不要使用标准库”?
  • 我希望.. 我在 Telit 蜂窝模块上使用 python 解释器。它只是不支持 datetime 模块。
  • ...也许应该删除作业标签?
  • 我当然没有添加它!无论如何,我为我的问题创建了一个解决方案。见下文。
  • 既然是手机用的,还需要担心100年和400年的闰年规则吗?

标签: python datetime


【解决方案1】:

你在不同的基础上做数学。您需要解析字符串并得出一个值列表,例如(年、月、日、小时、分钟、秒),然后进行其他基础数学运算以进行加减运算。例如,小时数以 24 为底,因此您需要使用模数来执行计算。这听起来有点像家庭作业,所以我不会详细说明:)

【讨论】:

  • 这是我正在采取的方法。这实际上不是家庭作业(尽管在大学里我也有过类似的令人讨厌的作业)。它只是一个非常欠发达的 Python 平台。当您开始查看月份以及它们的天数如何不同时,基本数学会变得很烦人,天堂禁止您考虑闰年。
【解决方案2】:

为了完整起见,datetime.datetime.strptime 和 datetime.timedelta 包含在默认的 Python 发行版中。

from datetime import datetime, timedelta

got = "09/10/20,09:59:47-16"

dt = datetime.strptime(got, '%y/%m/%d,%H:%M:%S-%f')
dt = dt + timedelta(seconds=30)
print dt.strftime('%y/%m/%d,%H:%M:%S-%f')

精确打印

09/10/20,10:00:17-160000

文档here.

【讨论】:

  • @Ravi:问题已被编辑 - 我保留我的答案以供参考和完整性 - 这是任何没有人为限制的人都会使用的理智方式。
【解决方案3】:

执行日期算术的最简单方法是不实际对日期执行该算术,而是对更简单的数量执行该算术。

通常,更简单的数量是自某个时期以来的秒数。 1970 年 1 月 1 日效果很好。知道纪元、每个月的天数以及哪些年份是闰年,您可以很容易地从这个“秒数”表示转换为日期字符串(如果在幼稚版本中不是很慢的话)。

您还需要将日期字符串转换回更简单的表示形式。这又是,不太难。

一旦有了这两个函数,算术就很简单了。只需在“秒数”表示中添加或减去时间量即可。然后转换回日期字符串。

话虽如此,我希望这是一个家庭作业,因为您绝对不应该在生产代码中编写自己的日期处理函数。

【讨论】:

  • 我同意。 DateTime 只是一个令人讨厌的混乱。但是我正在开发一个缺乏这些功能的平台。
  • 但是 DateTime 包含的知识超出了你我的范围。它是一团糟(在您看来)不足以成为不使用它的充分理由。
  • 没有它是不使用它的充分理由
  • 对不起,我不清楚。物理日期和时间是令人讨厌的混乱。 DateTime 库利用你和我之外的知识来理解混乱。
【解决方案4】:

这是我对问题的解决方案:

year = int(s[0:2])
month = int(s[3:5])
day = int(s[6:8])
hour = int(s[9:11])
minute = int(s[12:14])
second = int(s[15:17])

amount_to_add = 30
second = second + amount_to_add
days_in_month = 30
if(month == 1 or month == 3 or month == 5 or month ==7 or month ==  8 or month == 10 or         month == 12):
    days_in_month = 31
if(month == 2):
    days_in_month = 28
if ((((year%4 == 0) and (year%100 != 0)) or (year%400 == 0)) and month == 2):
    days_in_month = 29

if(second > 60):
    minute = minute + second/60
    second = second%60
if(minute > 60):
    hour = hour + minute/60
    minute = minute%60
if(hour >24):
    day = day + hour/60
    hour = hour%24
if(day > days_in_month):
    month = month + day/days_in_month
    day = day%days_in_month
if(month > 12):
    year = year + month/12
    month = month%12

有点杂乱无章,但它可以完成工作。

【讨论】:

  • 我认为您需要将比较逻辑更改为>= 60> 59,因为一旦达到 60,这实际上意味着下一分钟的第 0 秒(重复分钟、小时和月)。如果second == 30,您当前的逻辑将无法正确级联。
  • @Erich “重复分钟、小时和月份”:秒和分钟不应该 == 60,小时不应该 == 24,但月份可以 == days_in_month
  • 如何使用month in (1,3,5,7,8,31):
  • 可以是60!,问Oracle suitablyflip.com/suitably_flip/2009/01/…
  • @foosion:你是伪正确的。 month 可以等于12,但不能等于您写的days_in_month(我从未提到days,因为该逻辑是正确的)。秒、分钟和小时都是从 0 开始的;日和月是从 1 开始的;因此有区别。
猜你喜欢
  • 1970-01-01
  • 2017-04-13
  • 2022-10-02
  • 2016-04-15
  • 1970-01-01
  • 2022-01-23
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多