Search code examples
pythonpython-2.7datetimematplotlibstrptime

how to work around "ValueError: day is out of range for month" with imaginary dates?


ok so I have a list of dates , and i have a list of sales . I want to use matplotlib to plot the values

import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

dateFormat = findDateFormat()

print dateFormat      #DEBUG#

x = [dt.datetime.strptime(d,dateFormat).date() for d in listOfDates]
y = listOfSales

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter(dateFormat))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.plot(x,y)
plt.gcf().autofmt_xdate()

findDateFormat() is a function that I created and it return a string that contains the format and i tested it to be okay %d/%m/%Y. when I run the script I got the error

ValueError: day is out of range for month

now I know the reason for that is the dates in the list are not real and some one them do not actually exist (31,6,2016 for example). is there a way to work around this so it just ignores the dates that do not actualy exist?

EDIT I just created this function:

def validateDates(dateFormat):

    itemsToDelete = []

    for i in range(0,len(listOfDates)):
        try:
            dt.datetime.strptime(listOfDates[i], dateFormat)
        except ValueError:
            print listOfDates[i] + "Has been deleted because it does not exist."
            itemsToDelete.append(i)

    for k in range(0,len(itemsToDelete)):
        del listOfDates[itemsToDelete[k]]
        del listOfSales[itemsToDelete[k]]

To get rid of non-existent dates before using this in the plot, but I still get same error message.


Solution

  • I would just ignore them by this way(if len(listOfDates) == len(listOfSales)):

    from datetime import datetime
    x = []
    y = []
    
    for d, sale in zip(listOfDates, listOfSales):
        try:
            x.append(datetime.strptime(d, dateFormat).date())
            y.append(sale/10)
        except ValueError:
            continue
    

    validateDates method may as follows:

    def validateDates(dateFormat, listOfDates, listOfSales):
        dates, sales = [], []    
        for d, s in zip(listOfDates, listOfSales):
            try:
                datetime.strptime(d, dateFormat)
            except ValueError:
                continue
            dates.append(d)
            sales.append(s)
        return dates, sales
    
    listOfDates, listOfSales = validateDates(dateFormat, listOfDates, listOfSales)