Python 如何测试给定的时间戳是以秒还是毫秒为单位?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23929145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test if a given time-stamp is in seconds or milliseconds?
提问by Ryan
Assume a given variable, it is containing a UNIX
time-stamp, but whether it is in seconds or milliseconds format is unknown, I want to assign to a variable which is in seconds format
假设一个给定的变量,它包含一个UNIX
时间戳,但是它是秒格式还是毫秒格式是未知的,我想分配给一个秒格式的变量
For Example:
例如:
unknown = 1398494489444 # This is millisecond
t = ???
Updated: I understand it is not possible to tell without giving some limitations, so here is it
更新:我知道在不给出一些限制的情况下无法判断,所以这里是
- current_ts - 86400 * 365 < unknown < current_ts
- current_ts - 86400 * 365 < 未知 < current_ts
Assume current_ts = current unix timestamp
Assume current_ts = current unix timestamp
回答by Sandman
If you convertthe maximum timestamp values with x digits in millis you get something like this:
如果您将最大时间戳值转换为以毫秒为单位的 x 位数字,则会得到如下结果:
- 9999999999999 (13 digits) means Sat Nov 20 2286 17:46:39 UTC
- 999999999999 (12 digits) means Sun Sep 09 2001 01:46:39 UTC
- 99999999999 (11 digits) means Sat Mar 03 1973 09:46:39 UTC
- 9999999999999(13 位数字)表示 UTC 时间 11 月 20 日星期六 17:46:39
- 999999999999(12 位数字)表示 2001 年 9 月 9 日星期日 01:46:39 UTC
- 99999999999(11 位数字)表示 1973 年 3 月 3 日星期六 09:46:39 UTC
Can your timestamps be older than 2001? If not i think you're safe to check whether the number has 13 digits or more - if yes you have milliseconds, if not you have seconds. Of course this will only work until timestamps in seconds will have 13 digits as well, which means timestamps in milliseconds will have 16 digits:
您的时间戳可以早于 2001 年吗?如果不是,我认为您可以安全地检查该数字是否有 13 位或更多位 - 如果是,则有毫秒,如果没有,则有秒。当然,这只适用于以秒为单位的时间戳也有 13 位数字,这意味着以毫秒为单位的时间戳将有 16 位数字:
- 1000000000000000 (16 digits) means Fri Sep 27 33658 01:46:40 but by then i will be living on a planet from the Alpha Centauri system and time standards will probably have changed a bit :)
- 1000000000000000(16 位数字)表示周五 9 月 27 日 33658 01:46:40 但到那时我将生活在半人马座阿尔法系统的行星上,时间标准可能会有所改变:)
P.S. you can loosen up the condition to 12 digits or more, if your timestamps can't go back further than 1973. The condition should only be ok up until:
PS,如果您的时间戳不能追溯到 1973 年之后,您可以将条件放宽到 12 位或更多。条件应该只在以下情况下正常:
- 100000000000000 (15 digits) means Wed Nov 16 5138 09:46:40 because this in seconds will have 12 digits and will overlap with your condition
- 100000000000000(15 位数字)表示 Wed Nov 16 5138 09:46:40 因为这以秒为单位将有 12 位数字并将与您的情况重叠
回答by Martijn Pieters
With your constraints, it is trivial to detect millisecond timestamps. Even timestamps a year into the past are still magnitudes larger than the current timestamp.
有了你的限制,检测毫秒时间戳就很简单了。即使是过去一年的时间戳仍然比当前时间戳大得多。
Simply test if the number is greater than the current timestamp; if so, you have a timestamp in milliseconds:
只需测试数字是否大于当前时间戳;如果是这样,你有一个以毫秒为单位的时间戳:
now = time.mktime(time.gmtime())
if t > now:
# milliseconds, convert to seconds
t /= 1000.0
By dividing by 1000, you convert the timestamp back to one expressed in seconds and the default time
module functions can be applied.
通过除以 1000,您可以将时间戳转换回以秒表示的时间戳,并且time
可以应用默认模块函数。
That's because even a timestamp in milliseconds representing one year in the past, accidentally interpreted as a timestamp in seconds, would lie farinto the future:
这是因为即使以毫秒为单位表示过去一年的时间戳,被意外解释为以秒为单位的时间戳,也会在很远的未来:
>>> import time
>>> ts = time.mktime(time.gmtime())
>>> year_ago = ts - (86400 * 365)
>>> time.gmtime(year_ago * 1000) # misinterpret milliseconds as seconds
time.struct_time(tm_year=45395, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=190, tm_isdst=0)
You'd have to have a timestamp early in 1970before you could confuse the two ranges:
在混淆这两个范围之前,您必须在 1970 年初有一个时间戳:
>>> now = time.mktime(time.gmtime())
>>> time.gmtime(ts / 1000) # misinterpret seconds as milliseconds
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=17, tm_hour=5, tm_min=25, tm_sec=13, tm_wday=5, tm_yday=17, tm_isdst=0)
E.g. timestamps in the first 17 days after the UNIX epoch could be confused for timestamps in milliseconds. Everything afterthat date is going to be larger than a 'current time' timestamp.
例如,UNIX 时代后前 17 天的时间戳可能会与以毫秒为单位的时间戳混淆。该日期之后的所有内容都将大于“当前时间”时间戳。
With your specific constraints, you are lucky that we can keep the two units separate so easily. The better optionis to not get into this situation in the first place. This data was sourced from somewhere; determine as early as possiblewhat data type you have instead of having to guess later. No system will randomly give you timestamps in seconds some of the time, timestamps in milliseconds the rest of the time. Surely you can know based on other information what type of data you are sourcing and either convert at that time or annotate your data to include the type?
根据您的特定限制,您很幸运,我们可以轻松地将两个单元分开。该更好的选择是不要陷入这种局面摆在首位。这些数据来自某个地方;尽早确定您拥有的数据类型,而不必事后猜测。没有系统会在某些时候随机给你以秒为单位的时间戳,在其他时间以毫秒为单位的时间戳。当然,您可以根据其他信息知道您正在采购什么类型的数据,并在当时转换或注释您的数据以包含该类型?
回答by Floris
At the risk of attracting downvotes, I want to go on record as saying DON'T DO IT.
冒着吸引反对票的风险,我想公开说不要这样做。
Making assumptions about the units of a physical quantity is a terrible idea - it led to the destruction of the Mars Meteorological Orbiter(the calculated units of thrust were in pounds, the engines expected Newtons. Not enough thrust - and the orbiter burnt up in the atmosphere).
对物理量的单位进行假设是一个可怕的想法 - 它导致火星气象轨道器的破坏(推力的计算单位以磅为单位,发动机预期为牛顿。推力不足 - 并且轨道器在大气层)。
If you have a pretty good idea of the magnitude of a number, you ought to be able to make an "educated guess" at the units. For example, if I tell you my weight is 230, you could look at me and think "I bet that is pounds, not kilos". Similarly, if you convert a time stamp of my birthday to a date on the assumption it was in seconds, and it turns out to be 200 years in the future, you can reasonably assume that "seconds" was the wrong unit.
如果您对数字的大小有一个很好的了解,您应该能够对单位进行“有根据的猜测”。例如,如果我告诉你我的体重是 230,你可以看着我想“我打赌这是磅,而不是公斤”。类似地,如果您假设我生日的时间戳以秒为单位转换为日期,而结果是未来 200 年,您可以合理地假设“秒”是错误的单位。
But it is a DANGEROUS thing to do.
但这是一件危险的事情。
Still - if you have to do it, then in general, I would recommend the following approach:
尽管如此 - 如果你必须这样做,那么总的来说,我会推荐以下方法:
- Given all the possible units, make the conversion to a "sensible" scale (for example, convert your time stamp to a year/month/day).
- Look at the values you obtained. Which of these is "most likely". In the case of dates, you might have a good idea (date this computer came into service: was it 1970 or 2012? etc)
- Choose the value that is most likely
- Record somewherethat this is what you did - so that if the consequences of this decision turn out to be wrong, you can trace the error
- 给定所有可能的单位,将转换为“合理”的比例(例如,将时间戳转换为年/月/日)。
- 查看您获得的值。其中哪些是“最有可能的”。在日期的情况下,您可能有一个好主意(这台计算机投入使用的日期:是 1970 年还是 2012 年?等)
- 选择最有可能的值
- 在某处记录这就是你所做的——这样如果这个决定的结果是错误的,你就可以追踪错误
That last thing is important - it will allow you to learn from your mistake. For example, if your time stamp tells you something about when the comet will next appear, you could print
最后一件事很重要——它会让你从错误中吸取教训。例如,如果您的时间戳告诉您有关彗星下一次出现的时间,您可以打印
Comet's next expected appearance: December 29, 2546 (assumption: time stamp from X was given in seconds)
彗星的下一次预计出现时间:2546 年 12 月 29 日(假设:X 的时间戳以秒为单位给出)
In this way, there is some "come back". In general, "document your assumptions" is not just good advice - it is essential in any exact science.
这样,就有了一些“回来”。一般来说,“记录你的假设”不仅仅是好的建议——它在任何精确的科学中都是必不可少的。
Finally - the conversion of a time stamp from ms to s is achieved by dividing the number by 1000. But I'm sure you know that.
最后 - 时间戳从 ms 到 s 的转换是通过将数字除以 1000 来实现的。但我相信您知道这一点。
回答by vlyubin
An alternative to the answer given by Martin:
马丁给出的答案的替代方案:
We've encountered this problem when we had to unify timestamps for documents coming in from 3rd parties. While the previous condition was:
当我们必须统一来自 3rd 方的文档的时间戳时,我们遇到了这个问题。而之前的条件是:
if date > time.time():
use_miliseconds(date)
else:
use_seconds(date)
, and it seems like it should work, there are edge cases, especially if date
was derived from a string representation without timezone info, or the clocks are being changed.
,看起来它应该可以工作,但存在边缘情况,特别是如果date
是从没有时区信息的字符串表示派生出来的,或者时钟正在更改。
A safer variant would be to use:
更安全的变体是使用:
if date > time.time() + HUNDRED_YEARS:
use_miliseconds(date)
else:
use_seconds(date)
, where HUNDRED_YEARS = 365 * 24 * 3600
. This condition is much more error prone, in fact, it works for any date except January and February 1970 (which are ambiguous either way).
,哪里HUNDRED_YEARS = 365 * 24 * 3600
。这种情况更容易出错,事实上,它适用于除 1970 年 1 月和 2 月以外的任何日期(无论哪种方式都不明确)。