* Computes the conversion factor to convert data with 'src_meta' metadata * into data with 'dst_meta' metadata. * * If overflow occurs, both out_num and out_denom are set to 0, but * no error is set. */
| 1093 | * no error is set. |
| 1094 | */ |
| 1095 | NPY_NO_EXPORT void |
| 1096 | get_datetime_conversion_factor(PyArray_DatetimeMetaData *src_meta, |
| 1097 | PyArray_DatetimeMetaData *dst_meta, |
| 1098 | npy_int64 *out_num, npy_int64 *out_denom) |
| 1099 | { |
| 1100 | int src_base, dst_base, swapped; |
| 1101 | npy_uint64 num = 1, denom = 1, tmp, gcd; |
| 1102 | |
| 1103 | /* Generic units change to the destination with no conversion factor */ |
| 1104 | if (src_meta->base == NPY_FR_GENERIC) { |
| 1105 | *out_num = 1; |
| 1106 | *out_denom = 1; |
| 1107 | return; |
| 1108 | } |
| 1109 | /* |
| 1110 | * Converting to a generic unit from something other than a generic |
| 1111 | * unit is an error. |
| 1112 | */ |
| 1113 | else if (dst_meta->base == NPY_FR_GENERIC) { |
| 1114 | PyErr_SetString(PyExc_ValueError, |
| 1115 | "Cannot convert from specific units to generic " |
| 1116 | "units in NumPy datetimes or timedeltas"); |
| 1117 | *out_num = 0; |
| 1118 | *out_denom = 0; |
| 1119 | return; |
| 1120 | } |
| 1121 | |
| 1122 | if (src_meta->base <= dst_meta->base) { |
| 1123 | src_base = src_meta->base; |
| 1124 | dst_base = dst_meta->base; |
| 1125 | swapped = 0; |
| 1126 | } |
| 1127 | else { |
| 1128 | src_base = dst_meta->base; |
| 1129 | dst_base = src_meta->base; |
| 1130 | swapped = 1; |
| 1131 | } |
| 1132 | |
| 1133 | if (src_base != dst_base) { |
| 1134 | /* |
| 1135 | * Conversions between years/months and other units use |
| 1136 | * the factor averaged over the 400 year leap year cycle. |
| 1137 | */ |
| 1138 | if (src_base == NPY_FR_Y) { |
| 1139 | if (dst_base == NPY_FR_M) { |
| 1140 | num *= 12; |
| 1141 | } |
| 1142 | else if (dst_base == NPY_FR_W) { |
| 1143 | num *= (97 + 400*365); |
| 1144 | denom *= 400*7; |
| 1145 | } |
| 1146 | else { |
| 1147 | /* Year -> Day */ |
| 1148 | num *= (97 + 400*365); |
| 1149 | denom *= 400; |
| 1150 | /* Day -> dst_base */ |
| 1151 | num *= get_datetime_units_factor(NPY_FR_D, dst_base); |
| 1152 | } |
no test coverage detected