1

I have the string "20150219-0700" to represent a time. I want to get the timestamp of this value in milliseconds. What I did was:

extracted_ts = "20150219-0700"

int_ts = int(datetime.datetime.strptime(extracted_ts, "%Y%m%d-%H%M").timestamp()) * 1000

However the output is 1424358000000. It is behind by 4 hours

The correct output should be 1424329200000

Liondancer
  • 15,721
  • 51
  • 149
  • 255

3 Answers3

2

The timestamp method adjusts the time from your current time zone to UTC. If that's not what you want, you can convert it manually using the formula from the timestamp documentation:

int_ts = int((datetime.datetime.strptime(extracted_ts, "%Y%m%d-%H%M") - datetime.datetime(1970,1,1)).total_seconds()) * 1000
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • it fails if the input is not in UTC and there is not enough info in the question to determine the timezone with certainty. Also, `int(diff.total_seconds())*1000` might lose precision in the general case. See [how both issues are handled in my answer](http://stackoverflow.com/a/28779031/4279) – jfs Feb 28 '15 at 06:57
2

Since you are using python3, how about:

from datetime import datetime, timezone
s = "20150219-0700"
d = datetime.strptime(s, "%Y%m%d-%H%M").replace(tzinfo=timezone.utc)
print(int(d.timestamp() * 1000))

Output:

1424329200000
JuniorCompressor
  • 19,631
  • 4
  • 30
  • 57
  • it fails if the input is not in UTC and there is not enough info in the question to determine the timezone with certainty. Also, `int(d.timestamp()*1000)` might lose precision in the general case. See [how both issues are handled in my answer](http://stackoverflow.com/a/28779031/4279) – jfs Feb 28 '15 at 06:59
  • @J.F.Sebastian they were pretty clear on what their expected result was, and already had a method that accounted for time zone. – Mark Ransom Feb 28 '15 at 13:31
  • @MarkRansom: there are other timezones apart from local and UTC (especially in the application domain where Python is used, [example](http://stackoverflow.com/q/28775650/4279)). Read [my answer](http://stackoverflow.com/a/28779031/4279). What do you think is the expected output for "20150619-0700"? Why? – jfs Feb 28 '15 at 13:38
2

You get the correct timestamp if you interpret the input time string as time in UTC.

Note: that conclusion is based only on ("20150219-0700", 1424329200000) pair that is consistent with UTC but it is not enough in general case e.g., you get the exact same result if the input time string is in Europe/London timezone (GMT+0000) that has zero utc offset now but in the summer it is one hour 'BST+0100' i.e., your code will be wrong by one hour for "20150619-0700" if the input is 'Europe/London' and not in UTC.

You have to know the input timezone to convert the time into POSIX timestamp:

#!/usr/bin/env python3
from datetime import datetime, timedelta
import pytz # $ pip install pytz

Epoch = datetime(1970, 1, 1, tzinfo=pytz.utc)
tz = pytz.timezone('Europe/London') # input timezone

naive_dt = datetime.strptime("20150219-0700", "%Y%m%d-%H%M")
dt = tz.localize(naive_dt, is_dst=None) # make it aware
timestamp_millis = (dt - Epoch) // timedelta(milliseconds=1)
# -> 1424329200000

Note: the latter expression might give more precise result than int(dt.timestamp()*1000) or int(diff.total_seconds()*1000) formulae. See the discussion in Python issue: timedelta.total_seconds needlessly inaccurate, especially for negative timedeltas e.g., "n/10**6 and n/1e6 aren't the same thing".

If you are sure that the input timezone is UTC then you could leave the input as naive datetime objects:

#!/usr/bin/env python3
from datetime import datetime

Epoch = datetime(1970, 1, 1)
utc_dt = datetime.strptime("20150219-0700", "%Y%m%d-%H%M")
timestamp_millis = (utc_dt - Epoch) // timedelta(milliseconds=1)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • I think it's safe to assume that OP wanted a UTC timestamp – JuniorCompressor Feb 28 '15 at 08:20
  • @JuniorCompressor: it is. There is a difference between "seconds since epoch" (what `time.time()` returns) and "seconds since Epoch" (POSIX time) if `time.time()` uses `"right"` timezones but it is rare. People who say UTC timestamp actually mean POSIX time. – jfs Feb 28 '15 at 08:20
  • @JuniorCompressor: Or are you talking about *input*? If it is then as I said there is not enough evidence for *"it's safe to assume"* that input is in UTC as I've shown above the input may be in Europe/London as well. – jfs Feb 28 '15 at 08:29
  • As I understood it, the input was in in UTC. But you are right, the OP should have clarified the wanted timezone. – JuniorCompressor Feb 28 '15 at 08:40