Python strptime parse timezone format "GMT+-H" - python-3.x

I'm using python 3.7 and trying to figure out the correct format to get this code to work
dt = datetime.strptime("4 January 2022, 22:03 GMT-5", "%-d %b %Y, %H:%M %Zz")
The above line always fails. Is there something I can do to get it to parse? I am assuming its failing on the "GMT-5 part"
Edit:
Adding context, the input string is scraped from a website so I need to find a way to turn it into a python datetime object so by code can understand when the event took place. Im not really sure how I could "In Code" change the input to match the required format of strptime

%z parsing directive won't parse an hour-only UTC offset (docs: requires ±HHMM[SS[.ffffff]] form). But you can derive a timezone object from a timedelta and set it like
from datetime import datetime, timedelta, timezone
s = "4 January 2022, 22:03 GMT-5"
parts = s.split('GMT')
dt = (datetime.strptime(parts[0].strip(), "%d %B %Y, %H:%M") # parse to datetime w/o offset
.replace(tzinfo=timezone(timedelta(hours=int(parts[1]))))) # add UTC offset
print(dt)
# 2022-01-04 22:03:00-05:00

You're using the wrong format for the month and invalid text for the UTC offset (it has to be four digits, as described in the documentation):
>>> datetime.datetime.strptime("4 January 2022, 22:03 GMT-0500", "%d %B %Y, %H:%M %Z%z")
datetime.datetime(2022, 1, 4, 22, 3, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400), 'GMT'))

Related

What's a good way of converting timezone of a timestamp?

I have a string in this format: 09/20/2020 10:30 AM
That timestamp is in Eastern Timezone.
I need to obtain the UTC equivalent, but in the following ISO format: 2020-09-20T14:30:00.0000Z
I've tried a few things but there doesn't seem to be a clean/short way of converting it.
So far I've tried:
dtSept = "09/20/2020 10:00 PM"
dtSeptTZ = pytz.timezone('US/Eastern').localize(datetime.datetime.strptime(dtSept, "%m/%d/%Y %I:%M %p")).isoformat(timespec='milliseconds')
dtSeptTZ at this point is a string object.
If I have to convert its TimeZone and format it, I have to execute the following which each take a datetime object but return a string.
dtSeptTZ.astimezone(pytz.timezone('Etc/UTC'))
dtSeptTZ.strftime("%Y-%m-%dT%I:%M.%fZ")
Is there a clean/short way of getting the proper output without coverting it back and forth between string and datetime?
Many thanks.
due to the immanent deprecation of pytz, I'd suggest to use dateutil. The usage of dateutil also transforms nicely to Python 3.9's zoneinfo.
from datetime import datetime, timezone
from dateutil.tz import gettz
dtSept = "09/20/2020 10:00 PM"
# string to datetime object
dt = datetime.strptime(dtSept, "%m/%d/%Y %I:%M %p")
# set tzinfo to appropriate time zone; (!) use "localize" instead with pytz timezone class
dt = dt.replace(tzinfo=gettz('US/Eastern'))
# to UTC (could use any other tz here)
dt_utc = dt.astimezone(timezone.utc)
# to ISO format string:
print(dt_utc.isoformat())
>>> 2020-09-21T02:00:00+00:00

how to convert a column of data in GMT format to local time in python

I have to plot a column of data,but it is given in GMT format in python.I need to convert it into local time.
I tried different codes given in this site for converting, but none of these worked
First step is to parse it into a proper datetime object:
import datetime
column_date_str_gmt = ...
gmt_datetime = datetime.datetime.strftime(column_date_str_gmt, '%Y-%m-%dT%H:%M:%SZ')
Then, move the gmt datetime over to UTC:
from datetime import timezone
utc_datetime= gmt_datetime.replace(tzinfo=timezone.utc).timestamp()
Finally, convert to local time:
import time
epoch = time.mktime(utc.timetuple())
epoch_offset = datetime.fromtimestamp (epoch) - datetime.utcfromtimestamp (epoch)
local_datetime = utc + epoch_offset

Get the day of week given a date

I am working on my project on a timetable app. I can get the date with:
import datetime
now = datetime.datetime.now()
print (now.day, "/", now.month, "/", now.year)
But I can't get the day of the week though. Can someone help me?
To format and print dates, you should use the strftime functions (see the strftime python 3 documentation) instead of manually build your own format.
so e.g.
import datetime
now = datetime.datetime.now()
print(now.strftime("%A, %d/%m/%Y"))
Check out the doc, for the full list of styles. Maybe you want %a (abbreviated weekday name, or also %b or %B for the month name.
If you need just the values, check the datetime documenation, in the same page: you have now.weekday() (Monday is 0 and Sunday is 6), or now.iweekday() (Monday is 1 and Sunday is 7).
Try this:
import time
localtime = time.localtime(time.time())
current_time = time.asctime(localtime)
print(current_time[:3])
This should work.
Thanks.
There is an excellent answer by #seddonym on https://stackoverflow.com/a/29519293/4672536 to find the day of the week. I will post the code here for reference. Good luck! :) :
>>> from datetime import date
>>> import calendar
>>> my_date = date.today()
>>> calendar.day_name[my_date.weekday()]
'Wednesday'

How to create a datetime object given seconds since unix epoch?

There seems to be a lot of confusion online on doing a very basic thing: create a datetime object with UTC timezone given seconds since unix epoch in the UTC timezone. Basically, I always want to work in absolute time/UTC.
I'm using python 3.5 (the latest right now) and want to simply get a datetime object in the context of UTC (+0/Zulu offset) from a floating point value of elapsed seconds since 1970 Jan 01.
This is wrong since the first time is created in my local timezone, and then I attempt to switch to UTC.
import datetime
import pytz
dt = datetime.datetime.fromtimestamp(my_seconds).replace(tzinfo=pytz.UTC)
Python provided the method utcfromtimestamp just for that case. utcfromtimestamp
import datetime
seconds = 0
utcdate_from_timestamp = datetime.datetime.utcfromtimestamp(seconds)
If my_seconds is a POSIX timestamp then to convert it to datetime in Python 3:
#!/usr/bin/env python3
from datetime import datetime, timedelta, timezone
utc_dt = datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=my_seconds)
utc_dt = datetime.fromtimestamp(my_seconds, timezone.utc)
naive_utc_dt = datetime.utcfromtimestamp(my_seconds)
If your local timezone is "right" (non-POSIX) then only the first formula is correct (the others interpret my_seconds as TAI timestamp with datetime(1970, 1, 1, 0, 0, 10) TAI epoch in this case).
The first formula is more portable and may support a wider input range than the others.
The results of the 1st and 2nd expressions may differ due to rounding errors on some Python versions.
The 2nd and 3rd calls should differ only by tzinfo attibute (the latter returns a naive datetime object (.tzinfo is None)). You should prefer timezone-aware datetime objects, to avoid ambiguity.

convertion of datetime to numpy datetime without timezone info

Suppose I have a datetime variable:
dt = datetime.datetime(2001,1,1,0,0)
and I convert it to numpy as follows numpy.datetime64(dt) I get
numpy.datetime64('2000-12-31T19:00:00.000000-0500')
with dtype('<M8[us]')
But this automatically takes into account my time-zone (i.e. EST in this case) and gives me back a date of 2001-12-31 and a time of 19:00 hours.
How can I convert it to datetime64[D] in numpy that ignores the timezone information and simply gives me
numpy.datetime64('2001-01-01')
with dtype('<M8[D]')
The numpy datetime64 doc page gives no information on how to ignore the time-zone or give the default time-zone as UTC
I was just playing around with this the other day. I think there are 2 issues - how the datetime.datetime object is converted to np.datetime64, and how the later is displayed.
The numpy doc talks about creating a datatime64 object from a date string. It appears that when given a datetime.datetime object, it first produces a string.
np.datetime64(dt) == np.datetime64(dt.isoformat())
I found that I could add timezone info to that string
np.datetime64(dt.isoformat()+'Z') # default assumption
np.datetime64(dt.isoformat()+'-0500')
Numpy 1.7.0 reads ISO 8601 strings w/o TZ as local (ISO specifies this)
Datetimes are always stored based on POSIX time with an epoch of 1970-01-01T00:00Z
As for display, the test_datetime.py file offers some clues as to the undocumented behavior.
https://github.com/numpy/numpy/blob/280f6050d2291e50aeb0716a66d1258ab3276553/numpy/core/tests/test_datetime.py
e.g.:
def test_datetime_array_str(self):
a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M')
assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']")
a = np.array(['2011-03-16T13:55Z', '1920-01-01T03:12Z'], dtype='M')
assert_equal(np.array2string(a, separator=', ',
formatter={'datetime': lambda x :
"'%s'" % np.datetime_as_string(x, timezone='UTC')}),
"['2011-03-16T13:55Z', '1920-01-01T03:12Z']")
So you can customize the print behavior of an array with np.array2string, and np.datetime_as_string. np.set_printoptions also takes a formatter parameter.
The pytz module is used to add further timezone handling:
#dec.skipif(not _has_pytz, "The pytz module is not available.")
def test_datetime_as_string_timezone(self):
# timezone='local' vs 'UTC'
a = np.datetime64('2010-03-15T06:30Z', 'm')
assert_equal(np.datetime_as_string(a, timezone='UTC'),
'2010-03-15T06:30Z')
assert_(np.datetime_as_string(a, timezone='local') !=
'2010-03-15T06:30Z')
....
Examples:
In [48]: np.datetime_as_string(np.datetime64(dt),timezone='local')
Out[48]: '2000-12-31T16:00:00.000000-0800'
In [49]: np.datetime64(dt)
Out[49]: numpy.datetime64('2000-12-31T16:00:00.000000-0800')
In [50]: np.datetime_as_string(np.datetime64(dt))
Out[50]: '2001-01-01T00:00:00.000000Z'
In [51]: np.datetime_as_string(np.datetime64(dt),timezone='UTC')
Out[51]: '2001-01-01T00:00:00.000000Z'
In [52]: np.datetime_as_string(np.datetime64(dt),timezone='local')
Out[52]: '2000-12-31T16:00:00.000000-0800'
In [81]: np.datetime_as_string(np.datetime64(dt),timezone=pytz.timezone('US/Eastern'))
Out[81]: '2000-12-31T19:00:00.000000-0500'

Resources