How to test if a given time-stamp is in seconds or milliseconds?

后端 未结 4 461
青春惊慌失措
青春惊慌失措 2021-02-03 19:45

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 i

相关标签:
4条回答
  • 2021-02-03 20:12

    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:

    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.

    A safer variant would be to use:

    if date > time.time() + HUNDRED_YEARS:
        use_miliseconds(date)
    else:
        use_seconds(date)
    

    , where HUNDRED_YEARS = 100 * 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).

    0 讨论(0)
  • 2021-02-03 20:13

    If you convert the maximum timestamp values with x digits in millis you get something like this:

    • 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

    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:

    • 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 :)

    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:

    • 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
    0 讨论(0)
  • 2021-02-03 20:13

    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.

    But it is a DANGEROUS thing to do.

    Still - if you have to do it, then in general, I would recommend the following approach:

    1. Given all the possible units, make the conversion to a "sensible" scale (for example, convert your time stamp to a year/month/day).
    2. 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)
    3. Choose the value that is most likely
    4. Record somewhere that this is what you did - so that if the consequences of this decision turn out to be wrong, you can trace the error

    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)

    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.

    0 讨论(0)
  • 2021-02-03 20:21

    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.

    That's because even a timestamp in milliseconds representing one year in the past, accidentally interpreted as a timestamp in seconds, would lie far into 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 1970 before you could confuse the two ranges:

    >>> 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 after that date is going to be larger than a 'current time' timestamp.

    With your specific constraints, you are lucky that we can keep the two units separate so easily. The better option is to not get into this situation in the first place. This data was sourced from somewhere; determine as early as possible what 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?

    0 讨论(0)
提交回复
热议问题