Calculating days using string dates in Python - python

I have dates in the current string format: 'Tue Feb 19 00:09:28 +1100 2013'
I'm trying to figure out how many days have passed between the date in the string and the present date.
I've been able to convert the string into a date.
import time
day = time.strptime('Tue Feb 19 00:09:28 +1100 2013', '%a %b %d %H:%M:%S +1100 %Y')

Use the datetime module instead:
import datetime
day = datetime.datetime.strptime('Tue Feb 19 00:09:28 +1100 2013', '%a %b %d %H:%M:%S +1100 %Y')
delta = day - datetime.datetime.now()
print delta.days
Subtracting two datetime.datetime values returns a datetime.timedelta object, which has a days attribute.
Your strings do contain a timezone offset, and you hardcoded it to match; if the value varies you'll have to use a parser that can handle the offset. The python-dateutil package includes both an excellent parser and the timezone support to handle this:
>>> from dateutil import parser
>>> parser.parse('Tue Feb 19 00:09:28 +1100 2013')
datetime.datetime(2013, 2, 19, 0, 9, 28, tzinfo=tzoffset(None, 39600))
Note that because this result includes the timezone, you now need to use timezone-aware datetime objects when using date arithmetic:
>>> from dateutil import tz
>>> import datetime
>>> utcnow = datetime.datetime.now(tz.tzutc())
>>> then = parser.parse('Tue Feb 19 00:09:28 +1100 2013')
>>> utcnow - then
datetime.timedelta(31, 12087, 617740)
>>> (utcnow - then).days
31
I created a utcnow variable in the above example based of the UTC timezone before calculating how long ago the parsed date was.

Related

Extract month from timestamp of a dict using python [duplicate]

I have a date string with the format 'Mon Feb 15 2010'. I want to change the format to '15/02/2010'. How can I do this?
datetime module could help you with that:
datetime.datetime.strptime(date_string, format1).strftime(format2)
For the specific example you could do
>>> import datetime
>>> datetime.datetime.strptime('Mon Feb 15 2010', '%a %b %d %Y').strftime('%d/%m/%Y')
'15/02/2010'
>>>
You can install the dateutil library. Its parse function can figure out what format a string is in without having to specify the format like you do with datetime.strptime.
from dateutil.parser import parse
dt = parse('Mon Feb 15 2010')
print(dt)
# datetime.datetime(2010, 2, 15, 0, 0)
print(dt.strftime('%d/%m/%Y'))
# 15/02/2010
convert string to datetime object
from datetime import datetime
s = "2016-03-26T09:25:55.000Z"
f = "%Y-%m-%dT%H:%M:%S.%fZ"
out = datetime.strptime(s, f)
print(out)
output:
2016-03-26 09:25:55
>>> from_date="Mon Feb 15 2010"
>>> import time
>>> conv=time.strptime(from_date,"%a %b %d %Y")
>>> time.strftime("%d/%m/%Y",conv)
'15/02/2010'
As this question comes often, here is the simple explanation.
datetime or time module has two important functions.
strftime - creates a string representation of date or time from a datetime or time object.
strptime - creates a datetime or time object from a string.
In both cases, we need a formating string. It is the representation that tells how the date or time is formatted in your string.
Now lets assume we have a date object.
>>> from datetime import datetime
>>> d = datetime(2010, 2, 15)
>>> d
datetime.datetime(2010, 2, 15, 0, 0)
If we want to create a string from this date in the format 'Mon Feb 15 2010'
>>> s = d.strftime('%a %b %d %y')
>>> print s
Mon Feb 15 10
Lets assume we want to convert this s again to a datetime object.
>>> new_date = datetime.strptime(s, '%a %b %d %y')
>>> print new_date
2010-02-15 00:00:00
Refer This document all formatting directives regarding datetime.
#codeling and #user1767754 : The following two lines will work. I saw no one posted the complete solution for the example problem that was asked. Hopefully this is enough explanation.
import datetime
x = datetime.datetime.strptime("Mon Feb 15 2010", "%a %b %d %Y").strftime("%d/%m/%Y")
print(x)
Output:
15/02/2010
You may achieve this using pandas as well:
import pandas as pd
pd.to_datetime('Mon Feb 15 2010', format='%a %b %d %Y').strftime('%d/%m/%Y')
Output:
'15/02/2010'
You may apply pandas approach for different datatypes as:
import pandas as pd
import numpy as np
def reformat_date(date_string, old_format, new_format):
return pd.to_datetime(date_string, format=old_format, errors='ignore').strftime(new_format)
date_string = 'Mon Feb 15 2010'
date_list = ['Mon Feb 15 2010', 'Wed Feb 17 2010']
date_array = np.array(date_list)
date_series = pd.Series(date_list)
old_format = '%a %b %d %Y'
new_format = '%d/%m/%Y'
print(reformat_date(date_string, old_format, new_format))
print(reformat_date(date_list, old_format, new_format).values)
print(reformat_date(date_array, old_format, new_format).values)
print(date_series.apply(lambda x: reformat_date(x, old_format, new_format)).values)
Output:
15/02/2010
['15/02/2010' '17/02/2010']
['15/02/2010' '17/02/2010']
['15/02/2010' '17/02/2010']
Just for the sake of completion: when parsing a date using strptime() and the date contains the name of a day, month, etc, be aware that you have to account for the locale.
It's mentioned as a footnote in the docs as well.
As an example:
import locale
print(locale.getlocale())
>> ('nl_BE', 'ISO8859-1')
from datetime import datetime
datetime.strptime('6-Mar-2016', '%d-%b-%Y').strftime('%Y-%m-%d')
>> ValueError: time data '6-Mar-2016' does not match format '%d-%b-%Y'
locale.setlocale(locale.LC_ALL, 'en_US')
datetime.strptime('6-Mar-2016', '%d-%b-%Y').strftime('%Y-%m-%d')
>> '2016-03-06'
use datetime library
http://docs.python.org/library/datetime.html look up 9.1.7.
especiall strptime() strftime() Behavior¶
examples
http://pleac.sourceforge.net/pleac_python/datesandtimes.html
If you dont want to define the input date format then, Install dateparser (pip install dateparser) and,
from dateparser import parse
parse("Mon Feb 15 2010").strftime("%d/%m/%Y")

How i can change date format in python [duplicate]

I have a date string with the format 'Mon Feb 15 2010'. I want to change the format to '15/02/2010'. How can I do this?
datetime module could help you with that:
datetime.datetime.strptime(date_string, format1).strftime(format2)
For the specific example you could do
>>> import datetime
>>> datetime.datetime.strptime('Mon Feb 15 2010', '%a %b %d %Y').strftime('%d/%m/%Y')
'15/02/2010'
>>>
You can install the dateutil library. Its parse function can figure out what format a string is in without having to specify the format like you do with datetime.strptime.
from dateutil.parser import parse
dt = parse('Mon Feb 15 2010')
print(dt)
# datetime.datetime(2010, 2, 15, 0, 0)
print(dt.strftime('%d/%m/%Y'))
# 15/02/2010
convert string to datetime object
from datetime import datetime
s = "2016-03-26T09:25:55.000Z"
f = "%Y-%m-%dT%H:%M:%S.%fZ"
out = datetime.strptime(s, f)
print(out)
output:
2016-03-26 09:25:55
>>> from_date="Mon Feb 15 2010"
>>> import time
>>> conv=time.strptime(from_date,"%a %b %d %Y")
>>> time.strftime("%d/%m/%Y",conv)
'15/02/2010'
As this question comes often, here is the simple explanation.
datetime or time module has two important functions.
strftime - creates a string representation of date or time from a datetime or time object.
strptime - creates a datetime or time object from a string.
In both cases, we need a formating string. It is the representation that tells how the date or time is formatted in your string.
Now lets assume we have a date object.
>>> from datetime import datetime
>>> d = datetime(2010, 2, 15)
>>> d
datetime.datetime(2010, 2, 15, 0, 0)
If we want to create a string from this date in the format 'Mon Feb 15 2010'
>>> s = d.strftime('%a %b %d %y')
>>> print s
Mon Feb 15 10
Lets assume we want to convert this s again to a datetime object.
>>> new_date = datetime.strptime(s, '%a %b %d %y')
>>> print new_date
2010-02-15 00:00:00
Refer This document all formatting directives regarding datetime.
#codeling and #user1767754 : The following two lines will work. I saw no one posted the complete solution for the example problem that was asked. Hopefully this is enough explanation.
import datetime
x = datetime.datetime.strptime("Mon Feb 15 2010", "%a %b %d %Y").strftime("%d/%m/%Y")
print(x)
Output:
15/02/2010
You may achieve this using pandas as well:
import pandas as pd
pd.to_datetime('Mon Feb 15 2010', format='%a %b %d %Y').strftime('%d/%m/%Y')
Output:
'15/02/2010'
You may apply pandas approach for different datatypes as:
import pandas as pd
import numpy as np
def reformat_date(date_string, old_format, new_format):
return pd.to_datetime(date_string, format=old_format, errors='ignore').strftime(new_format)
date_string = 'Mon Feb 15 2010'
date_list = ['Mon Feb 15 2010', 'Wed Feb 17 2010']
date_array = np.array(date_list)
date_series = pd.Series(date_list)
old_format = '%a %b %d %Y'
new_format = '%d/%m/%Y'
print(reformat_date(date_string, old_format, new_format))
print(reformat_date(date_list, old_format, new_format).values)
print(reformat_date(date_array, old_format, new_format).values)
print(date_series.apply(lambda x: reformat_date(x, old_format, new_format)).values)
Output:
15/02/2010
['15/02/2010' '17/02/2010']
['15/02/2010' '17/02/2010']
['15/02/2010' '17/02/2010']
Just for the sake of completion: when parsing a date using strptime() and the date contains the name of a day, month, etc, be aware that you have to account for the locale.
It's mentioned as a footnote in the docs as well.
As an example:
import locale
print(locale.getlocale())
>> ('nl_BE', 'ISO8859-1')
from datetime import datetime
datetime.strptime('6-Mar-2016', '%d-%b-%Y').strftime('%Y-%m-%d')
>> ValueError: time data '6-Mar-2016' does not match format '%d-%b-%Y'
locale.setlocale(locale.LC_ALL, 'en_US')
datetime.strptime('6-Mar-2016', '%d-%b-%Y').strftime('%Y-%m-%d')
>> '2016-03-06'
use datetime library
http://docs.python.org/library/datetime.html look up 9.1.7.
especiall strptime() strftime() Behavior¶
examples
http://pleac.sourceforge.net/pleac_python/datesandtimes.html
If you dont want to define the input date format then, Install dateparser (pip install dateparser) and,
from dateparser import parse
parse("Mon Feb 15 2010").strftime("%d/%m/%Y")

Python Convert unusual date string to datetime format

I have date string like this:
Saturday, 30 Nov, 2013
So it is like Day_Name, Day, Month_Name_3_Letters, Year.
I wonder what is the best way to convert it to datetime format using python?
I using like this:
datetime.strptime((row[7].split(',')[1] + row[7].split(',')[2]).replace(' ',''), "%d%b%Y").strftime("%Y-%m-%d")
Use strptime:
import datetime as dt
s = 'Saturday, 30 Nov, 2013'
d = dt.datetime.strptime(s,'%A, %d %b, %Y')
Result:
>>> d
datetime.datetime(2013, 11, 30, 0, 0)
As you'll see from the reference:
%A Weekday as locale’s full name.
%d Day of the month as a zero-padded decimal number.
%b Month as locale’s abbreviated name.
%Y Year with century as a decimal number.
You can use strptime function and initialize it as the following:
from datetime import datetime
datetime_object = datetime.strptime('Saturday, 30 Nov, 2013', '%A, %d %b, %Y')
print datetime_object
Conversely, the datetime.strptime() class method creates a datetime
object from a string representing a date and time and a corresponding
format string. datetime
In order to see how to use the formats and when, you can see strftime formats
Why don't you use dateutil's parse ?
from dateutil import parser
parser.parse('Saturday, 30 Nov, 2013')
datetime.datetime(2013, 11, 30, 0, 0)
from datetime import datetime
st='Saturday, 30 Nov, 2013'
print datetime.strptime(st,'%A, %d %b, %Y')
OUTPUT
2013-11-30 00:00:00
See strptime() at Tutorials point

Python : Converting string to datetime [duplicate]

I was trying to convert a string to a datetime object.
The string I got from a news feed is in the following format:
"Thu, 16 Oct 2014 01:16:17 EDT"
I tried using datetime.strptime() to convert it.
i.e.,
datetime.strptime('Thu, 16 Oct 2014 01:16:17 EDT','%a, %d %b %Y %H:%M:%S %Z')
And got the following error:
Traceback (most recent call last):
File "", line 1, in
datetime.strptime('Thu, 16 Oct 2014 01:16:17 EDT','%a, %d %b %Y %H:%M:%S %Z')
File "C:\Anaconda\lib_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Thu, 16 Oct 2014 01:16:17 EDT' does not match
format '%a, %d %b %Y %H:%M:%S %Z'
However, if I tried the string without "EDT", it worked.
i.e.,
datetime.strptime('Thu, 16 Oct 2014 01:16:17','%a, %d %b %Y %H:%M:%S')
Does anyone know how to parse that "EDT" part?
To parse the date in RFC 2822 format, you could use email package:
from datetime import datetime, timedelta
from email.utils import parsedate_tz, mktime_tz
timestamp = mktime_tz(parsedate_tz("Thu, 16 Oct 2014 01:16:17 EDT"))
# -> 1413436577
utc_dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
# -> datetime.datetime(2014, 10, 16, 5, 16, 17)
Note: parsedate_tz() assumes that EDT corresponds to -0400 UTC offset but it might be incorrect in Australia where EDT is +1100 (AEDT is used by pytz in this case) i.e., a timezone abbreviation may be ambiguous. See Parsing date/time string with timezone abbreviated name in Python?
Related Python bug: %Z in strptime doesn't match EST and others.
If your computer uses POSIX timestamps (likely), and you are sure the input date is within an acceptable range for your system (not too far into the future/past), and you don't need to preserve the microsecond precision then you could use datetime.utcfromtimestamp:
from datetime import datetime
from email.utils import parsedate_tz, mktime_tz
timestamp = mktime_tz(parsedate_tz("Thu, 16 Oct 2014 01:16:17 EDT"))
# -> 1413436577
utc_dt = datetime.utcfromtimestamp(timestamp)
# -> datetime.datetime(2014, 10, 16, 5, 16, 17)
The email.utils.parsedate_tz() solution is good for 3-letter timezones but it does not work for 4 letters such as AEDT or CEST. If you need a mix, the answer under Parsing date/time string with timezone abbreviated name in Python? works for both with the most commonly used time zones.

Comparing dates in Python - how to handle time zone modifiers

I am doing Python date comparizon:
Assume I have a date like this: 'Fri Aug 17 12:34:00 2012 +0000'
I am parsing it in the following manner:
dt=datetime.strptime('Fri Aug 17 12:34:00 2012 +0000', '%a %b %d %H:%M:%S %Y +0000')
I could not find on the documentation page how to handle the remaining +0000?
I want to have a more generic solution then hardcoded value.
Perhaps this is quite easy, any hint?
The default datetime module does not handle timezones very well; beyond your current machine timezone and UTC, they are basically not supported.
You'll have to use an external library for that or handle the timezone offset manually.
External library options:
Use dateutil.parser can handle just about any date and or time format you care to throw at it:
from dateutil import parser
dt = parser.parse(s)
The iso8601 library handles only ISO 8601 formats, which include timezone offsets of the same form:
import iso8601
datetimetext, tz = s.rsplit(None, 1) # only grab the timezone portion.
timezone = iso8601.iso8601.parse_timezone('{}:{}'.format(tz[:3], tz[3:]))
dt = datetime.strptime(datetimetext, '%a %b %d %H:%M:%S %Y').replace(tzinfo=timezone)
Demonstration of each approach:
>>> import datetime
>>> s = 'Fri Aug 17 12:34:00 2012 +0000'
>>> import iso8601
>>> timezone = iso8601.iso8601.parse_timezone('{}:{}'.format(tz[:3], tz[3:]))
>>> datetime.datetime.strptime(datetimetext, '%a %b %d %H:%M:%S %Y').replace(tzinfo=timezone)
datetime.datetime(2012, 8, 17, 12, 34, tzinfo=<FixedOffset '+00:00'>)
>>> from dateutil import parser
>>> parser.parse(s)
datetime.datetime(2012, 8, 17, 12, 34, tzinfo=tzutc())
You might want also give Delorean a look. Which is a wrapper around both pytz and dateutil it provides timezone manipulation as well as easy datetime time zone shift.
Here is how I would solve your question with Delorean.
>>> from delorean import parse
>>> parse("2011/01/01 00:00:00 -0700")
Delorean(datetime=2011-01-01 07:00:00+00:00, timezone=UTC)
From there you can return the datetime by simply return the .datetime attribute. If you wan to do some time shifts simply use the Delorean object and do .shift("UTC") etc.
Use the dateutil.parser:
>>> import dateutil.parser
>>> dateutil.parser.parse('Fri Aug 17 12:34:00 2012 +0000')
>>> datetime.datetime(2012, 8, 17, 12, 34, tzinfo=tzutc())

Categories