JNN
JNN

Reputation: 131

Unable to extract season from date attribute in shapefile

I have a point shapefile with the following attributes:

FID    REPORT_DAT     Season
0       8/23/2018     
1       9/23/2020     
2       1/23/2020     

The REPORT_DAT in esri has a data type of date but apparently it's a str when I print it out in the python console. I'm trying to fill in the Season field based on a specified date range using python. Here's what I have so far:

        import arcpy
from datetime import date, datetime


arcpy.env.overwriteOutput = True

fc = r"C:\Users\RoadKill.shp"
#arcpy.AddField_management("roadkill", "Season", "TEXT", "", "", "20")  

seasons = {'spring':(datetime(2020,03,30), datetime(2020,04,13)),
           'summer':(datetime(2020,04,14), datetime(2020,10,31)),
           'autumn':(datetime(2020,11,01), datetime(2020,11,17)),
           'winter':(datetime(2018,11,17), datetime(2019,03,29))}


rows = arcpy.SearchCursor(fc)
for row in rows:
    datetimeVal = row.getValue("REPORT_DAT")
    formattedTime = datetime.strftime(datetimeVal, "%Y/%m/%d")
    datetime = datetime.strptime(formattedTime, "%Y/%m/%d").date()
    print(datetime, type(datetime))
    

    def get_season(datetime):
        print(datetime, type(datetime))
        for season,(season_start, season_end) in seasons.items():
            if datetime>=season_start and datetime<= season_end:
                return season


    arcpy.CalculateField_management("roadkill", "Season", get_season("REPORT_DAT"), "PYTHON_9.3", "")

My print statement prints out:

(datetime.date(2018, 8, 23), <type 'datetime.date'>)
('REPORT_DAT', <type 'str'>)

I thought I converted the date to the right format above and passed it to the REPORT_DAT field but I'm still getting this error:

         line 19, in get_season
                   if datetime>=season_start and datetime<= season_end:
TypeError: can't compare datetime.datetime to str

Any suggestions on how to properly convert my date field?

Upvotes: 1

Views: 242

Answers (2)

Tobin
Tobin

Reputation: 2149

You must convert your dates before any comparison. You can try this:

# First harmonize your seasons dates by replacing date by datetime

seasons = {'spring':(datetime(2020,03,30), datetime(2020,04,13)),
           'summer':(datetime(2020,04,14), datetime(2020,10,31)),
           'autumn':(datetime(2020,11,01), datetime(2020,11,17)),
           'winter':(datetime(2020,11,17), datetime(2020,03,29))}

def date_conversion(my_date):
    values = my_date.split('/')
    year, month, day = int(values[0]), int(values[1]), int(values[2])
    return datetime(year, month, day)

# rename the variable date by my_date
def get_season(my_date):
    my_date = date_conversion(my_date)
    for season, (season_start, season_end) in seasons.items():
        # Refine your comparison
        if season_start <= my_date <= season_end:
            # You should return season, not seasons
            return season

Upvotes: 3

JNN
JNN

Reputation: 131

I ended up using an update cursor to solve my issue.

with arcpy.da.UpdateCursor(fc, fields) as cursor:
    for row in cursor:
        myDate = datetime.strptime(datetime.strftime(row[0], "%m/%d/%Y"), "%m/%d/%Y")
        if (myDate >= datetime.strptime("03/30/2020", "%m/%d/%Y") and myDate <= datetime.strptime("04/13/2020", "%m/%d/%Y")):
            row[1] = "SPRING"
        elif (myDate >= datetime.strptime("04/14/2020", "%m/%d/%Y")and myDate <= datetime.strptime("10/31/2020", "%m/%d/%Y")):
            row[1] = "SUMMER"
        elif (myDate >= datetime.strptime("02/06/2020", "%m/%d/%Y") and myDate <= datetime.strptime("01/10/2020", "%m/%d/%Y")):
            row[1] = "FALL"
        elif (myDate >= datetime.strptime("02/10/2020", "%m/%d/%Y")):
            row[1] = "WINTER"

        cursor.updateRow(row)

Upvotes: 1

Related Questions