How to normalize string to datetime format in Python - python

I want to transfer date string into python datetime format. The string is below:
Mon, 26 Dec 2011 20:42:08 +0200
Sat, 24 Dec 2011 16:28:59 +0200
Is there any faster way to transfer the string into python datetime format without using pytz API?

>>> import datetime
>>> s = "Mon, 26 Dec 2011 20:42:08 +0200"
>>> t = datetime.datetime.strptime(s, "%a, %d %b %Y %H:%M:%S %z")
>>> t
datetime.datetime(2011, 12, 26, 20, 42, 8, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
See the docs for a complete list of datetime placeholders.

Here's a variant that works on Python 2.5+, PyPy, Jython:
from datetime import datetime, timedelta
from email.utils import mktime_tz, parsedate_tz
s = "Mon, 26 Dec 2011 20:42:08 +0200"
t = parsedate_tz(s)
if t[9] is not None:
utc_offset = timedelta(seconds=t[9]) # local = utc + offset
print("utc offset: %s" % (utc_offset,))
print(repr(datetime.utcfromtimestamp(mktime_tz(t)))) # naive datetime in UTC
Output
utc offset: 2:00:00
datetime.datetime(2011, 12, 26, 18, 42, 8)

Try this?
Assuming input of 2016-01-02 and you want to standardize all dates.
def NormalizaData(input):
input = str(input)
num = input.split('-')
year = num[0]
newnum = num[1]
num = newnum.split('-')
month = num[0]
day = '01'
return (year + '-' + month + '-' + day)

Related

Convert YYYY-MM-DD to Aug 26, 2022 [duplicate]

This question already has answers here:
Python convert date format
(3 answers)
Closed 6 months ago.
I have date in the form of YYYY-MM-DD how can i format that date into Aug 26, 2022.
def return_date():
date_returned = YYYY-MM-DD
return date_returned in form of Aug 26, 2022
here is your code:
from datetime import date
date_string = '2022-08-26'
date.fromisoformat(date_string).strftime('%b %d, %Y') # 'Aug 26, 2022'
You can easily understand with this example:
from datetime import datetime
# Get current Date
date = datetime.now()
# Represent dates in short textual format
print("dd-MMM-yyyy:", date.strftime("%b %d, %Y"))
# prints "dd-MMM-yyyy: Aug 26, 2022"
I hope this will help you.
Use strptime to decode the string then strftime to format it to your liking as follows:
from time import strptime, strftime
def return_date(ds): # data as string in the form YYYY-MM-DD
return strftime('%b %d, %Y', strptime(ds, '%Y-%m-%d'))
print(return_date('2022-08-26'))
Output:
Aug 26, 2022
Is this what you are trying to accomplish?
import datetime
def return_date(ymd_format):
year, month, day = ymd_format.split("-")
return datetime.datetime(int(year), int(month), int(day)).strftime("%b %d, %Y")
print(return_date("2022-08-26")) # prints "Aug 26, 2022"

Python : string with timezone to datetime object conversion

I have a string like this
dateStr = "Wed Mar 15 12:50:52 GMT+05:30 2017"
which is IST time.
Is there any way to read the dateStr as per the specified timezone within the dateStr
i.e. GMT+05:30.
So that I can make datetime object directly.
I have tried to parse it using format
format = "%a %b %d %H:%M:%S %Z%z %Y"
But it gives me error of format does not match.
Can you try this?
>>> dateStr = "Wed Mar 15 12:50:52 GMT+05:30 2017"
>>> from dateutil.parser import parse
>>> parse(dateStr)
datetime.datetime(2017, 3, 15, 12, 50, 52, tzinfo=tzoffset(None, -19800))

How to convert GMT time to EST time using Python

I want convert GMT time to EST time and get a timestamp. I tried the following but don't know how to set time zone.
time = "Tue, 12 Jun 2012 14:03:10 GMT"
timestamp2 = time.mktime(time.strptime(time, '%a, %d %b %Y %H:%M:%S GMT'))
Time zones aren't built into standard Python - you need to use another library. pytz is a good choice.
>>> gmt = pytz.timezone('GMT')
>>> eastern = pytz.timezone('US/Eastern')
>>> time = "Tue, 12 Jun 2012 14:03:10 GMT"
>>> date = datetime.datetime.strptime(time, '%a, %d %b %Y %H:%M:%S GMT')
>>> date
datetime.datetime(2012, 6, 12, 14, 3, 10)
>>> dategmt = gmt.localize(date)
>>> dategmt
datetime.datetime(2012, 6, 12, 14, 3, 10, tzinfo=<StaticTzInfo 'GMT'>)
>>> dateeastern = dategmt.astimezone(eastern)
>>> dateeastern
datetime.datetime(2012, 6, 12, 10, 3, 10, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
Using pytz
from datetime import datetime
from pytz import timezone
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
now_time = datetime.now(timezone('US/Eastern'))
print now_time.strftime(fmt)
With Python 3.9, time zone handling is built into the standard lib with the zoneinfo module (for older Python versions, use zoneinfo via backports.zoneinfo).
Ex:
from zoneinfo import ZoneInfo
from datetime import datetime, timezone
time = "Tue, 12 Jun 2012 14:03:10 GMT"
# parse to datetime, using %Z for the time zone abbreviation
dtobj = datetime.strptime(time, '%a, %d %b %Y %H:%M:%S %Z')
# note that "GMT" (=UTC) is ignored:
# datetime.datetime(2012, 6, 12, 14, 3, 10)
# ...so let's correct that:
dtobj = dtobj.replace(tzinfo=timezone.utc)
# datetime.datetime(2012, 6, 12, 14, 3, 10, tzinfo=datetime.timezone.utc)
# convert to US/Eastern (EST or EDT, depending on time of the year)
dtobj = dtobj.astimezone(ZoneInfo('US/Eastern'))
# datetime.datetime(2012, 6, 12, 10, 3, 10, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
print(dtobj)
# 2012-06-12 10:03:10-04:00
And there's also dateutil, which follows the same semantics:
import dateutil
# no strptime needed...
# correctly localizes to GMT (=UTC) directly
dtobj = dateutil.parser.parse(time)
dtobj = dtobj.astimezone(dateutil.tz.gettz('US/Eastern'))
# datetime.datetime(2012, 6, 12, 10, 3, 10, tzinfo=tzfile('US/Eastern'))
print(dtobj)
# 2012-06-12 10:03:10-04:00
If it is your local timezone and the timezone rules are the same for the given time as they are now then you could use stdlib-only solution (except for some edge cases):
#!/usr/bin/env python
from email.utils import parsedate_tz, mktime_tz
from datetime import datetime
timestamp = mktime_tz(parsedate_tz("Tue, 12 Jun 2012 14:03:10 GMT"))
print(datetime.fromtimestamp(timestamp))
# -> 2012-06-12 10:03:10
Otherwise you need data from a historical timezone database to get the correct utc offset. pytz module provides access to the tz database:
#!/usr/bin/env python
from email.utils import parsedate_tz, mktime_tz
from datetime import datetime
import pytz # $ pip install pytz
timestamp = mktime_tz(parsedate_tz("Tue, 12 Jun 2012 14:03:10 GMT"))
eastern_dt = datetime.fromtimestamp(timestamp, pytz.timezone('America/New_York'))
print(eastern_dt.strftime('%a, %d %b %Y %H:%M:%S %z (%Z)'))
# -> Tue, 12 Jun 2012 10:03:10 -0400 (EDT)
Note: POSIX timestamp is the same around the world i.e., your local timezone doesn't matter if you want to find the timestamp (unless your timezone is of "right" kind). Here's how to convert a utc time to the timestamp.

How can I convert a timestamp string with timezone offset to local time?

I am trying to convert a string timestamp into a proper datetime object. The problem I am having is that there is a timezone offset and everything I am doing doesn't seem to work.
Ultimately I want to convert the string timestamp into a datetime object in my machines timezone.
# string timestamp
date = "Fri, 16 Jul 2010 07:08:23 -0700"
The dateutil package is handy for parsing date/times:
In [10]: date = u"Fri, 16 Jul 2010 07:08:23 -0700"
In [11]: from dateutil.parser import parse
In [12]: parse(date)
Out[12]: datetime.datetime(2010, 7, 16, 7, 8, 23, tzinfo=tzoffset(None, -25200))
Finally, to convert into your local timezone,
In [13]: parse(date).astimezone(YOUR_LOCAL_TIMEZONE)
It looks like datetime.datetime.strptime(d, '%a, %d %b %Y %H:%M:%S %z') should work, but according to this bug report there are issues with the %z processing. So you'll probably have to handle the timezone on your own:
import datetime
d = u"Fri, 16 Jul 2010 07:08:23 -0700"
d, tz_info = d[:-5], d[-5:]
neg, hours, minutes = tz_info[0], int(tz_info[1:3]), int(tz_info[3:])
if neg == '-':
hours, minutes = hours * -1, minutes * -1
d = datetime.datetime.strptime(d, '%a, %d %b %Y %H:%M:%S ')
print d
print d + datetime.timedelta(hours = hours, minutes = minutes)
Here's a stdlib solution:
>>> from datetime import datetime
>>> from email.utils import mktime_tz, parsedate_tz
>>> datetime.fromtimestamp(mktime_tz(parsedate_tz(u"Fri, 16 Jul 2010 07:08:23 -0700")))
datetime.datetime(2010, 7, 16, 16, 8, 23) # your local time may be different
See also, Python: parsing date with timezone from an email.
Note: fromtimestamp() may fail if the local timezone had different UTC offset in the past (2010) and if it does not use a historical timezone database on the given platform. To fix it, you could use tzlocal.get_localzone(), to get a pytz tzinfo object representing your local timezone. pytz provides access to the tz database in a portable manner:
>>> timestamp = mktime_tz(parsedate_tz(u"Fri, 16 Jul 2010 07:08:23 -0700"))
>>> import tzlocal # $ pip install tzlocal
>>> str(datetime.fromtimestamp(timestamp, tzlocal.get_localzone()))
'2010-07-16 16:08:23+02:00'

Parsing date with timezone from an email?

I am trying to retrieve date from an email. At first it's easy:
message = email.parser.Parser().parse(file)
date = message['Date']
print date
and I receive:
'Mon, 16 Nov 2009 13:32:02 +0100'
But I need a nice datetime object, so I use:
datetime.strptime('Mon, 16 Nov 2009 13:32:02 +0100', '%a, %d %b %Y %H:%M:%S %Z')
which raises ValueError, since %Z isn't format for +0100. But I can't find proper format for timezone in the documentation, there is only this %Z for zone. Can someone help me on that?
email.utils has a parsedate() function for the RFC 2822 format, which as far as I know is not deprecated.
>>> import email.utils
>>> import time
>>> import datetime
>>> email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0100')
(2009, 11, 16, 13, 32, 2, 0, 1, -1)
>>> time.mktime((2009, 11, 16, 13, 32, 2, 0, 1, -1))
1258378322.0
>>> datetime.datetime.fromtimestamp(1258378322.0)
datetime.datetime(2009, 11, 16, 13, 32, 2)
Please note, however, that the parsedate method does not take into account the time zone and time.mktime always expects a local time tuple.
>>> (time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0900')) ==
... time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0100'))
True
So you'll still need to parse out the time zone and take into account the local time difference, too:
>>> REMOTE_TIME_ZONE_OFFSET = +9 * 60 * 60
>>> (time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0900')) +
... time.timezone - REMOTE_TIME_ZONE_OFFSET)
1258410122.0
Use email.utils.parsedate_tz(date):
msg=email.message_from_file(open(file_name))
date=None
date_str=msg.get('date')
if date_str:
date_tuple=email.utils.parsedate_tz(date_str)
if date_tuple:
date=datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
if date:
... # valid date found
For python 3.3+ you can use parsedate_to_datetime function:
>>> from email.utils import parsedate_to_datetime
>>> parsedate_to_datetime('Mon, 16 Nov 2009 13:32:02 +0100')
...
datetime.datetime(2009, 11, 16, 13, 32, 2, tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))
Official documentation:
The inverse of format_datetime(). Performs the same function as
parsedate(), but on success returns a datetime. If the input date has
a timezone of -0000, the datetime will be a naive datetime, and if the
date is conforming to the RFCs it will represent a time in UTC but
with no indication of the actual source timezone of the message the
date comes from. If the input date has any other valid timezone
offset, the datetime will be an aware datetime with the corresponding
a timezone tzinfo. New in version 3.3.
In Python 3.3+, email message can parse the headers for you:
import email
import email.policy
headers = email.message_from_file(file, policy=email.policy.default)
print(headers.get('date').datetime)
# -> 2009-11-16 13:32:02+01:00
Since Python 3.2+, it works if you replace %Z with %z:
>>> from datetime import datetime
>>> datetime.strptime("Mon, 16 Nov 2009 13:32:02 +0100",
... "%a, %d %b %Y %H:%M:%S %z")
datetime.datetime(2009, 11, 16, 13, 32, 2,
tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))
Or using email package (Python 3.3+):
>>> from email.utils import parsedate_to_datetime
>>> parsedate_to_datetime("Mon, 16 Nov 2009 13:32:02 +0100")
datetime.datetime(2009, 11, 16, 13, 32, 2,
tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))
if UTC offset is specified as -0000 then it returns a naive datetime object that represents time in UTC otherwise it returns an aware datetime object with the corresponding tzinfo set.
To parse rfc 5322 date-time string on earlier Python versions (2.6+):
from calendar import timegm
from datetime import datetime, timedelta, tzinfo
from email.utils import parsedate_tz
ZERO = timedelta(0)
time_string = 'Mon, 16 Nov 2009 13:32:02 +0100'
tt = parsedate_tz(time_string)
#NOTE: mktime_tz is broken on Python < 2.7.4,
# see https://bugs.python.org/issue21267
timestamp = timegm(tt) - tt[9] # local time - utc offset == utc time
naive_utc_dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
aware_utc_dt = naive_utc_dt.replace(tzinfo=FixedOffset(ZERO, 'UTC'))
aware_dt = aware_utc_dt.astimezone(FixedOffset(timedelta(seconds=tt[9])))
print(aware_utc_dt)
print(aware_dt)
# -> 2009-11-16 12:32:02+00:00
# -> 2009-11-16 13:32:02+01:00
where FixedOffset is based on tzinfo subclass from the datetime documentation:
class FixedOffset(tzinfo):
"""Fixed UTC offset: `time = utc_time + utc_offset`."""
def __init__(self, offset, name=None):
self.__offset = offset
if name is None:
seconds = abs(offset).seconds
assert abs(offset).days == 0
hours, seconds = divmod(seconds, 3600)
if offset < ZERO:
hours = -hours
minutes, seconds = divmod(seconds, 60)
assert seconds == 0
#NOTE: the last part is to remind about deprecated POSIX
# GMT+h timezones that have the opposite sign in the
# name; the corresponding numeric value is not used e.g.,
# no minutes
self.__name = '<%+03d%02d>GMT%+d' % (hours, minutes, -hours)
else:
self.__name = name
def utcoffset(self, dt=None):
return self.__offset
def tzname(self, dt=None):
return self.__name
def dst(self, dt=None):
return ZERO
def __repr__(self):
return 'FixedOffset(%r, %r)' % (self.utcoffset(), self.tzname())
Have you tried
rfc822.parsedate_tz(date) # ?
More on RFC822, http://docs.python.org/library/rfc822.html
It's deprecated (parsedate_tz is now in email.utils.parsedate_tz), though.
But maybe these answers help:
How to parse dates with -0400 timezone string in python?
python time to age part 2, timezones
# Parses Nginx' format of "01/Jan/1999:13:59:59 +0400"
# Unfortunately, strptime doesn't support %z for the UTC offset (despite what
# the docs actually say), hence the need # for this function.
def parseDate(dateStr):
date = datetime.datetime.strptime(dateStr[:-6], "%d/%b/%Y:%H:%M:%S")
offsetDir = dateStr[-5]
offsetHours = int(dateStr[-4:-2])
offsetMins = int(dateStr[-2:])
if offsetDir == "-":
offsetHours = -offsetHours
offsetMins = -offsetMins
return date + datetime.timedelta(hours=offsetHours, minutes=offsetMins)
For those who want to get the correct local time, here is what I did:
from datetime import datetime
from email.utils import parsedate_to_datetime
mail_time_str = 'Mon, 16 Nov 2009 13:32:02 +0100'
local_time_str = datetime.fromtimestamp(parsedate_to_datetime(mail_time_str).timestamp()).strftime('%Y-%m-%d %H:%M:%S')
print(local_time_str)
ValueError: 'z' is a bad directive in format...
(note: I have to stick to python 2.7 in my case)
I have had a similar problem parsing commit dates from the output of git log --date=iso8601 which actually isn't the ISO8601 format (hence the addition of --date=iso8601-strict in a later version).
Since I am using django I can leverage the utilities there.
https://github.com/django/django/blob/master/django/utils/dateparse.py
>>> from django.utils.dateparse import parse_datetime
>>> parse_datetime('2013-07-23T15:10:59.342107+01:00')
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)
Instead of strptime you could use your own regular expression.

Categories

Resources