How to populate a new field with integer year extracted from date field in arcpy

833
10
Jump to solution
04-21-2020 11:17 AM
RobertTrotter
New Contributor III

I recognize this is a question that has been asked before (I have included some links and strings below that are related), but I have not found a solution, and I am likely making a mistake that is now opaque to me, so I am hoping for assistance here.

The solutions I have found seem to use Arcade, VB, and/or the GUI Field Calculator (the Field Calculator works, but I would like to automate the process in a script).

What I I would like to do is create a new field "inspectionyear", and populate it with an integer for the year, extracted from another date field "inspection_date".

Creating the new field is straight forward.

# Import modules
import arcpy, datetime # Provides access to arcpy tools
from arcpy import time
from datetime import *

# Add a new field to contain the year integer
arcpy.env.workspace = "C/DataFiles/DataSource.dbf"
arcpy.DeleteField_management("DataSource.dbf","inspectionyear") # If a field with the name "yearvalue" already exists, delete it
arcpy.AddField_management("DataSource.dbf","yearfield","INTEGER") # Create the field that will hold the year integers.

However, I have not successfully extracted the year values and added them to the new field.

I have tried using the GUI Field Calculator as shown:

The process runs and closes successfully, with no errors, however, the inspectionyear field remains populated with <NULL>

I have also tried using the VB function in arcpy

arcpy.CalculateField_management(inputtable,"inspectionyear",DatePart("yyyy",[fulldate]),"VB")

which produces:

NameError: name 'DatePart' is not defined

and I have also tried:

datevalues = datetime.datetime.strftime(!inspection_date!,"%-m/%-d/%Y")

To simply retrieve the year, but end up with a syntax error.

Can someone recommend a way to retrieve the year value, or point me in the direction of a guide?  I have already explored quite a few links, including but not limited to the following.

Arcade approach

Matching question posed by other user, but not answered

Field Calculator GUI method that ran, but did not populate the field

Info on generating datetime objects

Thank you,

Robert

0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

Using Python, try the following in your expression:

!inspection_date!.date().year

I can't remember the exact version, possibly 10.5.x, Esri switched from having Esri date fields returned as Python strings to Python datetime. 

View solution in original post

10 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Robert,

If you're date is in the following format:

8/23/2019 12:08:19 PM

You could use the following:

str(!EditDate!)[5:9]

0 Kudos
RobertTrotter
New Contributor III

Hi Jake, thanks for the suggestion, I gave it a try, but it generated the same issue the VB language generated.  The process runs and closes successfully and does not generate any errors, but the field remains blank.

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Do you have Python checked at the top of the Field Calculator?  Can you send a screen shot of the Field Calculator?

0 Kudos
RobertTrotter
New Contributor III

This is a screen shot from running it.  However, it occurs to me that this also may not work (even if it does populate the field), since it will attempt to extract characters 5 through 9, and since months and days can include 1 or 2 digits, the indices would shift.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

An ugly workaround to deal with shifting month and day lengths is to split on the separator.  If you have no 'time' you can omit the last split

z = "8/23/2019 12:08:19 PM"
z.split("/")[2].split(" ")[0]
'2019'

If you are using an alternate format then you have to adjust the slicing, as in the international standard format.

z = "2019/8/23 12:08:19 PM"

z.split("/")[0]
'2019'
0 Kudos
RobertTrotter
New Contributor III

That makes sense (and I am happy for a solution, ugly, elegant, or just odd), however would this approach require me to loop through each feature/row in the table, updating the value?  It seems odd that there is not simply a function to export a year from a date field as a "FLOAT", or other format.

Is datetime.datetime.strftime(!fulldate!, "%-m/%-d/%Y") the right tree to be barking up to extract the year?

I appreciate your time with this, I am learning how little I know about arcpy.

Robert

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Maybe this will help.  The format is for my datetime settings

n = datetime.datetime.now()
now_str = datetime.datetime.strftime(n, "%Y-%m-%d")
now_str.split("-")[0]
'2020'
0 Kudos
RobertTrotter
New Contributor III

Two more failed efforts.

Using the Field Calculator GUI, the VB code:

year = DatePart("yyyy",[fulldate])

seems to work.

But, using the arcpy line

arcpy.CalculateField_management(datatable,year,DatePart("yyyy",[fulldate]),"VB")

generates the error

arcpy.CalculateField_management(datatable,year,DatePart("yyyy",[fulldate]),"VB")
NameError: name 'DatePart' is not defined

It is not clear to my why the VB script is not working.  But as an alternative, it seems that I could instead use

arcpy.CalculateField_management(datatable,year,expression,"Python_9_3"),

and use something like

expression = !fulldate!.year

since the field fulldate is already defined as a date field?

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Date fields—ArcGIS Pro | Documentation 

There are dates, then there are dates.  Which is why I avoid using date fields, and convert to string

As for VB, not used in ArcGIS Pro any more, and I haven't used ArcMap in years, so I can't help you out.

I guess no one else is jumping in, so I can only wish you good luck.

0 Kudos