将Unix时间戳字符串转换为可读日期

1113

我有一个字符串表示一个Unix时间戳(例如“1284101485”)在Python中,我想将其转换为可读日期。当我使用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

4
好的,我会尽力以最简洁的方式翻译以下内容:问题描述: 我有一个字符串,其中包含多个单词,每个单词都以大写字母开头。我需要将这些单词转换为小写,并在它们之间添加下划线。原字符串示例:TheQuickBrownFox 期望输出结果:the_quick_brown_fox解决方案: 使用正则表达式来匹配大写字母并将其替换为相应的小写字母和下划线即可。Python代码示例:import re s = "TheQuickBrownFox" s = re.sub('([A-Z])', r'_\1', s).lower().lstrip('_') print(s)输出结果为:the_quick_brown_fox - slushy
19个回答

1561

使用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'))

162
如果本地时区的UTC偏移量与历史时期不同时,.fromtimestamp() 可能会失败。您需要使用历史时区数据库,例如 pytz 模块(或您的操作系统提供的)。或者只需使用UTC并使用 .utcfromtimestamp() - jfs
11
@J.F.Sebastian,你在几次评论中提到这可能会失败 - 请详细阐述一下为什么对于过去的日期/时间它会失败?(根据点赞数,很多人都同意你的观点并认为这很简单)难道任何Unix时间戳都不具备简单的等效日期/时间吗? - davidhood2
4
请 @davidhood2 在一个 Python 无法访问时区数据库的系统上(例如 Windows),将本地时区设置为过去 UTC 偏移量不同的时区(例如 Europe/Moscow),使用过去(2011 年之后)的时间戳调用 fromtimestamp() 函数。将结果与使用 pytz 计算的值进行比较。如果不清楚,请在 Stack Overflow 上提出单独的问题。 - jfs
4
@davidhood2:我已经发布了展示 pytz 解决方案的我的回答 - jfs
10
一个重要的点是,这个时间戳是自纪元以来的秒数;如果你有毫秒数,你需要除以1000,因为我刚刚发现了这一点。 - wordsforthewise
显示剩余6条评论

322
>>> from datetime import datetime
>>> datetime.fromtimestamp(1172969203.1)
datetime.datetime(2007, 3, 4, 0, 46, 43, 100000)

本段内容来源于http://seehuhn.de/pages/pdate


该方法返回一个datetime.datetime对象。它可以被打印,因为它包含了神奇的__str__()方法。同时请查看[最佳评论][1],这样print(datetime.utcfromtimestamp(unix_time_value)就可以变成可读的时间格式。[1]: https://dev59.com/7XA65IYBdhLWcg3wsgyA#uqefEYcBWogLw_1bPClY - PythoNic

196

最受欢迎的答案建议使用fromtimestamp,但这种方法容易出错,因为它使用本地时区。为了避免问题,更好的方法是使用UTC:

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

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


2
import datetime, pytz datetime.datetime(1990, 1, 1, tzinfo=pytz.utc) - y.selivonchyk
请注意,在某些情况下,Unix时间可能与POSIX时间不同,例如TZ=right/UTC dateTZ=UTC date的区别是Mon 7 Sep 15:58:05 UTC 2020Mon 7 Sep 15:58:32 UTC 2020(差异可能会根据闰秒数量而变化)。 - jfs
2
ValueError: year 53085 is out of range - alper
7
在这种情况下,可能有一个以毫秒为单位的时间戳;尝试除以1000。如果时间戳是微秒级别的,则可以尝试除以1000000。 - ShreevatsaR
“它使用本地时区”是什么意思?它是否假定时间戳是指自1970年1月1日以来在本地时区经过的秒数?还是正确地假定时间戳是指自1970年1月1日以来在UTC中经过的秒数,然后将结果日期/时间表达为本地时区? - Jack M

92

有两个部分:

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

一个可移植的方法是使用pytz时区获取本地时间,即使本地时区在过去有不同的UTC偏移量且Python无法访问时区数据库也可以使用:

#!/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)
为了显示它,您可以使用任何您的系统支持的时间格式,例如:

To display it, you could use any time format that is supported by your system e.g.:


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上,您可以仅使用标准库(如果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))  

如果您关心本地时间,那么它应该是最受欢迎的答案。 - azzamsa
如果你遇到了“ValueError: year xxx is out of range”错误,请将你的时间戳除以1000。参考链接:https://dev59.com/S1wZ5IYBdhLWcg3wWvRY#31548402 - Barlas Apaydin
@jfs 是否有类似的方法可以将日期时间字符串转换回Unix时间戳? - ENV
@ENV:一旦你将输入的时间字符串解析成一个知道时区的datetime对象,只需要调用它的.timestamp()方法即可。如何转换时间字符串取决于其格式--在一般情况下是模棱两可的,但对于各种情况有许多解决方案。 - jfs

92
>>> 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'

12
如果当地时区的 UTC 偏移量不同,time.ctime()time.localtime() 在处理过去的日期时可能会失败。你需要使用历史时区数据库,例如 pytz 模块(或操作系统提供的)。或者直接使用 UTC 并使用 time.gmtime()datetime 可能提供更广泛的日期范围,因此可以使用 datetime.utcfromtimestamp() 代替 time 函数。请注意不改变原文意思。 - jfs
@John La Rooy,是否有类似的方法可以将日期时间字符串转换回Unix时间戳? - ENV

79

在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
@bjornasm 当然,已经更新了答案,并提供了一种类似的方法来实现这个。 - Contango
1
f-strings是Python v3.6+特有的功能 - https://dev59.com/UnI95IYBdhLWcg3wyBCc#51262245 - essexboyracer
1
输出的时间不是UTC时间,除非你在fromtimestamp函数中设置了tz参数,例如datetime.timezone.utc - FObersteiner
@MrFruppes 正确。已于2022年1月17日编辑答案以修复此问题。 - Contango

45
除了使用 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个数字(秒) - 将转换为日期,请使用:

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

38

为了从UNIX时间戳获取可读的时间戳,我以前在脚本中使用过以下代码:

import os, datetime

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

输出:

'2012年12月26日'


我不需要浮点数,只需要这个:datetime.fromtimestamp(path.getmtime('file')).strftime("%Y年%m月%d日") - undefined

29
您可以这样将当前时间转换:
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

24
timestamp ="124542124"
value = datetime.datetime.fromtimestamp(timestamp)
exct_time = value.strftime('%d %B %Y %H:%M:%S')

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


7
这个回答对于这个回答有什么补充? - kocica
1
请添加一个与本地时区假设问题相关的警告。编程中的最佳实践是将时间戳存储为UTC时间,而不是本地时间戳。但是,如果本地时区不是UTC,则上述示例将返回错误的时间。 - Timothy C. Quinn

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