I have time = '2020-06-24T13:30:00-04:00'. How can I change it to a dateTime object in UTC time. I would prefer not to use pd.Timestamp(time).tz_convert("UTC").to_pydatetime() because it returns a weird output that would look like this datetime.datetime(2020, 6, 24, 17, 30, tzinfo=<UTC>). As a result, when I check for equality with datetime.datetime(2020, 6, 24, 17, 30), it return False.
Edit:
import datetime
import pytz
time = '2020-06-24T13:30:00-04:00
dt = datetime.datetime(2020, 6, 24, 17, 30)
print("dt: ",dt)
so = datetime.datetime.strptime(time, '%Y-%m-%dT%H:%M:%S%z').astimezone(pytz.utc)
print("so:",so)
print(dt == so)
outputs
dt: 2020-06-24 17:30:00
so: 2020-06-24 17:30:00+00:00
False
How can I get it to properly evaluate to True?
#1 Since your string is ISO 8601 compatible, use fromisoformat() on Python 3.7+:
from datetime import datetime, timezone
s = '2020-06-24T13:30:00-04:00'
dtobj = datetime.fromisoformat(s)
# dtobj
# datetime.datetime(2020, 6, 24, 13, 30, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
Note that this will give you a timezone-aware datetime object; the tzinfo property is a UTC offset. You can easily convert that to UTC using astimezone():
dtobj_utc = dtobj.astimezone(timezone.utc)
# dtobj_utc
# datetime.datetime(2020, 6, 24, 17, 30, tzinfo=datetime.timezone.utc)
#2 You can achieve the same with strptime (also Python3.7+ according to this):
dtobj = datetime.strptime(s, '%Y-%m-%dT%H:%M:%S%z')
dtobj_utc = dtobj.astimezone(timezone.utc)
# dtobj_utc
# datetime.datetime(2020, 6, 24, 17, 30, tzinfo=datetime.timezone.utc)
#3 If you want to turn the result into a naive datetime object, i.e. remove the tzinfo property, replace with None:
dtobj_utc_naive = dtobj_utc.replace(tzinfo=None)
# dtobj_utc_naive
# datetime.datetime(2020, 6, 24, 17, 30)
#4 For older Python versions, you should be able to use dateutil's parser:
from dateutil import parser
dtobj = parser.parse(s)
dtobj_utc = dtobj.astimezone(timezone.utc)
dtobj_utc_naive = dtobj_utc.replace(tzinfo=None)
# dtobj_utc_naive
# datetime.datetime(2020, 6, 24, 17, 30)
Alright so my previous answer was sort of wack because I did not understand your issue entirely so I am rewriting it. You problem is that you are constructing a datetime object from a string and it is timezone aware(UTC). However, whenever you make a datetime object in python, dt = datetime.datetime(2020, 6, 24, 17, 30), it is creating it but with no timezone information (which you can check using .tzinfo on it). All you would need to do is make dt timezone aware when you first create it. See below my code snippit.
import datetime
time = '2020-06-24T13:30:00-04:00'
dt = datetime.datetime(2020, 6, 24, 17, 30, tzinfo=datetime.timezone.utc)
print("dt: ",dt.tzinfo)
so = datetime.datetime.strptime(time, '%Y-%m-%dT%H:%M:%S%z')
print("so:",so.tzinfo)
print(dt == so)
Related
I am working on a project where I have to find the next 10 trains departing from a station. Below is the api where in I will get the trains data and the time of departure is specified in UTC-04:00 format.
https://api-v3.mbta.com/predictions?filter%5Bstop%5D=place-pktrm&include=route&sort=departure_time
For this I have to compare the current time with departure time and have to find the time difference.
Below is the approach I used to get the time difference but not sure if it is correct. I am new to this and please help me.
>>> from datetime import datetime,timezone
#departure time of train in 'UTC-04:00'
>>> time = "2021-08-21T13:17:47-04:00"
#converting to datetime object with tzinfo
>>> actual_time = datetime.fromisoformat(time)
>>> actual_time
datetime.datetime(2021, 8, 21, 13, 17, 47, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
#saving the datetime object representing the current utc time
>>> utc_time = datetime.now(timezone.utc)
>>> utc_time
datetime.datetime(2021, 8, 21, 20, 18, 32, 694983, tzinfo=datetime.timezone.utc)
#converting datetime object with departure time to local time zone
>>> actual_time_in_local_timezone = actual_time.astimezone(tz=None)
>>> actual_time_in_local_timezone
datetime.datetime(2021, 8, 21, 22, 47, 47, tzinfo=datetime.timezone(datetime.timedelta(seconds=19800), 'India Standard Time'))
#converting datetime object with current UTC time to local time zone
>>> utc_time_in_local_timezone = utc_time.astimezone(tz=None)
>>> utc_time_in_local_timezone
datetime.datetime(2021, 8, 22, 1, 48, 32, 694983, tzinfo=datetime.timezone(datetime.timedelta(seconds=19800), 'India Standard Time'))
#total seconds difference between both the times
>>> total_seconds_difference = (actual_time_in_local_timezone - utc_time_in_local_timezone).total_seconds()
>>> total_seconds_difference
-10845.694983
I get two type of timestamp (one with millisecond and another one without it)
'endtime': '2020-09-09T05:46:41.620Z'
'starttime': '2020-09-08T18:20:57Z'
I have to specify the format to convert it into datetime
timestampstart = pd.to_datetime(starttime, format="%Y-%m-%dT%H:%M:%S%fZ")
is there a way to generalize "format" in this line, because if my time has millisecond, the code will crash.
how can rewrite this to always ignore millisecond without getting my code crashed?
Both formats are ISO8601 compliant. You can parse the timestamps conveniently using datetime.fromisoformat after you replace the 'Z' character (which denotes UTC) with '+00:00' (also UTC). You can find this method also here.
from datetime import datetime
endtime = '2020-09-09T05:46:41.620Z'
starttime = '2020-09-08T18:20:57Z'
for t in (endtime, starttime):
print(repr(datetime.fromisoformat(t.replace('Z', '+00:00'))))
# datetime.datetime(2020, 9, 9, 5, 46, 41, 620000, tzinfo=datetime.timezone.utc)
# datetime.datetime(2020, 9, 8, 18, 20, 57, tzinfo=datetime.timezone.utc)
To set all microseconds to zero you can write
# setting microseconds to zero:
for t in (endtime, starttime):
print(repr(datetime.fromisoformat(t.replace('Z', '+00:00')).replace(microsecond=0)))
# datetime.datetime(2020, 9, 9, 5, 46, 41, tzinfo=datetime.timezone.utc)
# datetime.datetime(2020, 9, 8, 18, 20, 57, tzinfo=datetime.timezone.utc)
I am trying to convert from GMT to e.g SGT:
For example, the value
0348 GMT should be 11:48 am
1059 GMT should be 6:59 pm
how do i do this?
i have tried:
date="03:48"
curr = (
dt.datetime.strptime(date, "%H:%M")
.astimezone(timezone('Asia/Singapore'))
)
print(curr)
But I am getting OSError: [Errno 22] Invalid argument
Assuming you have a naive datetime object which represents UTC:
from datetime import datetime, timezone
from dateutil import tz
now = datetime.now()
print(repr(now))
>>> datetime.datetime(2020, 7, 28, 8, 5, 42, 553781)
Make sure to set the tzinfo property to UTC using replace:
now_utc_aware = now.replace(tzinfo=timezone.utc)
print(repr(now_utc_aware))
>>> datetime.datetime(2020, 7, 28, 8, 5, 42, 553781, tzinfo=datetime.timezone.utc)
Now you can convert to another timezone using astimezone:
now_sgt = now_utc_aware.astimezone(tz.gettz('Asia/Singapore'))
print(repr(now_sgt))
>>> datetime.datetime(2020, 7, 28, 16, 5, 42, 553781, tzinfo=tzfile('Singapore'))
Sidenote, referring to your other question, if you parse correctly, you already get an aware datetime object:
date = "2020-07-27T16:38:20Z"
dtobj = datetime.fromisoformat(date.replace('Z', '+00:00'))
print(repr(dtobj))
>>> datetime.datetime(2020, 7, 27, 16, 38, 20, tzinfo=datetime.timezone.utc)
I have tried a number of posts/suggestions on here on converting time zone objects and have failed. I hope someone can point me to an easy way to do this.
I have a string/datetime of 2017-05-11T16:24:56-04:00
I can parse it a number of ways, dateutil, etc, into a datetime object.
when printed i get
datetime.datetime(2017, 5, 11, 16, 24, 56, tzinfo=tzoffset(None, -14400))
so it gets a tzoffset.
Trying any conversion doesn't seem to update the actual time portion, just the zone information.
How do I convert this string to my local time zone (EST, or offset -5hrs).
edit: trying astimezone() gets me this:
dt.astimezone()
Out[18]: datetime.datetime(2017, 5, 11, 16, 24, 56,
tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
Thanks!
When you convert it using tzinfo you only change the suffix of the output string (e.g. with tzutc()): 2017-05-11 16:24:56+00:00
If you want to print it in your time zone, first create the datetime object using the actual timezone it represents:
dt = datetime(2017, 5, 11, 16, 24, 56,
tzinfo=tzoffset(None, -18000))
# 2017-05-11 16:24:56-05:00
And then convert it to the desired timezone using:
mydt = dt.astimezone(tzutc())
# 2017-05-11 21:24:56+00:00
How can I change a timezone in a datetimefield.
right now I have
datetime.datetime(2013, 7, 16, 4, 30, tzinfo=<UTC>)
how can modify the tzinfo just for display not to update on the db.
Use pytz for such things.
From the pytz docs, you can use astimezone() to transform time into different time zone, as example below.
>>> eastern = timezone('US/Eastern')
>>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
>>> loc_dt = utc_dt.astimezone(eastern)
>>> loc_dt.strftime(fmt)
'2002-10-27 01:00:00 EST-0500'