EasyCalculate is a free set of 100+ field calculator scripts, definitely check them out: http://www.ian-ko.com/free/free_arcgis.htm
The only way I have found to avoid using the Project tool to do a conversion from a spatial projection that uses linear units (like State Plane coordinates) to angular units (like Decimal Degrees) is using the Geoprocessing Environment settings to set up any transformation option and the spatial reference parameter of a Python UpdateCursor. If you have ArcGIS Desktop 10.1 or later you should only use a Data Access UpdateCursor (da UpdateCursor), not the original Python UpdateCursor syntax.
A note of warning, if you use this approach with an XY Event layer that has its original coordinates in linear units, like State Plane coordinates, you need to first duplicate those coordinates into a pair of new fields that you want to hold your Latitude (Y coordinate) and Longitude (X coordinate) and use those new fields with the XY Event Layer tool, because if you include the SHAPE@X or SHAPE@Y feilds in the UpdateCursor field list and use the updateRow method, the fields used to set the coordinates of the XY Event Layer will convert and be overwritten with new coordinate values that match the new spatial reference and transformation.
The script below can create a new Latitude and Longitude field in an XY Event Layer table that has only State Plane coordinates, make a copy of the original state plane coordinates into the new Latitude and Longitude fields, and use an XY Event layer and a da UpdateCursor opened with a different spatial reference to convert the values in the Latitude and Longitude fields into the coordinates matching the new spatial reference. It can run the entire script to process over 131K records in an XY Event Layer in approximately 36 seconds, which is about 5 to 10 times faster than methods that used to use the Field Calculator.
# Import arcpy module
from time import strftime
print "Start script: " + strftime("%Y-%m-%d %H:%M:%S")
import arcpy
# Set or comment out Geographic Transformation
arcpy.env.geographicTransformations = "NAD_1983_To_WGS_1984_5"
# Use a table with State Plane NAD 83 coordinates
fc = r"C:\Users\RFAIRHUR\Documents\ArcGIS\DEFAULT.gdb\CL_INTERSECTIONS_PAIRS"
print "Finished Setup: " + strftime("%Y-%m-%d %H:%M:%S")
# Process: Add Latitude Field
arcpy.AddField_management(fc, "LATITUDE", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
# Process: Add Longitude Field
arcpy.AddField_management(fc, "LONGITUDE", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
print "Finish Adding Fields: " + strftime("%Y-%m-%d %H:%M:%S")
# Specify original X and Y fields and corresponding Longitude and Latitude output fields.
fields = ( 'LONGITUDE', 'X_COORD', 'LATITUDE', 'Y_COORD')
#Open a da UpdateCursor and duplicate the X and Y coordinates in the Longitude and Latitude fields.
with arcpy.da.UpdateCursor(fc, fields) as updateRows:
for updateRow in updateRows:
updateRow[0] = updateRow[1]
updateRow[2] = updateRow[3]
updateRows.updateRow(updateRow)
print "Finished UpdateCursor Longitude and Latitude edits " + strftime("%Y-%m-%d %H:%M:%S")
# Set a name for your XY Event Layer
CL_INTERSECTIONS_PAIRS_Events = "CL_INTERSECTIONS_PAIRS Events"
# Make an X/Y Event Layer with NAD 83 projection.
arcpy.MakeXYEventLayer_management(fc, "LONGITUDE", "LATITUDE", CL_INTERSECTIONS_PAIRS_Events, "PROJCS['NAD_1983_StatePlane_California_VI_FIPS_0406_Feet',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',6561666.666666666],PARAMETER['False_Northing',1640416.666666667],PARAMETER['Central_Meridian',-116.25],PARAMETER['Standard_Parallel_1',32.78333333333333],PARAMETER['Standard_Parallel_2',33.88333333333333],PARAMETER['Latitude_Of_Origin',32.16666666666666],UNIT['Foot_US',0.3048006096012192]];-118608900 -91259500 3048.00609601219;-100000 10000;-100000 10000;3.28083333333333E-03;0.001;0.001;IsHighPrecision", "")
print "Finished Making XY Event Layer: " + strftime("%Y-%m-%d %H:%M:%S")
# Use the Event layer as the cursor input
fcl = CL_INTERSECTIONS_PAIRS_Events
# Specify shape coordinate fields.
fields = ("SHAPE@X", "SHAPE@Y")
# Specify the Spatial Reference of the Cursor
latLonRef = "Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj"
# Create update cursor for feature class with a new Spatial Reference.
with arcpy.da.UpdateCursor(fcl, fields, ' ', latLonRef) as updateRows:
for updateRow in updateRows:
# Lat and Long convert just by using the updateRow method on the Shape fields
updateRows.updateRow(updateRow)
print "Finished Converting Longitude and Latitude fields: " + strftime("%Y-%m-%d %H:%M:%S")
# The coordinates in the Longitude and Latitude fields are now converted to Decimal Degrees.
print "Finish script: " + strftime("%Y-%m-%d %H:%M:%S")
Below is a script that adds a Latitude and Longitude field to a State Plane NAD 83 Point Feature Class and using an UpdateCursor with a different spatial reference is able to fill those fields in with the Decimal Degree coordinates of a WGS 1984 spatial reference. The underly geometry of the points is unaffected by the script. The entire script takes approximately 25 seconds to run on over 131K points.
from time import strftime
print "Start script: " + strftime("%Y-%m-%d %H:%M:%S")
import arcpy
# Set or comment out Geographic Transformation
arcpy.env.geographicTransformations = "NAD_1983_To_WGS_1984_5"
# Use a table with State Plane NAD 83 coordinates
fc = r"C:\Users\RFAIRHUR\Documents\ArcGIS\DEFAULT.gdb\CL_INT_PAIRS_POINTS"
print "Finished Setup: " + strftime("%Y-%m-%d %H:%M:%S")
# Process: Add Latitude Field
arcpy.AddField_management(fc, "LATITUDE", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
# Process: Add Longitude Field
arcpy.AddField_management(fc, "LONGITUDE", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
print "Finish Adding Fields: " + strftime("%Y-%m-%d %H:%M:%S")
# Specify shape coordinate fields.
fields = ("LONGITUDE", "SHAPE@X", "LATITUDE", "SHAPE@Y")
# Specify the Spatial Reference of the Cursor
latLonRef = "Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj"
# Create update cursor for feature class with a new Spatial Reference.
with arcpy.da.UpdateCursor(fc, fields, ' ', latLonRef) as updateRows:
for updateRow in updateRows:
updateRow[0] = updateRow[1]
updateRow[2] = updateRow[3]
updateRows.updateRow(updateRow)
print "Finished Converting Longitude and Latitude fields: " + strftime("%Y-%m-%d %H:%M:%S")
# The coordinates in the Longitude and Latitude fields are now converted to Decimal Degrees.
print "Finish script: " + strftime("%Y-%m-%d %H:%M:%S")