Parses (almost) standard ISO 8601 date strings. The differences are:
-
The date "20100312" is parsed as the year 20100312, not as equivalent to "2010-03-12". The '-' in the dates are not optional.
-
Only seconds may have a decimal point, with up to 18 digits after it (maximum attoseconds precision).
-
Either a 'T' as in ISO 8601 or a ' ' may be used to separate the date and the time. Both are treated equivalently.
-
Doesn't (yet) handle the "YYYY-DDD" or "YYYY-Www" formats.
-
Doesn't handle leap seconds (seconds value has 60 in these cases).
-
Doesn't handle 24:00:00 as synonym for midnight (00:00:00) tomorrow
-
Accepts special values "NaT" (not a time), "Today", (current day according to local time) and "Now" (current time in UTC).
'str' must be a NULL-terminated string, and 'len' must be its length. 'unit' should contain -1 if the unit is unknown, or the unit
System Message: ERROR/3 (<string>
, line 17) Unexpected indentation.
<blockquote> which will be used if it is.</blockquote>
System Message: WARNING/2 (<string>
, line 18) Block quote ends without a blank line; unexpected unindent.
- 'casting' controls how the detected unit from the string is allowed
- to be cast to the 'unit' parameter.
'out' gets filled with the parsed date-time. 'out_local' gets set to 1 if the parsed time was in local time,
System Message: ERROR/3 (<string>
, line 23) Unexpected indentation.
<blockquote> to 0 otherwise. The values 'now' and 'today' don't get counted as local, and neither do UTC +/-#### timezone offsets, because they aren't using the computer's local timezone offset.</blockquote>
System Message: WARNING/2 (<string>
, line 26) Block quote ends without a blank line; unexpected unindent.
- 'out_bestunit' gives a suggested unit based on the amount of
- resolution provided in the string, or -1 for NaT.
- 'out_special' gets set to 1 if the parsed time was 'today',
- 'now', or ''/'NaT'. For 'today', the unit recommended is 'D', for 'now', the unit recommended is 's', and for 'NaT' the unit recommended is 'Y'.
Returns 0 on success, -1 on failure.
Initialize the output to all zeros
Convert the empty string and case-variants of "NaT" to not-a-time. Tried to use PyOS_stricmp, but that function appears to be broken, not even matching the strcmp function signature as it should.
Indicate that this was a special value, and recommend generic units.
The string "today" means take today's date in local time, and convert it to a date representation. This date representation, if forced into a time unit, will be at midnight UTC. This is perhaps a little weird, but done so that the 'datetime64[D]' type produces the date you expect, rather than switching to an adjacent day depending on the current time and your timezone.
Other platforms may require something else
Indicate that this was a special value, and is a date (unit 'D').
Check the casting rule
The string "now" resolves to the current UTC time
Set up a dummy metadata for the conversion
Indicate that this was a special value, and use 's' because the time() function has resolution seconds.
Check the casting rule
Anything else isn't a special value
Skip leading whitespace
Leading '-' sign for negative year
PARSE THE YEAR (digits until the '-' character)
Negate the year if necessary
Check whether it's a leap-year
Next character must be a '-' or the end of the string
Can't have a trailing '-'
PARSE THE MONTH (2 digits)
Next character must be a '-' or the end of the string
Can't have a trailing '-'
PARSE THE DAY (2 digits)
Next character must be a 'T', ' ', or end of string
PARSE THE HOURS (2 digits)
Next character must be a ':' or the end of the string
Can't have a trailing ':'
PARSE THE MINUTES (2 digits)
Next character must be a ':' or the end of the string
Can't have a trailing ':'
PARSE THE SECONDS (2 digits)
Next character may be a '.' indicating fractional seconds
PARSE THE MICROSECONDS (0 to 6 digits)
PARSE THE PICOSECONDS (0 to 6 digits)
PARSE THE ATTOSECONDS (0 to 6 digits)
ISO 8601 states to treat date-times without a timezone offset or 'Z' for UTC as local time. The C standard libary functions mktime and gmtime allow us to do this conversion.
Only do this timezone adjustment for recent and future years.
mktime converts a local 'struct tm' into a time_t
gmtime converts a 'time_t' into a UTC 'struct tm'
Other platforms may require something else
Since neither "Z" nor a time-zone was specified, it's local
UTC specifier
"Z" means not local
Time zone offset
Since "local" means local with respect to the current machine, we say this is non-local.
The hours offset
The minutes offset is optional
Optional ':'
The minutes offset (at the end of the string)
Apply the time zone offset
Skip trailing whitespace
Check the casting rule
References NPY_DATETIME_NAT, NPY_FR_GENERIC, and npy_datetimestruct::year.
Referenced by _strided_to_strided_datetime_general_cast().