【问题标题】:How can I convert a datetime object to milliseconds since epoch (unix time) in Python?如何在 Python 中将日期时间对象转换为自纪元(unix 时间)以来的毫秒数?
【发布时间】:2011-10-23 09:43:30
【问题描述】:

我有一个 Python datetime 对象,我想将其转换为 unix 时间,或自 1970 年以来的秒/毫秒。

我该怎么做?

【问题讨论】:

标签: python datetime epoch


【解决方案1】:
>>> import datetime
>>> # replace datetime.datetime.now() with your datetime object
>>> int(datetime.datetime.now().strftime("%s")) * 1000 
1312908481000

或者时间模块的帮助(并且没有日期格式):

>>> import datetime, time
>>> # replace datetime.datetime.now() with your datetime object
>>> time.mktime(datetime.datetime.now().timetuple()) * 1000
1312908681000.0

http://pleac.sourceforge.net/pleac_python/datesandtimes.html的帮助下回答了

文档:

【讨论】:

  • 顺便说一句,strftime("%s") 为我返回一个空字符串。第二种方法效果很好。
  • 只有秒精度
  • '%s' 不受 Python 支持,例如,它在 Windows 上可能不存在。 .timetuple() 返回 tm_isdst=-1 它迫使 mktime() 猜测。它可能会在 DST 期间猜错(50% 的错误几率 +/- 小时)。 '%s' 和 mktime() 都可能对过去的日期使用错误的 UTC 偏移量。您需要一个历史时区数据库,例如 pytz 模块提供的以可靠地将本地时间转换为 POSIX 时间戳(除非操作系统已经提供了这样的数据库)
  • time.mktime(ts.timetuple()) 其中 ts 是 python 的日期时间对象
  • @suhail:阅读我上面关于mktime/timetuple 的评论。 timetuple() 也去除了几分之一秒,问题的关键是要获得毫秒精度的时间戳。
【解决方案2】:
import time
seconds_since_epoch = time.mktime(your_datetime.timetuple()) * 1000

【讨论】:

  • 这是错误的!时间元组不包括毫秒,因此 mktime 不会返回毫秒分辨率的纪元。在这种情况下它是没有用的。
  • @Wang - 你是对的先生,这不会返回毫秒,只有几秒钟
  • 如果你删除* 1000,你会得到seconds_since_epoch。赞成这个答案,因为我现在不关心毫秒。
【解决方案3】:

在我看来,最简单的方法是

import datetime

epoch = datetime.datetime.utcfromtimestamp(0)

def unix_time_millis(dt):
    return (dt - epoch).total_seconds() * 1000.0

【讨论】:

  • 到目前为止,这是最好的解决方案(如果 python 版本 >2.7)。因为%s 的实现取决于操作系统!因此,任何人都希望代码可靠地工作,无论在哪个操作系统上,都不应使用%s。对于 2.3 total_seconds():delta.days*86400+delta.seconds+delta.microseconds/1e6
  • 注意:dt 必须是 UTC(不是本地)。见similar answer with Python 2.6/3 support
  • 值得一提的是,如果您想要的只是此处定义的真正的 unix 时间戳en.wikipedia.org/wiki/Unix_time (因此只会使用此答案中的 unix_time 函数),那么您应该将 delta.total_seconds() 包装为int 以避免以浮点数结束
  • 使用utcfromtimestamp(0) 计算的纪元只有在'tz' 不为0 时才可能导致'tz' 偏移。这是因为dt- epoch 中的dt 在其中计算了'tz' 纪元是 UTC 时间。计算纪元的最佳方法是epoch = datetime.datetime(1970, 1, 1),其中考虑了时区。
  • 为什么datetime.utcfromtimestamp(0) 返回一个没有tzinfo 的日期时间?它就在方法名称中,utcfromtimestamp。为了使它不幼稚,我必须做类似datetime.utcfromtimestamp(0).replace(tzinfo=pytz.UTC) 的事情。如果dt 可以识别时区,则这是必要的,否则您将获得TypeError: can't subtract offset-naive and offset-aware datetimes
【解决方案4】:

这就是我的做法:

from datetime import datetime
from time import mktime

dt = datetime.now()
sec_since_epoch = mktime(dt.timetuple()) + dt.microsecond/1000000.0

millis_since_epoch = sec_since_epoch * 1000

【讨论】:

  • @J.F.Sebastian 感谢您的提醒!确实没有考虑dst。如果您的服务器是本地时间而不是 UTC,那么它会有所作为。我还没有找到任何令人信服的理由来设置除 UTC 以外的任何服务器。我的 moto 是“写 UTC,读本地时间”,所以你总是知道你住在哪里......
  • 您可以随时使用 calendar.timegm 代替 mktime 来避免 mktime 试图猜测时区的问题。
【解决方案5】:
>>> import datetime
>>> import time
>>> import calendar

>>> #your datetime object
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2013, 3, 19, 13, 0, 9, 351812)

>>> #use datetime module's timetuple method to get a `time.struct_time` object.[1]
>>> tt = datetime.datetime.timetuple(now)
>>> tt
time.struct_time(tm_year=2013, tm_mon=3, tm_mday=19, tm_hour=13, tm_min=0, tm_sec=9,     tm_wday=1, tm_yday=78, tm_isdst=-1)

>>> #If your datetime object is in utc you do this way. [2](see the first table on docs)
>>> sec_epoch_utc = calendar.timegm(tt) * 1000
>>> sec_epoch_utc
1363698009

>>> #If your datetime object is in local timeformat you do this way
>>> sec_epoch_loc = time.mktime(tt) * 1000
>>> sec_epoch_loc
1363678209.0

[1]http://docs.python.org/2/library/datetime.html#datetime.date.timetuple

[2]http://docs.python.org/2/library/time.html

【讨论】:

    【解决方案6】:

    你可以使用 Delorean 穿越时空!

    import datetime
    import delorean
    dt = datetime.datetime.utcnow()
    delorean.Delorean(dt, timezone="UTC").epoch
    

    http://delorean.readthedocs.org/en/latest/quickstart.html

    【讨论】:

      【解决方案7】:
      from datetime import datetime
      from calendar import timegm
      
      # Note: if you pass in a naive dttm object it's assumed to already be in UTC
      def unix_time(dttm=None):
          if dttm is None:
             dttm = datetime.utcnow()
      
          return timegm(dttm.utctimetuple())
      
      print "Unix time now: %d" % unix_time()
      print "Unix timestamp from an existing dttm: %d" % unix_time(datetime(2014, 12, 30, 12, 0))
      

      【讨论】:

      • timegm() 仅适用于 UTC 时间。它不使用tm_isdst,因此您可以使用utcnow.timetuple() 而不是utcnow.utctimetuple()。注意:在这里使用naive_local_datetime.utctimetuple() 是错误的。它不会将当地时间转换为 UTC。此外,timetuple() 调用会从结果中删除几分之一秒(是否重要取决于应用程序)。该问题还询问 *milli*​秒,而不是秒
      • 我更喜欢使用 utcnow() 和 utctimetuple() 使代码绝对清楚你正在处理 UTC(这样任何阅读它的人都不必记住 timegm 只是 UTC )。 utctimetuple() 并不意味着对天真的 dttm 对象进行翻译(因此使用 utcnow() 初始化 dttm)。另外,问题提到了秒或毫秒。
      • 注意:应该在最后的评论中说我读到这个问题暗示他想要几秒钟或几毫秒(可能是我的错误)。对于毫秒,只需乘以 1000(如得分最高的答案所示)。
      • utctimetuple() 去除几分之一秒。乘以 1000 不会让他们回来。
      • 由于 OP 提出这个问题的方式,不清楚他/她到底想要什么(即真正的 unix 时间戳或毫秒精度的时间戳)。无论如何,这两个问题都已经在其他地方提出并回答了。话虽如此,我认为这里的答案对于人们来说是最快和最干净的,并且很好地说明了问题的各种解决方案。
      【解决方案8】:

      在 Python 3.3 中,添加了新方法 timestamp

      import datetime
      seconds_since_epoch = datetime.datetime.now().timestamp()
      

      你的问题表明你需要毫秒,你可以这样得到:

      milliseconds_since_epoch = datetime.datetime.now().timestamp() * 1000
      

      如果你在一个简单的日期时间对象上使用timestamp,那么它假定它在本地时区。如果您不打算这样做,请使用可识别时区的日期时间对象。

      【讨论】:

      • 注意:.timestamp() 方法假定天真的输入日期时间在本地时区(本地时间可能不明确)。如果是 UTC,则使用 dt.replace(tzinfo=timezone.utc).timestamp() instead
      • datetime.timestamp() 以浮点数形式返回纪元秒数。获取毫秒:int(datetime.timestamp() * 1000)
      • 这个答案不是一个可复制粘贴的例子,本着docs.python.org/3/library/… 的非人性化文档的精神——这是:datetime.datetime.timestamp(datetime.datetime.now())
      • 在 3.6 中(至少), datetime.timestamp() 假定时区天真 (tzinfo=None) 日期时间为 UTC。所以最好设置你的时区:datetime.datetime.now(pytz.timezone('Europe/Paris')).timestamp() == datetime.datetime.now(pytz.utc).timestamp() == datetime.datetime.utcnow().timestamp(),但不(总是)等于datetime.datetime.now().timestamp()(如果本地 tz 是 UTC,最后一个只等于其余的......)
      • 为了您的兴趣,反面是]fromtimestamp(docs.python.org/3/library/…)
      【解决方案9】:

      这是另一种形式的时间对象标准化解决方案:

      def to_unix_time(timestamp):
          epoch = datetime.datetime.utcfromtimestamp(0) # start of epoch time
          my_time = datetime.datetime.strptime(timestamp, "%Y/%m/%d %H:%M:%S.%f") # plugin your time object
          delta = my_time - epoch
          return delta.total_seconds() * 1000.0
      

      【讨论】:

        【解决方案10】:

        【讨论】:

        • @ChristopherBull 只需将毫秒数除以 1000 即可得到秒数
        • 你误解了,弄错了。秒在上述功能中都已准备就绪。您可以将其转换为毫秒,但它会是一秒的精度。
        • 此答案使用 time 模块,但 OP 询问了 datetime 模块。 FWIW,最简单的当前纪元是int(time.time())
        【解决方案11】:

        另一种将日期时间转换为 unixtimestampmillis 的解决方案。

        private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        
            public static long GetCurrentUnixTimestampMillis()
            {
                DateTime localDateTime, univDateTime;
                localDateTime = DateTime.Now;          
                univDateTime = localDateTime.ToUniversalTime();
                return (long)(univDateTime - UnixEpoch).TotalMilliseconds;
            } 
        

        【讨论】:

        • 问题是关于Python语言的
        【解决方案12】:

        一点熊猫代码:

        import pandas
        
        def to_millis(dt):
            return int(pandas.to_datetime(dt).value / 1000000)
        

        【讨论】:

          【解决方案13】:

          这是我根据上面的答案做的一个函数

          def getDateToEpoch(myDateTime):
              res = (datetime.datetime(myDateTime.year,myDateTime.month,myDateTime.day,myDateTime.hour,myDateTime.minute,myDateTime.second) - datetime.datetime(1970,1,1)).total_seconds()
              return res
          

          你可以像这样包装返回值:str(int(res)) 将其返回不带十进制值用作字符串或仅 int(不带 str)

          【讨论】:

            【解决方案14】:

            其中很多答案不适用于 python 2,或者不保留日期时间的毫秒数。这对我有用

            def datetime_to_ms_epoch(dt):
                microseconds = time.mktime(dt.timetuple()) * 1000000 + dt.microsecond
                return int(round(microseconds / float(1000)))
            

            【讨论】:

              猜你喜欢
              • 2017-02-19
              • 2013-08-19
              • 1970-01-01
              • 1970-01-01
              • 2014-03-14
              • 2019-05-20
              • 2017-07-23
              • 2011-08-31
              相关资源
              最近更新 更多