How to convert UTC/extended format to datetime in Python - python

I want to convert datetime in %Y-%m-%d,
so from Sat, 17 Apr 2021 16:17:00 +0100 to 17-04-2021
def convertDatetime(data):
test_datetime = data
data_new_format = datetime.datetime.strptime(test_datetime,'%- %Y %M %d')
print(data_new_format)
convertDatetime("Sat, 17 Apr 2021 16:17:00 +0100")
but it say me: '-' is a bad directive in format '%- %Y %M %d'

The format you specify '%- %Y %M %d' (1) contains an incorrect specifier - as the error says, and also (2) completely does not match the data you want to convert. The format you pass to strptime() must match the way the data looks, not the way you want it to look.
>>> data="Sat, 17 Apr 2021 16:17:00 +0100"
>>> format = "%a, %d %b %Y %H:%M:%S %z"
>>> datetime.datetime.strptime(data, format)
datetime.datetime(2021, 4, 17, 16, 17, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))
To reformat the datetime the way you want, you need a second call, to strftime():
>>> datetime.datetime.strptime(data, format).strftime("%Y-%m-%d")
'2021-04-17'

Related

How to convert timezone in number to UTC?

I have some random dates with different timezones, they are in formats like this "07 Mar 2022 13:52:00 -0300", or they could be like this: "07 Mar 2022 11:12:00 -0700". I don't know which timezone exactly they will be coming from. How can I convert all of them to UTC time "0000Z"?
You can use standard module datetime for this.
Function strptime() (string parsing time) can convert string to object datetime using matching pattern. For your examples works pattern '%d %b %Y %H:%M:%S %z'
Next you can use .astimezone(datetime.timezone.utc) to convert to UTC.
And later you can format string with strftime() (string formatting time) using again pattern '%d %b %Y %H:%M:%S %z' (or you can skip %z)
Minimal working code:
import datetime
data = [
"07 Mar 2022 13:52:00 -0300",
"07 Mar 2022 11:12:00 -0700",
]
for item in data:
print('before str:', item)
dt = datetime.datetime.strptime(item, '%d %b %Y %H:%M:%S %z')
print('before dt :', dt)
dt = dt.astimezone(datetime.timezone.utc)
print('after dt :', dt)
print('after str:', dt.strftime('%d %b %Y %H:%M:%S %z'))
print('---')
Result:
before str: 07 Mar 2022 13:52:00 -0300
before dt : 2022-03-07 13:52:00-03:00
after dt : 2022-03-07 16:52:00+00:00
after str: 07 Mar 2022 16:52:00 +0000
---
before str: 07 Mar 2022 11:12:00 -0700
before dt : 2022-03-07 11:12:00-07:00
after dt : 2022-03-07 18:12:00+00:00
after str: 07 Mar 2022 18:12:00 +0000
---
I would suggest to import datetime, then use the following method to convert your time stamps into datetime objects (where str is the time stamp as a string): time_stamp = datetime.strptime(str, "%d %b %Y") (where the parameter after str gives information on the formatting; for details see here: https://www.programiz.com/python-programming/datetime/strptime).
After that, you can use datetime.astimezone() to convert this into another time zone.

Convert date string (from gmail) to timestamp | Python

I want to save the received date of emails from a Gmail account into a time-series database.
The problem is that I cannot convert the string that I got from the email to timestamp.
I tried this:
from datetime import datetime
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')
print(date1_obj)
But got this error:
Traceback (most recent call last):
File "/format_date.py", line 11, in <module>
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 359, in _strptime
(data_string, format))
ValueError: time data 'Thu, 28 May 2020 08:15:58 -0700 (PDT)' does not match format '%a, %d %b %Y %H:%M:%S %z %Z'
Tried with or without parenthesis wrapping Timezone.
Read a lot, but nothing about how to deal with date strings containing "(PDT)" or any other timezones. It's very important to get the right date... If I run the same code without "(PDT)", got an incorrect time (because of my local time).
I know I can use string methods to manipulate it and convert to a right datetime, but I feel like this would be flexible.
Sorry for my terrible English.
Thank you!
you could use dateutil's parser to parse the string, automatically inferring the format:
import dateutil
s = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)'
dt = dateutil.parser.parse(s)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzoffset('PDT', -25200))
dt.utcoffset().total_seconds()
# -25200.0
Note that although the timezone is given a name ("PDT"), it is only a UTC offset of 25200 s. In many cases that is sufficient, at least to convert to UTC.
If you need the specific timezone (e.g. to account for DST transitions etc.), you can use a mapping dict that you supply to dateutil.parser.parse as tzinfos:
tzmap = {'PDT': dateutil.tz.gettz('US/Pacific'),
'PST': dateutil.tz.gettz('US/Pacific')}
dt = dateutil.parser.parse(s, tzinfos=tzmap)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzfile('US/Pacific'))
dt.utcoffset().total_seconds()
# -25200.0
Close, you forgot to put the bracket around the last entry.
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
Well, after all your answers, which were very helpful, I finally solved.
This is how:
>>> from email.utils import parsedate_tz, mktime_tz
>>> date = 'Thu, 28 May 2020 08:15:58 -0700 (PST)'
>>> timestamp = mktime_tz(parsedate_tz(date))
>>> timestamp
1590678958
>>>
I checked that timestamp, and stands to 12:15:58 local time, what it's exactly what I was looking for.
Thank you very much to everybody who took a minute to answer.
If it does not work even if you enclose %Z in brackets then the problem lies within the %Z directive
https://docs.python.org/3/library/time.html
Support for the %Z directive is based on the values contained in
tzname and whether daylight is true. Because of this, it is
platform-specific except for recognizing UTC and GMT which are always
known (and are considered to be non-daylight savings timezones).
In example the following results in a ValueError for me (in Europe)
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PST)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)
While with GMT it the output is 2020-05-28 08:15:58-07:00
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)
Based on your comment under this answer you could split the string if the Timezone bit is not important:
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1.split(" (")[0], '%a, %d %b %Y %H:%M:%S %z')

Parsing GST timezone with datetime.strptime

I am trying to parse a str as a datetime.datetime object. However, I am unable to achieve this because the timezone is GST.
import datetime
s_dt = 'Mon Jul 01 17:17:37 UTC'
datetime.datetime.strptime(s_dt, '%a %b %d %H:%M:%S %Z')
# datetime.datetime(1900, 7, 1, 17, 17, 37)
s_dt = 'Mon Jul 01 17:17:37 GST'
datetime.datetime.strptime(s_dt, '%a %b %d %H:%M:%S %Z')
# ValueError: time data 'Mon Jul 01 17:17:37 GST' does not match format '%a %b %d %H:%M:%S %Z'
How can I fix this?
There are two ways to deal with this:-
Replace the GST in the string, to UTC
Replace the GST in the string, to UTC with proper time conversion (decreasing the time in UTC by 4 hours, as time GST is +4 hours from UTC).
METHOD 1:-
s_dt = 'Mon Jul 01 17:17:37 GST'.replace("GST", "UTC")
datetime.datetime.strptime(s_dt, '%a %b %d %H:%M:%S %Z')
METHOD 2:-
# replacing GST to UTC in original string
s_dt = 'Mon Jul 01 17:17:37 GST'.replace("GST", "UTC")
# getting the hours from the string
s_dt_obj = int(s_dt.split(":")[0][-2:])
# substracting 4 from the hours (in order to create UTC equivalent of GST time)
s_dt_obj = str((s_dt_obj - 4) % 24)
# putting everything back to a string
s_dt_obj = f"{s_dt.split(':')[0][:-2]}{s_dt_obj}:{s_dt.split(':')[1]}:{s_dt.split(':')[2]}"
# creating datetime object out of our newly created string
datetime.datetime.strptime(s_dt_obj, '%a %b %d %H:%M:%S %Z')
# datetime.datetime(1900, 7, 1, 13, 17, 37)

How to fix ValueError time date does not match format when converting from string to datetime

Im trying to convert a string to datetime and keep getting the error: ValueError: time data 'Mon, 22 Apr 2019 17:04:38 +0200 (CEST)' does not match format '%a, %d %b %Y %H:%M:%S %z %Z'
from datetime import datetime
s = "Mon, 22 Apr 2019 17:04:38 +0200 (CEST)"
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z %Z')
What am i missing?
%Z is generally used for converting into string format. In any case, it is the offset, not the name of the time zone.
The rest of your code is valid, however:
s = "Mon, 22 Apr 2019 17:04:38 +0200"
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z')
datetime only comes with the ability to parse UTC and whatever local time zone is listed in time.tzname. It can't match (CEST) because it doesn't know what timezone that is (It would also be redundant because you defined the timezone using the offset +0200).
You will need to implement your own (CEST) using datetime.tzinfo or by importing an external library like pytz or pendulum in order to parse (CEST) from a string into a datetime.timezone.
Also, don't forget to include parenthesis() in your match string.
This code passes, however, I do not know what happens to 'CEST' once it is converted into the string.
from datetime import datetime
tz = 'CEST'
s = "Mon, 22 Apr 2019 17:04:38 +0200 " + tz
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z ' + tz)

How to parse time retrieved from Facebook Graph into 12 hour format?

When I pull events start times from Facebook Graph in comes in this form:
2017-09-26T18:00:00+0300
I'd like to convert it into readable format so I use this:
readable_event_date = dateutil.parser.parse(event_date).strftime('%a, %b %d %Y %H:%M:%S')
and it comes out like this:
Tue, 26 Sep 2017 18:00:00
Which is good but it loses the offset from UTC and I'd like it in AM PM format.
Thus, I would like it like this:
Tue, 26 Sep 2017 9:00 PM
To get into 12 hours format and keep offset from UTC for printing :
from dateutil.parser import parse
event_date = '2017-09-26T18:00:0+0300'
date = parse(event_date)
offset = date.tzinfo._offset
readable_event_date = (date + offset).strftime('%a, %b %d %Y %I:%M:%S %p')
print(readable_event_date)
Output:
'Tue, Sep 26 2017 09:00:00 PM'
It seems like what you want is this time, expressed in UTC, in the format '%a, %b %d %Y %I:%M:%S %p'. Luckily, all the information you need to do this is contained in the datetime object that you parsed, you just need to convert to UTC
Python 2.6+ or Python 3.3+:
The approach you've taken using dateutil will work for Python 2.6+ or Python 3.3.+ (and also works for a greater variety of datetime string formats):
from dateutil.parser import parse
# In Python 2.7, you need to use another one
from dateutil.tz import tzutc
UTC = tzutc()
dt_str = '2017-09-26T18:00:00+0300'
dt = parse(dt_str)
dt_utc = dt.astimezone(UTC) # Convert to UTC
print(dt_utc.strftime('%a, %b %d %Y %I:%M:%S %p'))
# Tue, Sep 26 2017 03:00:00 PM
One thing I notice is that the date you've provided, as far as I can tell, represents 3PM in UTC, not 9PM (as your example states). This is one reason you should use .astimezone(UTC) rather than some other approach.
If you want to include the time zone offset information, you can also use the %z parameter on the non-converted version of the datetime object.
print(dt.strftime('%a, %b %d %Y %I:%M:%S%z %p'))
# Tue, Sep 26 2017 06:00:00+0300 PM
This %z parameter may also be useful even if you are keeping it in UTC, because then you can at least be clear that the date the user is seeing is a UTC date.
Python 3.2+ only:
Given that you know the exact format of the input string, in Python 3.2+, you can achieve this same thing without pulling in dateutil, and it will almost certainly be faster (which may or may not be a concern for you).In your case here is how to rewrite the code so that it works with just the standard library:
from datetime import datetime, timezone
UTC = timezone.utc
dt_str = '2017-09-26T18:00:00+0300'
dt = datetime.strptime(dt_str, '%Y-%m-%dT%H:%M:%S%z')
dt_utc = dt.astimezone(UTC)
print(dt_utc.strftime('%a, %b %d %Y %I:%M:%S %p'))
# Tue, Sep 26 2017 03:00:00 PM
print(dt.strftime('%a, %b %d %Y %I:%M:%S%z %p'))
# Tue, Sep 26 2017 06:00:00+0300 PM

Categories