Python将毫秒转换为datetime并返回

Python trouble converting milliseconds to datetime and back

所以我有两个函数可以将python datetime.datetime()对象转换为毫秒和毫秒。我不知道哪里出了问题。以下是我的工作内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
>>> import datetime
>>> def mil_to_date(mil):
   """date items from REST services are reported in milliseconds,
    this function will convert milliseconds to datetime objects

    Required:
        mil -- time in milliseconds
   """

    if mil == None:
        return None
    elif mil < 0:
        return datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(seconds=(mil/1000))
    else:
        return datetime.datetime.fromtimestamp(mil / 1000)

>>> def date_to_mil(date):
   """converts datetime.datetime() object to milliseconds

    date -- datetime.datetime() object"""

    if isinstance(date, datetime.datetime):
        epoch = datetime.datetime.utcfromtimestamp(0)
        return long((date - epoch).total_seconds() * 1000.0)

>>> mil = 1394462888000
>>> date = mil_to_date(mil)
>>> date
datetime.datetime(2014, 3, 10, 9, 48, 8)  #this is correct
>>> d2m = date_to_mil(date)
>>> d2m
1394444888000L
>>> mil
1394462888000L
>>> date2 = mil_to_date(d2m)
>>> date2
datetime.datetime(2014, 3, 10, 4, 48, 8) #why did I lose 5 hours??

因为某种原因,我损失了5个小时。我忽略了一些明显的东西吗?还是我的一个或两个功能都有问题?


原因是date_to_milUTC工作,mil_to_date不工作,你应该用fromtimestamp代替utcfromtimestamp

进一步解释:

在您的代码中,epoch是以UTC表示的纪元日期(但对象没有任何时区)。但是date是本地的,因为fromtimestamp返回一个本地时间:

If optional argument tz is None or not specified, the timestamp is
converted to the platform’s local date and time, and the returned
datetime object is naive

因此,从本地日期时间中减去UTC时间,得到一个延迟,它是到UTC的本地延迟。


如果输入为UTC,则以整数毫秒的形式获取POSIX时间戳:

1
2
3
4
5
6
from datetime import datetime, timedelta

def timestamp_millis(utc_time, epoch=datetime(1970, 1, 1)):
   """Return milliseconds since Epoch as integer."""
    td = utc_time - epoch
    return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) // 10**3

注:公式可能产生与:int(td.total_seconds() * 1000)不同的结果。

反过来:要从POSIX时间中获取UTC时间,以毫秒为单位:

1
2
3
def datetime_from_millis(millis, epoch=datetime(1970, 1, 1)):
   """Return UTC time that corresponds to milliseconds since Epoch."""
    return epoch + timedelta(milliseconds=millis)

支持正、负millis

注:None处理发生在这些功能之外。

例子:

1
2
3
4
5
6
>>> datetime_from_millis(1394462888000)
datetime.datetime(2014, 3, 10, 14, 48, 8)
>>> datetime.utcfromtimestamp(1394462888)
datetime.datetime(2014, 3, 10, 14, 48, 8)
>>> timestamp_millis(_)
1394462888000

结果与你问题中的结果不同!

忽略了gmtime(0).year != 1970TZ=right/UTC案例。