numpy  2.0.0
src/multiarray/_datetime.h
Go to the documentation of this file.
00001 #ifndef _NPY_PRIVATE__DATETIME_H_
00002 #define _NPY_PRIVATE__DATETIME_H_
00003 
00004 #ifdef NPY_ENABLE_SEPARATE_COMPILATION
00005 extern NPY_NO_EXPORT char *_datetime_strings[NPY_DATETIME_NUMUNITS];
00006 extern NPY_NO_EXPORT int _days_per_month_table[2][12];
00007 #else
00008 NPY_NO_EXPORT char *_datetime_strings[NPY_DATETIME_NUMUNITS];
00009 NPY_NO_EXPORT int _days_per_month_table[2][12];
00010 #endif
00011 
00012 NPY_NO_EXPORT void
00013 numpy_pydatetime_import();
00014 
00015 /*
00016  * Returns 1 if the given year is a leap year, 0 otherwise.
00017  */
00018 NPY_NO_EXPORT int
00019 is_leapyear(npy_int64 year);
00020 
00021 /*
00022  * Calculates the days offset from the 1970 epoch.
00023  */
00024 NPY_NO_EXPORT npy_int64
00025 get_datetimestruct_days(const npy_datetimestruct *dts);
00026 
00027 /*
00028  * Creates a datetime or timedelta dtype using a copy of the provided metadata.
00029  */
00030 NPY_NO_EXPORT PyArray_Descr *
00031 create_datetime_dtype(int type_num, PyArray_DatetimeMetaData *meta);
00032 
00033 /*
00034  * Creates a datetime or timedelta dtype using the given unit.
00035  */
00036 NPY_NO_EXPORT PyArray_Descr *
00037 create_datetime_dtype_with_unit(int type_num, NPY_DATETIMEUNIT unit);
00038 
00039 /*
00040  * This function returns a pointer to the DateTimeMetaData
00041  * contained within the provided datetime dtype.
00042  */
00043 NPY_NO_EXPORT PyArray_DatetimeMetaData *
00044 get_datetime_metadata_from_dtype(PyArray_Descr *dtype);
00045 
00046 /*
00047  * Both type1 and type2 must be either NPY_DATETIME or NPY_TIMEDELTA.
00048  * Applies the type promotion rules between the two types, returning
00049  * the promoted type.
00050  */
00051 NPY_NO_EXPORT PyArray_Descr *
00052 datetime_type_promotion(PyArray_Descr *type1, PyArray_Descr *type2);
00053 
00054 /*
00055  * Converts a datetime from a datetimestruct to a datetime based
00056  * on some metadata.
00057  */
00058 NPY_NO_EXPORT int
00059 convert_datetimestruct_to_datetime(PyArray_DatetimeMetaData *meta,
00060                                     const npy_datetimestruct *dts,
00061                                     npy_datetime *out);
00062 
00063 /*
00064  * Extracts the month number, within the current year,
00065  * from a 'datetime64[D]' value. January is 1, etc.
00066  */
00067 NPY_NO_EXPORT int
00068 days_to_month_number(npy_datetime days);
00069 
00070 /*
00071  * Parses the metadata string into the metadata C structure.
00072  *
00073  * Returns 0 on success, -1 on failure.
00074  */
00075 NPY_NO_EXPORT int
00076 parse_datetime_metadata_from_metastr(char *metastr, Py_ssize_t len,
00077                                     PyArray_DatetimeMetaData *out_meta);
00078 
00079 
00080 /*
00081  * Converts a datetype dtype string into a dtype descr object.
00082  * The "type" string should be NULL-terminated, and len should
00083  * contain its string length.
00084  */
00085 NPY_NO_EXPORT PyArray_Descr *
00086 parse_dtype_from_datetime_typestr(char *typestr, Py_ssize_t len);
00087 
00088 /*
00089  * Converts a substring given by 'str' and 'len' into
00090  * a date time unit enum value. The 'metastr' parameter
00091  * is used for error messages, and may be NULL.
00092  *
00093  * Returns 0 on success, -1 on failure.
00094  */
00095 NPY_NO_EXPORT NPY_DATETIMEUNIT
00096 parse_datetime_unit_from_string(char *str, Py_ssize_t len, char *metastr);
00097 
00098 /*
00099  * Translate divisors into multiples of smaller units.
00100  * 'metastr' is used for the error message if the divisor doesn't work,
00101  * and can be NULL if the metadata didn't come from a string.
00102  *
00103  * Returns 0 on success, -1 on failure.
00104  */
00105 NPY_NO_EXPORT int
00106 convert_datetime_divisor_to_multiple(PyArray_DatetimeMetaData *meta,
00107                                     int den, char *metastr);
00108 
00109 /*
00110  * Determines whether the 'divisor' metadata divides evenly into
00111  * the 'dividend' metadata.
00112  */
00113 NPY_NO_EXPORT npy_bool
00114 datetime_metadata_divides(
00115                         PyArray_DatetimeMetaData *dividend,
00116                         PyArray_DatetimeMetaData *divisor,
00117                         int strict_with_nonlinear_units);
00118 
00119 /*
00120  * This provides the casting rules for the DATETIME data type units.
00121  *
00122  * Notably, there is a barrier between 'date units' and 'time units'
00123  * for all but 'unsafe' casting.
00124  */
00125 NPY_NO_EXPORT npy_bool
00126 can_cast_datetime64_units(NPY_DATETIMEUNIT src_unit,
00127                           NPY_DATETIMEUNIT dst_unit,
00128                           NPY_CASTING casting);
00129 
00130 /*
00131  * This provides the casting rules for the DATETIME data type metadata.
00132  */
00133 NPY_NO_EXPORT npy_bool
00134 can_cast_datetime64_metadata(PyArray_DatetimeMetaData *src_meta,
00135                              PyArray_DatetimeMetaData *dst_meta,
00136                              NPY_CASTING casting);
00137 
00138 /*
00139  * This provides the casting rules for the TIMEDELTA data type units.
00140  *
00141  * Notably, there is a barrier between the nonlinear years and
00142  * months units, and all the other units.
00143  */
00144 NPY_NO_EXPORT npy_bool
00145 can_cast_timedelta64_units(NPY_DATETIMEUNIT src_unit,
00146                           NPY_DATETIMEUNIT dst_unit,
00147                           NPY_CASTING casting);
00148 
00149 /*
00150  * This provides the casting rules for the TIMEDELTA data type metadata.
00151  */
00152 NPY_NO_EXPORT npy_bool
00153 can_cast_timedelta64_metadata(PyArray_DatetimeMetaData *src_meta,
00154                              PyArray_DatetimeMetaData *dst_meta,
00155                              NPY_CASTING casting);
00156 
00157 /*
00158  * Computes the conversion factor to convert data with 'src_meta' metadata
00159  * into data with 'dst_meta' metadata.
00160  *
00161  * If overflow occurs, both out_num and out_denom are set to 0, but
00162  * no error is set.
00163  */
00164 NPY_NO_EXPORT void
00165 get_datetime_conversion_factor(PyArray_DatetimeMetaData *src_meta,
00166                                 PyArray_DatetimeMetaData *dst_meta,
00167                                 npy_int64 *out_num, npy_int64 *out_denom);
00168 
00169 /*
00170  * Given a pointer to datetime metadata,
00171  * returns a tuple for pickling and other purposes.
00172  */
00173 NPY_NO_EXPORT PyObject *
00174 convert_datetime_metadata_to_tuple(PyArray_DatetimeMetaData *meta);
00175 
00176 /*
00177  * Converts a metadata tuple into a datetime metadata C struct.
00178  *
00179  * Returns 0 on success, -1 on failure.
00180  */
00181 NPY_NO_EXPORT int
00182 convert_datetime_metadata_tuple_to_datetime_metadata(PyObject *tuple,
00183                                         PyArray_DatetimeMetaData *out_meta);
00184 
00185 /*
00186  * Gets a tzoffset in minutes by calling the fromutc() function on
00187  * the Python datetime.tzinfo object.
00188  */
00189 NPY_NO_EXPORT int
00190 get_tzoffset_from_pytzinfo(PyObject *timezone, npy_datetimestruct *dts);
00191 
00192 /*
00193  * Converts an input object into datetime metadata. The input
00194  * may be either a string or a tuple.
00195  *
00196  * Returns 0 on success, -1 on failure.
00197  */
00198 NPY_NO_EXPORT int
00199 convert_pyobject_to_datetime_metadata(PyObject *obj,
00200                                         PyArray_DatetimeMetaData *out_meta);
00201 
00202 /*
00203  * 'ret' is a PyUString containing the datetime string, and this
00204  * function appends the metadata string to it.
00205  *
00206  * If 'skip_brackets' is true, skips the '[]'.
00207  *
00208  * This function steals the reference 'ret'
00209  */
00210 NPY_NO_EXPORT PyObject *
00211 append_metastr_to_string(PyArray_DatetimeMetaData *meta,
00212                                     int skip_brackets,
00213                                     PyObject *ret);
00214 
00215 /*
00216  * Tests for and converts a Python datetime.datetime or datetime.date
00217  * object into a NumPy npy_datetimestruct.
00218  *
00219  * 'out_bestunit' gives a suggested unit based on whether the object
00220  *      was a datetime.date or datetime.datetime object.
00221  *
00222  * If 'apply_tzinfo' is 1, this function uses the tzinfo to convert
00223  * to UTC time, otherwise it returns the struct with the local time.
00224  *
00225  * Returns -1 on error, 0 on success, and 1 (with no error set)
00226  * if obj doesn't have the neeeded date or datetime attributes.
00227  */
00228 NPY_NO_EXPORT int
00229 convert_pydatetime_to_datetimestruct(PyObject *obj, npy_datetimestruct *out,
00230                                      NPY_DATETIMEUNIT *out_bestunit,
00231                                      int apply_tzinfo);
00232 
00233 /*
00234  * Converts a PyObject * into a datetime, in any of the forms supported.
00235  *
00236  * If the units metadata isn't known ahead of time, set meta->base
00237  * to -1, and this function will populate meta with either default
00238  * values or values from the input object.
00239  *
00240  * The 'casting' parameter is used to control what kinds of inputs
00241  * are accepted, and what happens. For example, with 'unsafe' casting,
00242  * unrecognized inputs are converted to 'NaT' instead of throwing an error,
00243  * while with 'safe' casting an error will be thrown if any precision
00244  * from the input will be thrown away.
00245  *
00246  * Returns -1 on error, 0 on success.
00247  */
00248 NPY_NO_EXPORT int
00249 convert_pyobject_to_datetime(PyArray_DatetimeMetaData *meta, PyObject *obj,
00250                                 NPY_CASTING casting, npy_datetime *out);
00251 
00252 /*
00253  * Converts a PyObject * into a timedelta, in any of the forms supported
00254  *
00255  * If the units metadata isn't known ahead of time, set meta->base
00256  * to -1, and this function will populate meta with either default
00257  * values or values from the input object.
00258  *
00259  * The 'casting' parameter is used to control what kinds of inputs
00260  * are accepted, and what happens. For example, with 'unsafe' casting,
00261  * unrecognized inputs are converted to 'NaT' instead of throwing an error,
00262  * while with 'safe' casting an error will be thrown if any precision
00263  * from the input will be thrown away.
00264  *
00265  * Returns -1 on error, 0 on success.
00266  */
00267 NPY_NO_EXPORT int
00268 convert_pyobject_to_timedelta(PyArray_DatetimeMetaData *meta, PyObject *obj,
00269                                 NPY_CASTING casting, npy_timedelta *out);
00270 
00271 /*
00272  * Converts a datetime into a PyObject *.
00273  *
00274  * For days or coarser, returns a datetime.date.
00275  * For microseconds or coarser, returns a datetime.datetime.
00276  * For units finer than microseconds, returns an integer.
00277  */
00278 NPY_NO_EXPORT PyObject *
00279 convert_datetime_to_pyobject(npy_datetime dt, PyArray_DatetimeMetaData *meta);
00280 
00281 /*
00282  * Converts a timedelta into a PyObject *.
00283  *
00284  * Not-a-time is returned as the string "NaT".
00285  * For microseconds or coarser, returns a datetime.timedelta.
00286  * For units finer than microseconds, returns an integer.
00287  */
00288 NPY_NO_EXPORT PyObject *
00289 convert_timedelta_to_pyobject(npy_timedelta td, PyArray_DatetimeMetaData *meta);
00290 
00291 /*
00292  * Converts a datetime based on the given metadata into a datetimestruct
00293  */
00294 NPY_NO_EXPORT int
00295 convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta,
00296                                     npy_datetime dt,
00297                                     npy_datetimestruct *out);
00298 
00299 /*
00300  * Converts a datetime from a datetimestruct to a datetime based
00301  * on some metadata. The date is assumed to be valid.
00302  *
00303  * TODO: If meta->num is really big, there could be overflow
00304  *
00305  * Returns 0 on success, -1 on failure.
00306  */
00307 NPY_NO_EXPORT int
00308 convert_datetimestruct_to_datetime(PyArray_DatetimeMetaData *meta,
00309                                     const npy_datetimestruct *dts,
00310                                     npy_datetime *out);
00311 
00312 /*
00313  * Adjusts a datetimestruct based on a seconds offset. Assumes
00314  * the current values are valid.
00315  */
00316 NPY_NO_EXPORT void
00317 add_seconds_to_datetimestruct(npy_datetimestruct *dts, int seconds);
00318 
00319 /*
00320  * Adjusts a datetimestruct based on a minutes offset. Assumes
00321  * the current values are valid.
00322  */
00323 NPY_NO_EXPORT void
00324 add_minutes_to_datetimestruct(npy_datetimestruct *dts, int minutes);
00325 
00326 /*
00327  * Returns true if the datetime metadata matches
00328  */
00329 NPY_NO_EXPORT npy_bool
00330 has_equivalent_datetime_metadata(PyArray_Descr *type1, PyArray_Descr *type2);
00331 
00332 /*
00333  * Casts a single datetime from having src_meta metadata into
00334  * dst_meta metadata.
00335  *
00336  * Returns 0 on success, -1 on failure.
00337  */
00338 NPY_NO_EXPORT int
00339 cast_datetime_to_datetime(PyArray_DatetimeMetaData *src_meta,
00340                           PyArray_DatetimeMetaData *dst_meta,
00341                           npy_datetime src_dt,
00342                           npy_datetime *dst_dt);
00343 
00344 /*
00345  * Casts a single timedelta from having src_meta metadata into
00346  * dst_meta metadata.
00347  *
00348  * Returns 0 on success, -1 on failure.
00349  */
00350 NPY_NO_EXPORT int
00351 cast_timedelta_to_timedelta(PyArray_DatetimeMetaData *src_meta,
00352                           PyArray_DatetimeMetaData *dst_meta,
00353                           npy_timedelta src_dt,
00354                           npy_timedelta *dst_dt);
00355 
00356 /*
00357  * Returns true if the object is something that is best considered
00358  * a Datetime or Timedelta, false otherwise.
00359  */
00360 NPY_NO_EXPORT npy_bool
00361 is_any_numpy_datetime_or_timedelta(PyObject *obj);
00362 
00363 /*
00364  * Implements a datetime-specific arange
00365  */
00366 NPY_NO_EXPORT PyArrayObject *
00367 datetime_arange(PyObject *start, PyObject *stop, PyObject *step,
00368                 PyArray_Descr *dtype);
00369 
00370 /*
00371  * Examines all the objects in the given Python object by
00372  * recursively descending the sequence structure. Returns a
00373  * datetime or timedelta type with metadata based on the data.
00374  */
00375 NPY_NO_EXPORT PyArray_Descr *
00376 find_object_datetime_type(PyObject *obj, int type_num);
00377 
00378 #endif