Python创建未来五分钟的Unix时间戳

305

我需要创建一个“过期时间”,使其在未来5分钟内失效,但是必须以UNIX时间戳格式提供。到目前为止,我已经有了下面的代码,但它似乎很不优雅。

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

是否有一个模块或函数可以为我执行时间戳转换?


7
我建议更改这个问题的主题。这个问题很好,但它不是关于将日期时间转换为Unix时间戳的问题。它是关于如何获取未来5分钟的Unix时间戳的问题。 - D. A.
我不同意,@D.A. 这个问题本质上是在说“我需要做X和Y。这是我现在拥有的。有没有更好的方法来做Y?”也许有更好的方法来做X,但标题和正文明确地询问了Y。 - Rob Kennedy
6
我完全同意您在这个问题上的看法,我认为这是一个好问题,并且有一个好答案。问题是,“Python datetime to Unix timestamp”并没有反映出问题或答案。我是通过搜索一种转换方式才找到了这篇文章,但由于误导性的主题行,浪费了我的时间。我建议改成:“Python,未来5分钟的UNIX时间戳”。 - D. A.
3
@JimmyKane - 在这里可以找到一份非常全面的答案,讲述如何从日期时间中获取时间戳:https://dev59.com/hWoy5IYBdhLWcg3wF6ML#8778548 - Tim Tisdall
@TimTisdall 是的,因为标题已更改,所以它没有意义。 - Jimmy Kane
12个回答

355

另一种方法是使用calendar.timegm


future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

相比于strftime%s标志(在Windows上不起作用),它也更具可移植性。


12
请注意,结合前两个评论,正确的解决方案是:calendar.timegm(future.utctimetuple())。这样可以确保将UTC时间传递给calendar.timegm - shadowmatter
1
无法对@tumbleweed的评论进行足够的点赞。如果您正在尝试获取UNIX时间戳(因此是UTC时间),请使用calendar.timegm。 - Bialecki
@tumbleweed,没错。如果您使用mktime加上gmtime(0),除了UTC之外的任何时区都会产生非零的往返差:例如,time.mktime(datetime.fromtimestamp(time.mktime(time.gmtime(0))).timetuple())在我的Unix机器的TZ中给出了21600.0秒(6小时),而不是0.0。 - hobs
如果您想获取UTC时间戳,应该使用以下代码:calendar.timegm(datetime.datetime.utcnow().timetuple())。在Python 3.2中,使用datetime.datetime.now().utctimetuple()方法无法正常工作。 - Wookie88
@NidhinBoseJ.:就好像你根本没有读答案一样。这也是一个愚蠢的解决方案,因为最终你会得到一个字符串。你为什么想要一个字符串?提示:你不需要。 - Lightness Races in Orbit
显示剩余6条评论

165

现在在 Python >= 3.3 版本中,您只需调用 timestamp() 方法 即可将时间戳作为浮点数获取。

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

5
+1给这个。它应该显示更高,因为这是在Python 3中实现的清晰方式。 - Viktor Stískala
3
我认为在评论的开头说得很清楚了,但我也加粗了一些字。 - Tim Tisdall
1
我会把这个注释作为代码块中的注释,因为我们都只是先扫描答案中的代码,只有当代码看起来不错时才会阅读其余部分。虽然回答很好。 - Matthew Purdon
2
本地时间可能不明确。这个例子(datetime.now())并不好,因为它鼓励使用表示本地时间的简单日期时间对象,并且在夏令时转换期间可能会出现错误(由于固有的模糊性)。您可以使用ts = datetime.now(timezone.utc).timestamp()来代替。 - jfs
@J.F.Sebastian - 说得好。虽然我不想增加导入,但我把它改成了 utcnow()。我习惯于在时区设置为UTC的机器上工作,但这不能在此代码片段中假定。 - Tim Tisdall
显示剩余5条评论

146

刚刚发现这个,而且它更短。

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

12
这并没有回答这个问题。 - Jesse Dhillon
24
@JesseDhillon回答了这个问题(生成一个未来5分钟的UNIX时间戳),只是没有按标题回答。 - dbr
3
time.time() 可以被设置回去。如果要创建一个在未来 5 分钟内过期的 "Expires" 值,则根据使用情况可能需要 time.monotonic() 类似的模拟函数。 - jfs
@j-f-sebastian time.monotonic() 不会返回 UNIX 时间戳,它会返回一个具有未定义参考点的时间戳。 - rspeer
@rspeer:是的,正如文档所述,只有连续调用之间的差异才是有效的。是否可以使用“单调”取决于您的用例,例如,“subprocess”模块确实使用它来实现“timeout”选项。 - jfs
你为什么要为此创建一个全新的专用函数? - au_stan

57

这是你需要的:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

这与“Cat Plus Plus”提供的有何不同或增加了什么? - David
3
这是对问题“Python datetime转换为Unix时间戳”的答案,而Cat Plus Plus回答了问题“5分钟后的Python datetime转换为Unix时间戳”。因此,这个答案很清晰明了。 - running.t
@running.t:这让我想起了一句话:“每个问题都有简单、明显而且错误的解决方案”。请参阅mktime(dt.timetuple())可能存在的问题。在Python 3.3+中,@Tim Tisdall提供的datetime.now(timezone.utc).timestamp()是解决方案。否则,可以使用(dt - epoch).total_seconds() - jfs
@J.F.Sebastian 如果我真的希望所有计算都在本地时间进行,该怎么办?例如,解析一个已知为本地时间的字符串,并决定在特定时间是否存在夏令时。 - n611x007
1
@naxa:是的,有些本地时间是模糊或不存在的。此外,时区偏移可能因其他原因而不同于夏令时(您需要像pytz这样的tz数据库来查找正确的偏移量)。本地时间意味着任何当地政治家认为衡量时间是一个好主意,即它可能非常不规则。 - jfs

49

您可以使用 datetime.strftime 函数,使用格式字符串 %s 来获取Epoch形式的时间:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

注意:此方法仅适用于Linux系统,而且此方法无法使用时区。


32
这是一个文档不太完整的行为(http://www.python.org/doc/current/library/datetime.html)。在Linux下似乎可以工作,但在win32下无法正常工作(会生成“ValueError:Invalid format string”错误)。 - Antony Hatchkins
3
这种方法不适用于时区。更改时区将得到相同的结果。 datetime(2013,12,7,tzinfo=timezone("America/Chicago")).strftime("%s") 1386385200 datetime(2013,12,7,tzinfo=timezone("Europe/Riga")).strftime("%s") 1386385200 - Martins Balodis

11
这里是一个更完整的基于 datetime 的解决方案,用于将日期时间对象转换为 POSIX 时间戳:
future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

请访问在Python中将datetime.date转换为UTC时间戳了解更多详细信息。


6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()

4
关键在于确保在开始转换之前,您使用的所有日期都是UTC时区。请参阅http://pytz.sourceforge.net/了解如何正确执行此操作。通过将其规范化为UTC,您可以消除夏令时转换的歧义。然后,您就可以安全地使用timedelta来计算距离Unix纪元的距离,然后转换为秒或毫秒。
请注意,生成的Unix时间戳本身位于UTC时区。如果您希望在本地化时区中查看时间戳,则需要进行另一次转换。
还要注意,这只适用于1970年之后的日期。
   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

3
请注意:我不理解“本地化时区的UNIX时间戳”是什么意思。时间戳是相同的(自1970年1月1日00:00:00 +00:00以来经过的秒数)。要获取本地时区的原始日期时间对象,请使用以下代码:datetime.fromtimestamp(ts) - jfs

4
以下内容基于上述答案(加上毫秒的更正),并模拟在使用时区时Python 3.3之前的 Python 3中datetime.timestamp()的功能。
def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

严格回答这个问题,您需要:

datetime_timestamp(my_datetime) + 5 * 60
datetime_timestampsimple-date 的一部分。但如果你正在使用该软件包,你可能会输入以下内容:
SimpleDate(my_datetime).timestamp + 5 * 60

这个处理程序可以处理更多的格式/类型,针对my_datetime。


你应该加上(5 * 60)来增加5分钟,不然只加5会在时间戳上增加5秒。 - Tim Tisdall

1
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue

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