昨天午夜的纪元时间是多少?

29

我正在尝试理解datetime模块。我知道现在的时间是一个纪元时间,以及事件上次发生的时间(也是一个纪元时间)。我需要做的是弄清楚这个事件是否发生在昨天的午夜到午夜之间。

t = time.time() # is now
t2 = 1234567890 # some arbitrary time from my log

24小时前是t - 86400,但我该如何将其四舍五入到午夜。我很难找到一种方法来获取时间戳并将其转换为日期时间,然后再操作日期时间以设置时间。


1
听起来你可能需要在某个地方将它转换为常规时间,因为像天/午夜等分隔符不是时代时间的一部分。 - Gray
7个回答

67

深夜时分

生成最后一次的午夜很容易:

from datetime import datetime, time

midnight = datetime.combine(datetime.today(), time.min)

这个将今天的日期(可以使用date()datetime()实例,你自己选择)与time.min结合起来,形成一个午夜的datetime对象。

昨天

通过使用timedelta(),您可以计算前一天的午夜:

from datetime import timedelta

yesterday_midnight = midnight - timedelta(days=1)

那是昨天的事

现在测试您的时间戳是否在这两个点之间:

timestamp = datetime.fromtimestamp(some_timestamp_from_your_log)
if yesterday_midnight <= timestamp < midnight:
    # this happened between 00:00:00 and 23:59:59 yesterday

齐心协力

合并为一个函数:

from datetime import datetime, time, timedelta

def is_yesterday(timestamp):
    midnight = datetime.combine(datetime.today(), time.min)
    yesterday_midnight = midnight - timedelta(days=1)
    return yesterday_midnight <= timestamp < midnight:

if is_yesterday(datetime.fromtimestamp(some_timestamp_from_your_log)):
    # ...

1
如何在不指定时区的情况下判断午夜时间? - sdanzig
1
默认情况下,datetime 模块不具备时区感知能力。它可以返回操作系统提供的本地时间或 UTC 时间。此代码使用本地时间。 - Martijn Pieters
1
在这种情况下,一切都在协调世界时运行,所以这不是一个问题。 - t0mmyt
1
如果所有东西都运行在UTC上,那么不仅没问题,而且背后还有一个聪明的开发者。但是要注意,"昨天"这个概念只适用于英格兰认为的昨天。例如,如果您想根据日志编写的站点的时间执行某些操作,您必须相应地指定时区。 - sdanzig
你能否用 midnight.timestamp() 代替 datetime.fromtimestamp - hounded
1
@hounded:当然你可以比较UNIX时间戳,但是datetime对象更加灵活多用,更不用说便于调试了。 - Martijn Pieters

5

今天开始的午夜是:

midnight = (int(time.time() // 86400)) * 86400

昨天的午夜是:
midnight = (int(time.time() // 86400)) * 86400 - 86400

你必须使用 // 而不是 %。 - mastisa
Mastisa - 非常感谢您的纠正;我本来也要改正它。 - ggemmill

2

给定这样的时间戳,您可以使用divmod来计算自历元以来的天数(您不关心),以及剩余的秒数(您需要):

days_since, remaining_seconds = divmod(t, 24*3600)  # Divide by number of seconds in one day

然后,你从原始的时间戳中减去剩余的秒数,这将得到当天午夜的时间。

t -= remaining_seconds

向上取整就是在向下取整之前将目标时间戳向前移动一天。
tomorrow_t = t + 24 * 3600
days_since, remaining_seconds = divmod(tomorrow_t, 24*3600)
t = tomorrow_t - remaining_seconds

我曾考虑过那种方法,我本来只是想对86400取模,但后来我想起了闰秒。 - t0mmyt
1
这些时间戳不受闰秒的影响。当发生闰秒时,UNIX纪元时间戳会简单地重复,因此您每天都有保证的86400秒。重复时间戳只是闰秒的另一个任意标签,就像“23:59:60”是23:59:59和00:00:00(或者何时应用闰秒)之间的闰秒的任意标签一样。 - chepner

2
获取特定时区的午夜时间戳:
from datetime import datetime
import pytz

TZ = "Asia/Shanghai"
datetime.now(pytz.timezone(TZ)).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()

0
在我的看法中,许多日期和时间的操作都可以借助arrow库更加容易实现并理解。这就是其中之一。
创建一个任意的日期和时间。
>>> import arrow
>>> arbitrary = arrow.get(2017,8,16,11,5)

计算昨天午夜:任意的午夜作为其“日”floor;然后将其向后移动一天。显示结果。
>>> midnight_yesterday = arbitrary.floor('day').shift(days=-1)
>>> midnight_yesterday 
<Arrow [2017-08-15T00:00:00+00:00]>

使用 timestamp 来获取 Python 3.3+ 的所需结果。

>>> midnight_yesterday.datetime.timestamp()
1502755200.0

或者在 Python 2.7 中使用以下表达式。(感谢https://dev59.com/kWgt5IYBdhLWcg3w5hWr#11743262提供后两个表达式。)

>>> (midnight_yesterday-arrow.get(1970,1,1)).total_seconds()
1502755200.0

0
您可以使用以下代码:
import time

seconds_of_day = 24 * 60 * 60  # 86400
last_midnight = (round(time.time()) // seconds_of_day) * seconds_of_day
yesterday_last_midnight = last_midnight - seconds_of_day

0
import time

start_str = time.strftime( "%m/%d/%Y" ) + " 00:00:00"
end_str = time.strftime( "%m/%d/%Y ") + " 23:59:59"
start_ts = int( time.mktime( time.strptime( start_str, "%m/%d/%Y %H:%M:%S" ) ) )
end_ts = int( time.mktime( time.strptime( end_str, "%m/%d/%Y %H:%M:%S" ) ) )

print (start_ts) # timestamp today at 00:00:00
print (end_ts) # timestamp today at 23:59:59
# 1552435200
# 1552521599

源代码 Python获取今天午夜和今天23:59:59的Unix纪元(一天的开始,一天的结束)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接