【问题标题】:Converting unix timestamp string to readable date将 unix 时间戳字符串转换为可读日期
【发布时间】:2022-01-21 15:34:05
【问题描述】:

我在 Python 中有一个表示 unix 时间戳(即“1284101485”)的字符串,我想将其转换为可读日期。当我使用time.strftime 时,我得到一个TypeError

>>>import time
>>>print time.strftime("%B %d %Y", "1284101485")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument must be 9-item sequence, not str

【问题讨论】:

标签: python datetime unix-timestamp strftime


【解决方案1】:

使用datetime模块:

from datetime import datetime
ts = int('1284101485')

# if you encounter a "year is out of range" error the timestamp
# may be in milliseconds, try `ts /= 1000` in that case
print(datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S'))

【讨论】:

  • 如果本地时区具有不同的 UTC 偏移量,.fromtimestamp() 可能会在过去的日期失败。您需要一个历史时区数据库,例如 pytz 模块(或您的操作系统)提供的。或者只是在 UTC 工作并使用.utcfromtimestamp()
  • @J.F.Sebastian 你已经提到这可能会在几个 cmets 中失败 - 请你详细说明为什么它会在过去的日期/时间失败? (从赞成票来看,很多人都同意你的观点并认为这很简单)当然任何 unix 时间戳都有一个简单的等效日期/时间?
  • @davidhood2 采用python无法访问the tz database(Windows)的系统,将您的本地时区设置为过去具有不同UTC偏移量的时区(例如欧洲/莫斯科),调用fromtimestamp() 带有过去 (2011-) 的时间戳。将结果与使用pytz 计算的值进行比较。如果不清楚;问一个单独的 Stack Overflow 问题。
  • @davidhood2:我已经发布了my own answer that demonstrates the pytz solution
  • 一个重要的点是这需要一个自纪元以来的时间戳,以秒为单位;如果你有毫秒,你必须除以 1000,正如我刚刚发现的那样。
【解决方案2】:
>>> from datetime import datetime
>>> datetime.fromtimestamp(1172969203.1)
datetime.datetime(2007, 3, 4, 0, 46, 43, 100000)

取自http://seehuhn.de/pages/pdate

【讨论】:

    【解决方案3】:

    投票最多的答案建议使用 fromtimestamp,因为它使用本地时区,因此很容易出错。为避免出现问题,更好的方法是使用 UTC:

    datetime.datetime.utcfromtimestamp(posix_time).strftime('%Y-%m-%dT%H:%M:%SZ')
    

    其中 posix_time 是您要转换的 Posix 纪元时间

    【讨论】:

    • 导入日期时间,pytz datetime.datetime(1990, 1, 1, tzinfo=pytz.utc)
    • 注意,在(罕见的)情况下,unix 时间可能与 posix 时间不同,例如,TZ=right/UTC dateTZ=UTC dateMon 7 Sep 15:58:05 UTC 2020Mon 7 Sep 15:58:32 UTC 2020(差异可能会根据闰秒数)
    • ValueError: year 53085 is out of range
    • @alper 在这种情况下,很可能有一个以毫秒为单位的时间戳;尝试除以 1000。如果时间戳以微秒为单位,则除以 1000000。
    【解决方案4】:
    >>> import time
    >>> time.ctime(int("1284101485"))
    'Fri Sep 10 16:51:25 2010'
    >>> time.strftime("%D %H:%M", time.localtime(int("1284101485")))
    '09/10/10 16:51'
    

    【讨论】:

    • 如果本地时区具有不同的 UTC 偏移量,time.ctime()time.localtime() 可能会在过去的日期失败。您需要一个历史时区数据库,例如 pytz 模块(或您的操作系统)提供的。或者只是在 UTC 工作并使用time.gmtime()datetime 可能提供更宽的日期范围,因此可以使用 datetime.utcfromtimestamp() 代替 time 函数。
    • @John La Rooy 是否有类似的方法可以将日期时间字符串转换回 Unix 时间戳?
    【解决方案5】:

    分为两部分:

    1. 将 unix 时间戳(“自纪元以来的秒数”)转换为本地时间
    2. 以所需格式显示本地时间。

    即使本地时区过去有不同的 utc 偏移量并且 python 无法访问 tz 数据库,获取本地时间的可移植方法是使用 pytz 时区:

    #!/usr/bin/env python
    from datetime import datetime
    import tzlocal  # $ pip install tzlocal
    
    unix_timestamp = float("1284101485")
    local_timezone = tzlocal.get_localzone() # get pytz timezone
    local_time = datetime.fromtimestamp(unix_timestamp, local_timezone)
    

    要显示它,您可以使用系统支持的任何时间格式,例如:

    print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"))
    print(local_time.strftime("%B %d %Y"))  # print date in your format
    

    如果您不需要本地时间,则改为获取可读的 UTC 时间:

    utc_time = datetime.utcfromtimestamp(unix_timestamp)
    print(utc_time.strftime("%Y-%m-%d %H:%M:%S.%f+00:00 (UTC)"))
    

    如果您不关心可能影响返回什么日期的时区问题,或者如果 python 可以访问系统上的 tz 数据库:

    local_time = datetime.fromtimestamp(unix_timestamp)
    print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f"))
    

    在 Python 3 上,您可以仅使用 stdlib 获得时区感知日期时间(如果 python 无法访问您系统上的 tz 数据库,例如在 Windows 上,则 UTC 偏移量可能是错误的):

    #!/usr/bin/env python3
    from datetime import datetime, timezone
    
    utc_time = datetime.fromtimestamp(unix_timestamp, timezone.utc)
    local_time = utc_time.astimezone()
    print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"))
    

    time 模块中的函数是围绕相应 C API 的精简包装器,因此它们的可移植性可能不如相应的 datetime 方法,否则您也可以使用它们:

    #!/usr/bin/env python
    import time
    
    unix_timestamp  = int("1284101485")
    utc_time = time.gmtime(unix_timestamp)
    local_time = time.localtime(unix_timestamp)
    print(time.strftime("%Y-%m-%d %H:%M:%S", local_time)) 
    print(time.strftime("%Y-%m-%d %H:%M:%S+00:00 (UTC)", utc_time))  
    

    【讨论】:

    • 如果您关心当地时间,这应该是投票最多的答案。
    • 如果你得到 ValueError: year xxx is out of range 错误将你的时间戳划分为 /1000 stackoverflow.com/a/31548402/1428241
    • @jfs 是否有类似的方法可以将日期时间字符串转换回 Unix 时间戳?
    • @ENV:一旦您将输入时间字符串解析为可感知的日期时间对象,只需调用其.timestamp() 方法即可。如何转换时间字符串取决于它的格式——在一般情况下它是模棱两可的,但对于各种情况有很多解决方案。
    【解决方案6】:

    在 Python 3.6+ 中:

    import datetime
    
    timestamp = 1642445213
    value = datetime.datetime.fromtimestamp(timestamp)
    print(f"{value:%Y-%m-%d %H:%M:%S}")
    

    输出(当地时间)

    2022-01-17 20:46:53
    

    说明

    奖金

    要将日期保存为字符串然后打印,请使用:

    my_date = f"{value:%Y-%m-%d %H:%M:%S}"
    print(my_date)
    

    以 UTC 输出:

    value = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc)
    # 2022-01-17 18:50:52
    

    【讨论】:

    • 很好的答案,但希望您展示如何将日期保存到字符串,而不仅仅是打印它: value.strftime('%Y-%m-%d %H:%M: %S')
    • @bjornasm 当然,用类似的方法更新答案来实现这一点。
    • f 字符串特定于 Python v3.6+ - stackoverflow.com/a/51262245/4442148
    • 输出是 不是 UTC 而是本地时间,除非您在 fromtimestamp 中设置了 tz 参数,例如到datetime.timezone.utc
    • @MrFruppes 正确。在 2022 年 1 月 17 日编辑答案以解决此问题。
    【解决方案7】:

    除了使用time/datetime包,pandas也可以用来解决同样的问题。下面是我们如何使用pandas时间戳转换为可读日期

    时间戳可以有两种格式:

    1. 13 位(毫秒)- 要将 毫秒 转换为日期,请使用:

      import pandas
      result_ms=pandas.to_datetime('1493530261000',unit='ms')
      str(result_ms)
      
      Output: '2017-04-30 05:31:01'
      
    2. 10 位(秒)- 要将 转换为日期,请使用:

      import pandas
      result_s=pandas.to_datetime('1493530261',unit='s')
      str(result_s)
      
      Output: '2017-04-30 05:31:01'
      

    【讨论】:

    • 似乎又是 pandas 的又一次胜利 - 该模块在所有方面都很棒
    【解决方案8】:

    对于来自 UNIX 时间戳的人类可读时间戳,我之前在脚本中使用过:

    import os, datetime
    
    datetime.datetime.fromtimestamp(float(os.path.getmtime("FILE"))).strftime("%B %d, %Y")
    

    输出:

    '2012 年 12 月 26 日'

    【讨论】:

      【解决方案9】:

      你可以像这样转换当前时间

      t=datetime.fromtimestamp(time.time())
      t.strftime('%Y-%m-%d')
      '2012-03-07'
      

      将字符串中的日期转换为不同的格式。

      import datetime,time
      
      def createDateObject(str_date,strFormat="%Y-%m-%d"):    
          timeStamp = time.mktime(time.strptime(str_date,strFormat))
          return datetime.datetime.fromtimestamp(timeStamp)
      
      def FormatDate(objectDate,strFormat="%Y-%m-%d"):
          return objectDate.strftime(strFormat)
      
      Usage
      =====
      o=createDateObject('2013-03-03')
      print FormatDate(o,'%d-%m-%Y')
      
      Output 03-03-2013
      

      【讨论】:

        【解决方案10】:
        timestamp ="124542124"
        value = datetime.datetime.fromtimestamp(timestamp)
        exct_time = value.strftime('%d %B %Y %H:%M:%S')
        

        还可以从时间戳中获取可读的日期,也可以更改日期的格式。

        【讨论】:

        • 这个答案对this 答案有什么作用?
        • 请添加与本地时区假设问题相关的警告。编程中的最佳实践是将时间戳存储为 UTC 时间,而不是本地时间戳。但是,如果本地时区不是 UTC,上面的示例将返回错误的时间。
        【解决方案11】:

        请注意,utcfromtimestamp 可以导致unexpected results,因为它返回一个简单的日期时间对象。 Python 将原始日期时间视为 本地时间 - 而 UNIX 时间指的是 UTC。

        可以通过在fromtimestamp 中设置tz 参数来避免这种歧义:

        from datetime import datetime, timezone
        
        dtobj = datetime.fromtimestamp(1284101485, timezone.utc)
        
        >>> print(repr(dtobj))
        datetime.datetime(2010, 9, 10, 6, 51, 25, tzinfo=datetime.timezone.utc)
        

        现在您可以格式化为字符串,例如符合 ISO8601 的格式:

        >>> print(dtobj.isoformat(timespec='milliseconds').replace('+00:00', 'Z'))
        2010-09-10T06:51:25.000Z
        

        【讨论】:

          【解决方案12】:

          使用下面的代码,希望能解决你的问题。

          import datetime as dt
          
          print(dt.datetime.fromtimestamp(int("1284101485")).strftime('%Y-%m-%d %H:%M:%S'))
          

          【讨论】:

          • 添加解释重新,为什么这段代码会解决问题以改善您的答案。
          【解决方案13】:
          import datetime
          temp = datetime.datetime.fromtimestamp(1386181800).strftime('%Y-%m-%d %H:%M:%S')
          print temp
          

          【讨论】:

            【解决方案14】:

            另一种可以使用 gmtime 和 format 函数完成的方法;

            from time import gmtime
            print('{}-{}-{} {}:{}:{}'.format(*gmtime(1538654264.703337)))
            

            输出:2018-10-4 11:57:44

            【讨论】:

              【解决方案15】:

              如果您正在使用数据框并且想要series cannot be converted to class int 错误。使用下面的代码。

              new_df= pd.to_datetime(df_new['time'], unit='s')
              

              【讨论】:

                【解决方案16】:

                我刚刚使用成功:

                >>> type(tstamp)
                pandas.tslib.Timestamp
                >>> newDt = tstamp.date()
                >>> type(newDt)
                datetime.date
                

                【讨论】:

                  【解决方案17】:

                  又快又脏的一个班轮:

                  '-'.join(str(x) for x in list(tuple(datetime.datetime.now().timetuple())[:6]))
                  

                  '2013-5-5-1-9-43'

                  【讨论】:

                  • 或更简洁:'-'.join(map(str, datetime.datetime.now().timetuple()[:6]))
                  • @JelleZijlstra 嗯,我更喜欢生成器表达式而不是 map。
                  • '2013-5-5-1-9-43' 是什么日期格式?我从未在任何地方看到这种格式作为日期/时间的有效表示。
                  • 你能详细说明什么是无效的表示@madoki?你的意思是非标准?它与大多数其他答案相比的主要优势是能够将其包含在文件或目录路径中,因为空格和冒号不在标准的 unix 目录字符集中。参见例如stackoverflow.com/a/458001/209246
                  【解决方案18】:

                  您可以使用easy_date 来简化:

                  import date_converter
                  my_date_string = date_converter.timestamp_to_string(1284101485, "%B %d, %Y")
                  

                  【讨论】:

                  • 每个节目都有自己的日期和时间转换器。永远不必为此使用模组/框架
                  • strptimestrftime 不直观...甚至不可读...但我理解并尊重您的意见
                  • 应该“永远不必使用”是错误的。这取决于内置库的语言和质量。 Javascript 有 moment.js,Java 有 Joda time,它们都比各自的内置日期和时间转换实用程序更受欢迎(以至于 Joda time 后来影响了 Java 8 的更新标准库)。也就是说,除非问题需要好的第三方库,否则最好根据标准库给出答案。
                  • 我已经纠正了@NikosVentouras。我刚刚第一次遇到“IE 中的 JS 日期行为不同”的问题。所以我最终使用了 moment.js
                  猜你喜欢
                  • 1970-01-01
                  • 2011-03-16
                  • 1970-01-01
                  • 2019-07-30
                  • 2012-06-23
                  • 2011-09-23
                  • 1970-01-01
                  • 2012-09-01
                  相关资源
                  最近更新 更多