I'm given a timestamp in seconds, and I 'inherited' a function to print it in human-readable form, but the function is locale-specific; that is, it matters what time zone the host is configured for. I want to print that time as GMT no matter what time zone I'm in. For example, here's the sequence on a computer in Mountain Time (the value 315878400 is a 'magic number'):
>>> import time
>>> secs = 1308512779
>>> tmp = secs + 315878400
>>> print(time.ctime(tmp))
Tue Jun 22 13:46:19 2021
And here it is on a computer in Pacific Time:
>>> import time
>>> secs = 1308512779
>>> tmp = secs + 315878400
>>> print(time.ctime(tmp))
Tue Jun 22 12:46:19 2021
Given the same time in seconds I'd like to run the same code anywhere and get the same string for output. Since I don't control the source of the seconds data itself, it's acceptable to assume it's GMT. Everything I find on the Web is about how to get my local time now, and that's not what this is about. Any help would be appreciated.
It sounds like you are describing Unix time. Python makes it very easy to get datetime objects from Unix time!
from datetime import datetime
def convert(timestamp):
return datetime.utcfromtimestamp(timestamp)
print(convert(1308512779))
# prints: 2011-06-19 19:46:19
Related
I'm new to Python and I cannot for the life of me find my specific answer online. I need to format a timestamp to this exact format to include 'T', 'Z' and no sub or miliseconds like this yyyy-mm-ddThh:mm:ssZ i.e. 2019-03-06T11:22:00Z. There's lots of stuff on parsing this format but nothing about formatting this way. The only way I have nearly got it to work involves sub-seconds which I do not need. I've tried using arrow and reading their documentation but unable to get anything to work. Any help would be appreciated.
Try datetime library
import datetime
output_date = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
print(output_date)
For more information, refer to the Python Documentation.
Be careful. Just be cause a date can be formatted to look like UTC, doesn't mean it's accurate.
In ISO 8601, 'Z' is meant to designate "zulu time" or UTC ('+00:00'). While local times are typically designated by their offset from UTC. Even worse, these offsets can change throughout a year due to Daylight Saving Time (DST).
So unless you live in England in the winter or Iceland in the summer, chances are, you aren't lucky enough to be working with UTC locally, and your timestamps will be completely wrong.
Python3.8
from datetime import datetime, timezone
# a naive datetime representing local time
naive_dt = datetime.now()
# incorrect, local (MST) time made to look like UTC (very, very bad)
>>> naive_dt.strftime("%Y-%m-%dT%H:%M:%SZ")
'2020-08-27T20:57:54Z' # actual UTC == '2020-08-28T02:57:54Z'
# so we'll need an aware datetime (taking your timezone into consideration)
# NOTE: I imagine this works with DST, but I haven't verified
aware_dt = naive_dt.astimezone()
# correct, ISO-8601 (but not UTC)
>>> aware_dt.isoformat(timespec='seconds')
'2020-08-27T20:57:54-06:00'
# lets get the time in UTC
utc_dt = aware_dt.astimezone(timezone.utc)
# correct, ISO-8601 and UTC (but not in UTC format)
>>> utc_dt.isoformat(timespec='seconds')
'2020-08-28T02:57:54+00:00'
# correct, UTC format (this is what you asked for)
>>> date_str = utc_dt.isoformat(timespec='seconds')
>>> date_str.replace('+00:00', 'Z')
'2020-08-28T02:57:54Z'
# Perfect UTC format
>>> date_str = utc_dt.isoformat(timespec='milliseconds')
>>> date_str.replace('+00:00', 'Z')
'2020-08-28T02:57:54.640Z'
I just wanted to illustrate some things above, there are much simpler ways:
from datetime import datetime, timezone
def utcformat(dt, timespec='milliseconds'):
"""convert datetime to string in UTC format (YYYY-mm-ddTHH:MM:SS.mmmZ)"""
iso_str = dt.astimezone(timezone.utc).isoformat('T', timespec)
return iso_str.replace('+00:00', 'Z')
def fromutcformat(utc_str, tz=None):
iso_str = utc_str.replace('Z', '+00:00')
return datetime.fromisoformat(iso_str).astimezone(tz)
now = datetime.now(tz=timezone.utc)
# default with milliseconds ('2020-08-28T02:57:54.640Z')
print(utcformat(now))
# without milliseconds ('2020-08-28T02:57:54Z')
print(utcformat(now, timespec='seconds'))
>>> utc_str1 = '2020-08-28T04:35:35.455Z'
>>> dt = fromutcformat(utc_string)
>>> utc_str2 = utcformat(dt)
>>> utc_str1 == utc_str2
True
# it even converts naive local datetimes correctly (as of Python 3.8)
>>> now = datetime.now()
>>> utc_string = utcformat(now)
>>> converted = fromutcformat(utc_string)
>>> now.astimezone() - converted
timedelta(microseconds=997)
Thanks to skaul05 I managed to get the code I needed, it's
date = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
print(date)
With f strings, you can shorten it down to:
from datetime import datetime
f'{datetime.now():%Y-%m-%dT%H:%M:%SZ}'
Credits go to How do I turn a python datetime into a string, with readable format date?.
I am using sunrise-sunset api to get sunrise and sunset for day.
>>> url = "https://api.sunrise-sunset.org/json?lat=36.7201600&lng=-4.4203400&date=2017-07-31"
>>> import urllib2
>>> import json
>>> resp = urllib2.urlopen(url)
>>> data = json.load(resp)
>>> sunriseUtc = data.get("results").get("sunrise")
>>> sunriseUtc
u'5:23:18 AM'
I want to convert this UTC time to local time of that of Long, Lat passed in the URL. i.e. not user local.
Any help would be greatly appreciated.
Rather than using a web query you might be better off using pyephem, it is pip install pyephem able and will give you the sunrise/set times, (and a lot more), for a given location, (lat/long), based on physical values.
>>> import ephem
>>> sun = ephem.Sun()
>>> greenwich = ephem.Observer()
>>> greenwich.lat = '51:28:38'
>>> print(greenwich.horizon)
0:00:00.0
>>> greenwich.date = '2007/10/1'
>>> r1 = greenwich.next_rising(sun)
>>> greenwich.pressure = 0
>>> greenwich.horizon = '-0:34'
>>> greenwich.date = '2007/10/1'
>>> r2 = greenwich.next_rising(sun)
>>> print('Visual sunrise: %s' % r1)
Visual sunrise: 2007/10/1 05:59:30
>>> print('Naval Observatory sunrise: %s' % r2)
Naval Observatory sunrise: 2007/10/1 05:59:50
Using Python 3.8:
To Begin add the following modules below:
import time
from time import localtime
Next, call on the localtime() method and insert your time (in this case, variable "sunriseUtc"):
localtime(sunriseUtc).
That's it.
If you would like to format the time (how it is presented) you will need to import strftime (abbreviated for string format time) from the time module. Then set up the format for your time. Then pass the same argument from above:
e.g.
from time import strftime
strftime("%m/%d/%Y %I:%M:%S %p", localtime(sunriseUtc))
'05/12/2019 05:57:05 AM'
This worked for me when using the requests module to download data from the openweathermap.org's API.
If you need more support, see time module's documentation:
https://docs.python.org/2/library/time.html#time.strftime
Note: My project was built on the example from "Project: Fetching Current Weather Data" found here:
https://automatetheboringstuff.com/chapter14/
pythondatetime-conversion
I'd like to round down/floor an epoch/Unix timestamp so as to remove the seconds.
I'm using Python 2.x and Python 3.x
E.g.
1488728901 = Sun, 05 Mar 2017 15:48:21 GMT
to:
1488728880 = Sun, 05 Mar 2017 15:48:00 GMT
There's some great answers by using datetime to manipulate the time but it seems OTT if my input and output are integers.
A simple bit of maths:
int(timestamp//60 * 60)
(// replicates Python 2.x division (/) where the result is a whole number)
Or if you're not clever you could use arrow:
>>> import arrow
>>> timestamp = arrow.get(1488728901)
>>> timestamp
<Arrow [2017-03-05T15:48:21+00:00]>
>>> timestamp = timestamp.floor('minute')
>>> timestamp.format('YYYY-MMM-DD HH:mm:ss')
'2017-Mar-05 15:48:00'
you can do one thing here lets suppose col has your unix value. modified_value=((col+30*1000)/60*1000).cast("long") -- it will be decimal or integer covert it into proper integer if
modified_value_final = modified_value*60*1000
Example val=1488728901
modifeid_value=(1488728901+30000)/60000 = 24,812.64835
modified_value = 24,812 --after casting to long
final_modified_value = 24812*60000=1,488,720,000
I noticed time.mktime(.timetuple()) returned different time on mac and linux(ubuntu). Why this?
date = ['2016-07-01', '2016-07-05']
xdata = [datetime.datetime.strptime(str(s), "%Y-%m-%d") for s in date]
xdata = [time.mktime(s.timetuple()) * 1000 for s in xdata]
print xdata
# ----mac--
>> [1467356400000.0, 1467702000000.0]
#-----linux---
>> [1467345600000.0, 1467691200000.0]
How to return in UTC?
I marked to close this as a duplicate, but it's really not if you're viewing your original inputs as being in UTC to begin with. If you are (it's not wholly clear), then just replace your time.mktime with calendar.timegm.
>>> d = datetime.datetime(2016, 9, 1)
>>> calendar.timegm(d.timetuple())
1472688000
Or you can do it all yourself:
>>> EPOCH = datetime.datetime(1970, 1, 1)
>>> def dt2utcstamp(d):
... return (d - EPOCH).total_seconds()
and then:
>>> dt2utcstamp(d)
1472688000.0
I generally do the latter, because I find it next to impossible to remember what all the goofy time-and-date functions do ;-) But the timedelta.total_seconds() method doesn't exist before Python 3.2.
Or if you do view the inputs as being in local time, then the other answers apply:
How do I convert local time to UTC in Python?
NOTE
When you ask "How to return in UTC?", you have to realize that your original code already did that: timestamps are always viewed as being seconds from the epoch in UTC. Indeed, that's why you got different results on platforms set to different time zones to begin with: '2016-07-01'(with implied time 00:00:00) is a different real-world instant depending on which time zone it's viewed as being in.
The s.timetuple() part doesn't care about that, but it's a primary purpose of the time.mktime() part to convert the local time to a UTC timestamp.
Any links for me to convert datetime to filetime using python?
Example: 13 Apr 2011 07:21:01.0874 (UTC) FILETIME=[57D8C920:01CBF9AB]
Got the above from an email header.
My answer in duplicated question got deleted, so I'll post here:
Surfing around i found this link: http://cboard.cprogramming.com/windows-programming/85330-hex-time-filetime.html
After that, everything become simple:
>>> ft = "57D8C920:01CBF9AB"
... # switch parts
... h2, h1 = [int(h, base=16) for h in ft.split(':')]
... # rebuild
... ft_dec = struct.unpack('>Q', struct.pack('>LL', h1, h2))[0]
... ft_dec
... 129471528618740000L
... # use function from iceaway's comment
... print filetime_to_dt(ft_dec)
2011-04-13 07:21:01
Tuning it up is up for you.
Well here is the solution I end up with
parm3=0x57D8C920; parm3=0x01CBF9AB
#Int32x32To64
ft_dec = struct.unpack('>Q', struct.pack('>LL', parm4, parm3))[0]
from datetime import datetime
EPOCH_AS_FILETIME = 116444736000000000; HUNDREDS_OF_NANOSECONDS = 10000000
dt = datetime.fromtimestamp((ft_dec - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS)
print dt
Output will be:
2011-04-13 09:21:01 (GMT +1)
13 Apr 2011 07:21:01.0874 (UTC)
base on David Buxton 'filetimes.py'
^-Note that theres a difference in the hours
Well I changes two things:
fromtimestamp() fits somehow better than *UTC*fromtimestamp() since I'm dealing with file times here.
FAT time resolution is 2 seconds so I don't care about the 100ns rest that might fall apart.
(Well actually since resolution is 2 seconds normally there be no rest when dividing HUNDREDS_OF_NANOSECONDS )
... and beside the order of parameter passing pay attention that struct.pack('>LL' is for unsigned 32bit Int's!
If you've signed int's simply change it to struct.pack('>ll' for signed 32bit Int's!
(or click the struct.pack link above for more info)