Convert strange date format to standard date format - python

In Sweden we sometimes use a strange date format, for example New Year is the 31/12. If I have this format as a string ,which can be any date between 1/1 and 31/12, and if we assume that it is this year, how do I get into a standard date format using Python (format as 2012-01-01 and 2012-12-31) that can be sore in be stored as a date in a mySQL database.

Simply split the two values, map them to integers and update a datetime.date() instance:
import datetime
day, month = map(int, yourvalue.split('/'))
adate = datetime.date.today().replace(month=month, day=day)
By using datetime.date.today() we get the current year.
Demo:
>>> import datetime
>>> somevalue = '31/12'
>>> day, month = map(int, somevalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 12, 31)
>>> someothervalue = '1/1'
>>> day, month = map(int, someothervalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 1, 1)
Alternatively, you could use the datetime.strptime() method to parse these dates, but you'll have to manually correct the year afterwards (it'll use 1900 as the default if no year is being parsed):
adate = datetime.datetime.strptime(yourvalue, '%d/%m').date()
adate = adate.replace(year=datetime.date.today().year)

There is nothing strange about this format :)
You can use the datetime module:
import datetime
d = datetime.datetime.strptime('31/12', '%d/%m').date().replace(year=2012)
print d
>> datetime.date(2012, 12, 31)

Related

Format Pandas datetime column as year-week [duplicate]

Please what's wrong with my code:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)
Display "2013-01-01 00:00:00", Thanks.
A week number is not enough to generate a date; you need a day of the week as well. Add a default:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)
The -1 and -%w pattern tells the parser to pick the Monday in that week. This outputs:
2013-07-01 00:00:00
%W uses Monday as the first day of the week. While you can pick your own weekday, you may get unexpected results if you deviate from that.
See the strftime() and strptime() behaviour section in the documentation, footnote 4:
When used with the strptime() method, %U and %W are only used in calculations when the day of the week and the year are specified.
Note, if your week number is a ISO week date, you'll want to use %G-W%V-%u instead! Those directives require Python 3.6 or newer.
In Python 3.8 there is the handy datetime.date.fromisocalendar:
>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1) # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)
In older Python versions (3.7-) the calculation can use the information from datetime.date.isocalendar to figure out the week ISO8601 compliant weeks:
from datetime import date, timedelta
def monday_of_calenderweek(year, week):
first = date(year, 1, 1)
base = 1 if first.isocalendar()[1] == 1 else 8
return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))
Both works also with datetime.datetime.
To complete the other answers - if you are using ISO week numbers, this string is appropriate (to get the Monday of a given ISO week number):
import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)
%G, %V, %u are ISO equivalents of %Y, %W, %w, so this outputs:
2013-06-24 00:00:00
Availabe in Python 3.6+; from docs.
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res
Adding of 1 as week day will yield exact current week start. Adding of timedelta(days=6) will gives you the week end.
datetime.datetime(2018, 7, 23)
If anyone is looking for a simple function that returns all working days (Mo-Fr) dates from a week number consider this (based on accepted answer)
import datetime
def weeknum_to_dates(weeknum):
return [datetime.datetime.strptime("2021-W"+ str(weeknum) + str(x), "%Y-W%W-%w").strftime('%d.%m.%Y') for x in range(-5,0)]
weeknum_to_dates(37)
Output:
['17.09.2021', '16.09.2021', '15.09.2021', '14.09.2021', '13.09.2021']
In case you have the yearly number of week, just add the number of weeks to the first day of the year.
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)
Another solution which worked for me that accepts series data as opposed to strptime only accepting single string values:
#fw_to_date
import datetime
import pandas as pd
# fw is input in format 'YYYY-WW'
# Add weekday number to string 1 = Monday
fw = fw + '-1'
# dt is output column
# Use %G-%V-%w if input is in ISO format
dt = pd.to_datetime(fw, format='%Y-%W-%w', errors='coerce')
Here's a handy function including the issue with zero-week.

Convert month to integer in python

I'm trying to find the difference between these two dates or any other dates for that matter
a = '11-Feb-2003'
b = '28-Aug-2015'
I'm looking for a way (something not so manual/diy) to convert the months (Feb & August) into integers?
Should I create a dictionary?
To be even more specific I'd like to turn the dates into lists.
'11-Feb-2003' becomes [11, 2, 2003] = startdate
'28-Aug-2015' becomes [28, 8, 2015] = enddate
From there I can calculate the difference in number of days between the two by executing:
import datetime
datetime.date(enddate[2], enddate[1], enddate[0]) -
dateimdate(startdate[2], startdate[1], startdate[0])
You can use Python's datetime module to convert a string to a date object.
The strptime function takes a string and the format of the date.
from datetime import datetime
print datetime.strptime('11-Feb-2003', '%d-%b-%Y')
%d is for Day of the month as a zero-padded decimal number. (01, 02, ..., 31)
%b is for Month as locale’s abbreviated name. (Jan, Feb, ..., Dec)
%Y is for Year with century as a decimal number. (1970, 1988, 2001, 2013)
Here is a list of all the format specifiers for your reference.
To find the difference between two strings that represent dates, you first need to convert them to Python's date type, then simply subtract them:
>>> import datetime
>>> s1 = '11-Feb-2003'
>>> s2 = '28-Aug-2015'
>>> d1 = datetime.datetime.strptime(s1, '%d-%b-%Y')
>>> d2 = datetime.datetime.strptime(s2, '%d-%b-%Y')
Now, once your subtract the two datetime objects, you'll get a special datetime.timedelta object:
>>> i = d2-d1
>>> i
datetime.timedelta(4581)
You can get a friendly representation of the difference if you print the object (or convert it to a string):
>>> print(i)
4581 days, 0:00:00
You can also query the object, for example:
>>> i.days
4581
You can use strptime.
import datetime as d
d.datetime.strptime(a, '%d-%b-%Y')
#=> datetime.datetime(2003, 2, 11, 0, 0)
you can use time module:
>>> import time
>>> a = '11-Feb-2003'
>>> b = '28-Aug-2015'
>>> time.strptime(a, "%d-%b-%Y") # %b Locale’s abbreviated month name.
time.struct_time(tm_year=2003, tm_mon=2, tm_mday=11, tm_hour=0,tm_min=0, tm_sec=0, tm_wday=1, tm_yday=42, tm_isdst=-1)
>>> my_date = time.strptime(a, "%d-%b-%Y")
>>> "{}-{}-{}".format(my_date.tm_mday, my_date.tm_mon, my_date.tm_year)
'11-2-2003'
You can use the split function:
a.split("-")
and that will return:
["11", "Feb", "2003"]
import datetime
datetime.datetime.strptime(month, '%B').month
Use %B for full name of the month (e.g. January), %b for short version (e.g. Jan)

convert time in Python

I am parsing an xml file in python and I need to convert the following date and time format to something human-friendly:
<due_date>735444</due_date>
<due_time>55800</due_time>
The format of date seems to be number of days since year 0, and time is the number of seconds since midnight.
How could I convert it into some standard format, such as 2014-07-30 15:30:00 ?
Use datetime.datetime.fromordinal() plus a timedelta() for the seconds after midnight:
import datetime
dt = datetime.datetime.fromordinal(due_date) + datetime.timedelta(seconds=due_time)
Your due_date is relative to the year 1 instead, as your values fit to produce your expected date:
>>> import datetime
>>> due_date = 735444
>>> due_time = 55800
>>> datetime.datetime.fromordinal(due_date) + datetime.timedelta(seconds=due_time)
datetime.datetime(2014, 7, 30, 15, 30)

Converting datetime to strptime

I'm pulling a timestamp that looks like this - 2014-02-03T19:24:07Z
I'm trying to calculate the number of days since January 1.
I was able to convert it to datetime using
yourdate = dateutil.parser.parse(timestamp)
But now I'm trying to parse it and grab individual elements, such as the month & day.
Is there a way to convert it to strptime so I can select each element?
Just access the month, day using year, month, day attributes..
>>> import dateutil.parser
>>> yourdate = dateutil.parser.parse('2014-02-03T19:24:07Z')
>>> yourdate.year
2014
>>> yourdate.month
2
>>> yourdate.day
3
Just to be a little more complete:
>>> from dateutil.parser import parse
>>> from datetime import datetime
>>> import pytz
>>> d = parse('2014-02-03T19:24:07Z')
>>> other = datetime(year=2014, month=1, day=1, tzinfo=pytz.utc)
>>> (d-other).days
33
You have to make sure the other datetime is timezone aware if you're creating it with datetime as opposed to the datetime you're parsing with dateutil.
There's no need for converting. The resulting datetime.datetime object has all necessary properties which you can access directly. For example:
>>> import dateutil.parser
>>> timestamp="2014-02-03T19:24:07Z"
>>> yourdate = dateutil.parser.parse(timestamp)
>>> yourdate.day
3
>>> yourdate.month
2
See: https://docs.python.org/2/library/datetime.html#datetime-objects
if you want to calculate:
import dateutil.parser
yourdate = dateutil.parser.parse('2014-02-03T19:24:07Z')
startdate = dateutil.parser.parse('2014-01-01T00:00:00Z')
print (yourdate - startdate)
Another way to solve without the dateutil module:
import datetime
# start date for comparision
start = datetime.date(2014, 1, 1)
# timestamp as string
datefmt = "%Y-%m-%dT%H:%M:%SZ"
current = "2014-02-03T19:24:07Z"
# convert timestamp string to date, dropping time
end = datetime.datetime.strptime(current, datefmt).date()
# compare dates and get number of days from timedelta object
days = (end - start).days
This assumes you don't care about time (including timezones).

Converting week numbers to dates

Say I have a week number of a given year (e.g. week number 6 of 2014).
How can I convert this to the date of the Monday that starts that week?
One brute force solution I thought of would be to go through all Mondays of the year:
date1 = datetime.date(1,1,2014)
date2 = datetime.date(12,31,2014)
def monday_range(date1,date2):
while date1 < date2:
if date1.weekday() == 0:
yield date1
date1 = date1 + timedelta(days=1)
and store a hash from the first to the last Monday of the year, but this wouldn't do it, since, the first week of the year may not contain a Monday.
You could just feed the data into time.asctime().
>>> import time
>>> week = 6
>>> year = 2014
>>> atime = time.asctime(time.strptime('{} {} 1'.format(year, week), '%Y %W %w'))
>>> atime
'Mon Feb 10 00:00:00 2014'
EDIT:
To convert this to a datetime.date object:
>>> datetime.datetime.fromtimestamp(time.mktime(atime)).date()
datetime.date(2014, 2, 10)
All about strptime \ strftime:
https://docs.python.org/2/library/datetime.html
mytime.strftime('%U') #for W\C Monday
mytime.strftime('%W') #for W\C Sunday
Sorry wrong way around
from datetime import datetime
mytime=datetime.strptime('2012W6 MON'. '%YW%U %a')
Strptime needs to see both the year and the weekday to do this. I'm assuming you've got weekly data so just add 'mon' to the end of the string.
Enjoy
A simple function to get the Monday, given a date.
def get_monday(dte):
return dte - datetime.timedelta(days = dte.weekday())
Some sample output:
>>> get_monday(date1)
datetime.date(2013, 12, 30)
>>> get_monday(date2)
datetime.date(2014, 12, 29)
Call this function within your loop.
We can just add the number of weeks to the first day of the year.
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)
To piggyback and give a different version of the answer #anon582847382 gave, you can do something like the below code if you're creating a function for it and the week number is given like "11-2023":
import time
from datetime import datetime
def get_date_from_week_number(str_value):
temp_str = time.asctime(time.strptime('{} {} 1'.format(str_value[3:7], str_value[0:2]), '%Y %W %w'))
return datetime.strptime(temp_str, '%a %b %d %H:%M:%S %Y').date()

Categories