This question already has answers here:
How to convert a UTC datetime to a local datetime using only standard library?
(14 answers)
Closed 2 years ago.
I have time since epoch and I am converting it to datetime.
import datetime
s = '1346114717'
t = datetime.datetime.fromtimestamp(float(s))
is this correct? t is in which timezone? How can I convert it to PST/PDT
Assuming your string represents Unix time / seconds since 1970-1-1, it refers to UTC. You can convert it to datetime like
from datetime import datetime, timezone
s = '1346114717'
dt = datetime.fromtimestamp(int(s), tz=timezone.utc)
print(dt.isoformat())
# 2012-08-28T00:45:17+00:00
Note that if you don't supply a time zone, the resulting datetime object will be naive, i.e. does not "know" of a time zone. Python will treat it as local time by default (your machine's OS setting).
To convert to US/Pacific time, you can use zoneinfo from Python 3.9's standard lib:
from zoneinfo import ZoneInfo
dt_pacific = dt.astimezone(ZoneInfo('US/Pacific'))
print(dt_pacific.isoformat())
# 2012-08-27T17:45:17-07:00
or use dateutil with older versions of Python:
from dateutil.tz import gettz # pip install python-dateutil
dt_pacific = dt.astimezone(gettz('US/Pacific'))
print(dt_pacific.isoformat())
# 2012-08-27T17:45:17-07:00
python datetime is by default time zone unaware(it doesnt have any timezone information). u could make it aware by using pytz. but i would suggest u take a look at a library like arrow which makes things easier.
Related
This question already has answers here:
Convert zulu time string to MST datetime object
(2 answers)
How do I parse an ISO 8601-formatted date?
(29 answers)
Closed 1 year ago.
I know this question has been asked in different forms, but I'm not finding what I need. I'm looking for a way to convert the following date / time to my local time zone using Python. Note the time zone of "Z" and the "T" between the date and time, this is what's throwing me off.
"startTime": "2021-03-01T21:21:00.652064Z"
the datetime module is your friend. You seem to be dealing with a date-time stamp in ISO format. The datetime module has a class method to generate a datetime object from an ISO formatted string.
from datetime import datetime
dateinput = "2021-03-01T21:21:00.652064Z"
stamp = datetime.fromisoformat(dateinput)
But here you will get an error because the trailing 'Z' is not quite right. If you know that it's always going to be there, just lop off the last character. Otherwise you might have to do some string manipulation first.
stamp = datetime.fromisoformat(dateinput[:-1])
See also the strptime() class method to get datetime objects from arbitrarily formatted strings.
Hoping this helps...
datetime and pytz modules! Also depends on what you need, but below is the date and time object without the miliseconds part and a simple conversion to Berlin timezone.
import datetime
from pytz import timezone
berlin_timezone = pytz.timezone('Europe/Berlin')
your_time = datetime.datetime.strptime(startTime.split(".")[0], "%Y-%m-%dT%H:%M:%S")
your_time_utc = your_time.astimezone(berlin_timezone)
This question already has answers here:
Python datetime object show wrong timezone offset
(2 answers)
Closed 5 years ago.
Converting a timezone naive date time to a specific timezone gives a completely incorrect result.
import dateutil as du
import pytz
du.parser.parse('2017-05-31T15:00:00').replace(tzinfo=pytz.timezone('Europe/London')).isoformat()
returns a one minute not one hour offset vs UTC
'2017-05-31T15:00:00-00:01'
I've seen a few datetime peculiarities before but this one is breathtaking.
The main problem here is that you are using a pytz time zone. pytz zones do not follow the tzinfo interface and cannot be simply attached to datetime objects (either through the constructor or through replace). If you would like to use pytz time zones, you should use pytz.timezone.localize with a naive datetime. If the datetime is already timezone-aware, you can use datetime.astimezone to convert it between zones.
from dateutil import parser
import pytz
LON = pytz.timezone('Europe/London')
dt = parser.parse('2017-05-31T15:00:00')
dt = LON.localize(dt)
print(dt) # 2017-05-31 15:00:00+01:00
This is because pytz's interface uses localize to attach a static time zone to a datetime. For the same reason, if you do arithmetic on the now-localized datetime object, it may give similar improper results and you'll have to use pytz.timezone.normalize to fix it. The reason this is done this way is that, historically, it has not been possible to handle ambiguous datetimes using a Pythonic tzinfo interface, which changed with PEP 495 in Python 3.6, making pytz's workaround less necessary.
If you would like to pass a tzinfo to a datetime using replace or the constructor, or you would prefer to use the pythonic interface, dateutil's time zone suite implements a PEP 495-compliant tzinfo interface. The equivalent using a dateutil zone is:
from dateutil import parser
from dateutil import tz
LON = tz.gettz('Europe/London')
dt = parser.parse('2017-05-31T15:00:00').replace(tzinfo=LON)
print(dt) # 2017-05-31 15:00:00+01:00
I have often had bad luck using replace() with tzinfo objects. I have however found this construct to be reliable:
Code:
def naive_to_aware(ts, tz):
return tz.localize(ts)
Update from Comments:
From the (pytz DOCS)
Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.
It is safe for timezones without daylight saving transitions though, such as UTC
So it is not just bad luck, it is problematic for pytz objects with timezones having DST.
Test Code:
import dateutil as du
import pytz
print(naive_to_aware(du.parser.parse('2017-05-31T15:00:00'),
pytz.timezone('Europe/London')).isoformat())
Results:
2017-05-31T15:00:00+01:00
I have been reading python's datetime documentation and it seems like there are few things which are not clearly mentioned there.
date = datetime.datetime(2014,10,1,11,45,30)
Which timezone will the above date be in? UTC?
If I have to make sure that the above date remains in EST what could be done. I am not clear on tzinfo object here?
If I have to convert these datetimes to some other time zones based on latitude and longitude what should I do?
Your code would create a "timezone naive" datetime object. That means - no timezone. It'll be interpreted as local time based on where it is used.
If you want to set a timezone, try using the pytz library.
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) # NOTE: it works only with a fixed utc offset
# Then you can change timezones, e.g. http://www.timezoneconverter.com/cgi-bin/zoneinfo?tz=America/New_York
print u.astimezone(pytz.timezone("America/New_York"))
As for the lat/lon conversion to a timezone, this isn't a simple task. Here's a question that discusses possible solutions.
This question already has answers here:
pytz localize vs datetime replace
(4 answers)
Closed 8 years ago.
Assume that I have a timezone-less datetime object:
import datetime
import pytz
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
dtUnaware = datetime.datetime(1979,2,20,6)
print(dtUnaware.strftime(fmt))
This yields:
1979-02-20 06:00:00
So far, so good. Now, I want to assign a timezone to this object. It seems like I could use either datetime.replace or pytz.localize.
First:
dtAware1 = dtUnaware.replace(tzinfo=pytz.timezone('Asia/Jerusalem'))
print(dtAware1.strftime(fmt))
returns: 1979-02-20 06:00:00 LMT+0221. Secondly:
dtAware2 = pytz.timezone('Asia/Jerusalem').localize(dtUnaware, is_dst=None)
print(dtAware2.strftime(fmt))
returns 1979-02-20 06:00:00 IST+0200.
What's wrong with the first method? It seems to assign a wrong timezone. Am I doing something wrong?
From Pytz documentation : This library differs from the documented Python API for
tzinfo implementations; if you want to create local wallclock
times you need to use the localize() method documented in this
document... Unfortunately these
issues cannot be resolved without modifying the Python datetime
implementation (see PEP-431)
My reading of that is that a pytz timezone is not exactly the same thing as a standard timezone. If you had a genuine timezone, first method should be good, but you have not.
There is a flaw in the datetime API: when you assign a timezone to it, the timezone is not given the opportunity to know the date and time it should be configured for. The historical database that pytz uses goes back a long way, often to periods when the timezone name or offset were different than the ones in use today. Without being given the chance to adjust to a specific date period, the details of the timezone may be wrong.
Using localize is the way around this problem, since both the date and timezone are available within the function at the same time.
I've used time.time() to generate timestamps across client apps. These timestamps are accumulated and sent in batches to an external and independent location.
While rendering these timestamps back on the client application I intend to use datetime.fromtimestamp(ts_from_external_source) in order to create local datetime objects, without defining the timezone so it assumes the local by default.
Is this the recommended way of doing it?
It is ok to use a naive datetime object that represents local time if you use it only for displaying the timestamp.
datetime.fromtimestamp(ts_from_external_source) should work during DST transitions (local time may be ambiguous but POSIX timestamps are not if we ignore leap seconds). Though it might fail for dates from the past/future if the local timezone had/will have different UTC offset at the time and the underlying C library does not use a historical timezone database such as the tz database (Linux, OS X use it. python on Windows -- might not).
datetime.fromtimestamp(ts_from_external_source) should be ok for recent dates in most timezones.
You could use Europe/Moscow timezone with dates from 2010-2015 for testing (the timezone rules had changed in that period).
You could provide the tz database using pytz module:
from datetime import datetime, timedelta
from tzlocal import get_localzone # $ pip install tzlocal
import pytz # $ pip install pytz
tz = get_localzone() # get the local timezone as pytz timezone (with historical data)
utc_dt = datetime(1970, 1, 1, tzinfo=pytz.utc) + timedelta(seconds=ts_from_external_source)
dt = utc_dt.astimezone(tz)
Or:
dt = datetime.fromtimestamp(ts_from_external_source, tz)
Run these tests to see whether datetime + timedelta and fromtimestamp() produce different results on your platform.
Yes that's a good way of doing it: you store "Unix epoch" style times, and convert them to whatever local time you need before displaying them.