One of the main pain points I've been having so far with using Python with FME is getting datetime attributes from features as datetimes in Python. FME datetimes normally have a sub-second precision of 7 digits, up to 9, but Python stops parsing after 6.
"When used with the strptime() method, the %f directive accepts from one to six digits and zero pads on the right. %f is an extension to the set of format characters in the C standard (but implemented separately in datetime objects, and therefore always available)."
#
# Unzoned
#
a_timestamp = feature.getAttribute('a_timestamp')
print(repr(a_timestamp)) # '20230620161403.0020449'
# ValueError: unconverted data remains: 9
# (Python's strptime stops at 6 decimals)
# (This will randomly work once out of 10 because trailing zeroes are trimmed)
# datetime.strptime(a_timestamp, '%Y%m%d%H%M%S.%f')
# This shouldn't be that complicated!
# Also, the dot in the format string means this will break
# if no seconds decimals are present
datetime.strptime(a_timestamp<0:21], '%Y%m%d%H%M%S.%f')
#
# Zoned
#
a_zoned_timestamp = feature.getAttribute('a_zoned_timestamp')
print(repr(a_zoned_timestamp)) # '20230620204757.833922+00:00'
# ValueError: time data '20230620205748.6822671+00:00' does not match format '%Y%m%d%H%M%S.%f%z'
#datetime.strptime(a_zoned_timestamp, '%Y%m%d%H%M%S.%f%z')
# It works... *but at what cost?*
# That also has 1/100 chance to break if the timestamp has 2 trailing zeroes
# and is trimmed to 5 fractionnal digits
datetime.strptime(a_zoned_timestampa0:21] + a_zoned_timestamp -6:], '%Y%m%d%H%M%S.%f%z')
Even if that wasn't an issue, having to constantly go back and forth between parsing and formatting datetimes makes manipulating these needlessly complicated. I'm surprised feature.getAttribute() can't handle auto-converting to/from Python's standard datetime class.
from datetime import datetime
#
# Wishful thinking :(
#
# TypeError: desired type must be bool, int, float, str, bytes, bytearray
a_timestamp = feature.getAttribute('a_timestamp', datetime)
Am I missing something regarding the "obvious" way of dealing with this? Even discounting the length issues, the string parsing/formatting dance gets old pretty quickly. Even just some fmeobjects.STRPTIME_DATETIMETZ_FORMAT constant would be a huge time saver, here.