/* * Create a datetime value from a filled datetime struct and resolution unit. */ internal static npy_datetime NpyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT fr, npy_datetimestruct d) { npy_datetime ret; if (fr == NPY_DATETIMEUNIT.NPY_FR_Y) { ret = d.year - 1970; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_M) { ret = (d.year - 1970) * 12 + d.month - 1; } else { npy_longlong days; /* The absolute number of days since Jan 1, 1970 */ days = days_from_ymd(d.year, d.month, d.day); if (fr == NPY_DATETIMEUNIT.NPY_FR_W) { /* This is just 7-days for now. */ if (days >= 0) { ret = days / 7; } else { ret = (days - 6) / 7; } } else if (fr == NPY_DATETIMEUNIT.NPY_FR_B) { npy_longlong x; int dotw = day_of_week(days); if (dotw > 4) { /* Invalid business day */ ret = 0; } else { if (days >= 0) { /* offset to adjust first week */ x = days - 4; } else { x = days - 2; } ret = 2 + (x / 7) * 5 + x % 7; } } else if (fr == NPY_DATETIMEUNIT.NPY_FR_D) { ret = days; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_h) { ret = days * 24 + d.hour; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_m) { ret = days * 1440 + d.hour * 60 + d.min; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_s) { ret = days * (npy_int64)(86400) + secs_from_hms(d.hour, d.min, d.sec, 1); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ms) { ret = days * (npy_int64)(86400000) + secs_from_hms(d.hour, d.min, d.sec, 1000) + (d.us / 1000); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_us) { npy_int64 num = 86400 * 1000; num *= (npy_int64)(1000); ret = days * num + secs_from_hms(d.hour, d.min, d.sec, 1000000) + d.us; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ns) { npy_int64 num = 86400 * 1000; num *= (npy_int64)(1000 * 1000); ret = days * num + secs_from_hms(d.hour, d.min, d.sec, 1000000000) + d.us * (npy_int64)(1000) + (d.ps / 1000); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ps) { npy_int64 num2 = 1000 * 1000; npy_int64 num1; num2 *= (npy_int64)(1000 * 1000); num1 = (npy_int64)(86400) * num2; ret = days * num1 + secs_from_hms(d.hour, d.min, d.sec, (int)num2) + d.us * (npy_int64)(1000000) + d.ps; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_fs) { /* only 2.6 hours */ npy_int64 num2 = 1000000; num2 *= (npy_int64)(1000000); num2 *= (npy_int64)(1000); /* get number of seconds as a postive or negative number */ if (days >= 0) { ret = secs_from_hms(d.hour, d.min, d.sec, 1); } else { ret = ((d.hour - 24) * 3600 + d.min * 60 + d.sec); } ret = ret * num2 + d.us * (npy_int64)(1000000000) + d.ps * (npy_int64)(1000) + (d.as1 / 1000); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_as) { /* only 9.2 secs */ npy_int64 num1, num2; num1 = 1000000; num1 *= (npy_int64)(1000000); num2 = num1 * (npy_int64)(1000000); if (days >= 0) { ret = d.sec; } else { ret = d.sec - 60; } ret = ret * num2 + d.us * num1 + d.ps * (npy_int64)(1000000) + d.as1; } else { /* Shouldn't get here */ NpyErr_SetString(npyexc_type.NpyExc_ValueError, "invalid internal frequency"); ret = -1; } } return(ret); }
/* * Fill the datetime struct from the value and resolution unit. */ internal static void NpyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIMEUNIT fr, npy_datetimestruct result) { int year = 1970; int month = 1, day = 1, hour = 0, min = 0, sec = 0, us = 0, ps = 0, as1 = 0; npy_int64 tmp; ymdstruct ymd; hmsstruct hms; /* * Note that what looks like val / N and val % N for positive numbers maps to * [val - (N-1)] / N and [N-1 + (val+1) % N] for negative numbers (with the 2nd * value, the remainder, being positive in both cases). */ if (fr == NPY_DATETIMEUNIT.NPY_FR_Y) { year = (int)(1970 + val); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_M) { if (val >= 0) { year = (int)(1970 + val / 12); month = (int)(val % 12 + 1); } else { year = (int)(1969 + (val + 1) / 12); month = (int)(12 + (val + 1) % 12); } } else if (fr == NPY_DATETIMEUNIT.NPY_FR_W) { /* A week is the same as 7 days */ ymd = days_to_ymdstruct(val * 7); year = ymd.year; month = ymd.month; day = ymd.day; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_B) { /* Number of business days since Thursday, 1-1-70 */ npy_longlong absdays; /* * A buisness day is M T W Th F (i.e. all but Sat and Sun.) * Convert the business day to the number of actual days. * * Must convert [0,1,2,3,4,5,6,7,...] to * [0,1,4,5,6,7,8,11,...] * and [...,-9,-8,-7,-6,-5,-4,-3,-2,-1,0] to * [...,-13,-10,-9,-8,-7,-6,-3,-2,-1,0] */ if (val >= 0) { absdays = 7 * ((val + 3) / 5) + ((val + 3) % 5) - 3; } else { /* Recall how C computes / and % with negative numbers */ absdays = 7 * ((val - 1) / 5) + ((val - 1) % 5) + 1; } ymd = days_to_ymdstruct(absdays); year = ymd.year; month = ymd.month; day = ymd.day; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_D) { ymd = days_to_ymdstruct(val); year = ymd.year; month = ymd.month; day = ymd.day; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_h) { if (val >= 0) { ymd = days_to_ymdstruct(val / 24); hour = (int)(val % 24); } else { ymd = days_to_ymdstruct((val - 23) / 24); hour = (int)(23 + (val + 1) % 24); } year = ymd.year; month = ymd.month; day = ymd.day; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_m) { if (val >= 0) { ymd = days_to_ymdstruct(val / 1440); min = (int)(val % 1440); } else { ymd = days_to_ymdstruct((val - 1439) / 1440); min = (int)(1439 + (val + 1) % 1440); } hms = seconds_to_hmsstruct(min * 60); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_s) { if (val >= 0) { ymd = days_to_ymdstruct(val / 86400); sec = (int)(val % 86400); } else { ymd = days_to_ymdstruct((val - 86399) / 86400); sec = (int)(86399 + (val + 1) % 86400); } hms = seconds_to_hmsstruct(val); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; sec = hms.sec; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ms) { if (val >= 0) { ymd = days_to_ymdstruct(val / 86400000); tmp = val % 86400000; } else { ymd = days_to_ymdstruct((val - 86399999) / 86400000); tmp = 86399999 + (val + 1) % 86399999; } hms = seconds_to_hmsstruct(tmp / 1000); us = (int)((tmp % 1000) * 1000); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; sec = hms.sec; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_us) { npy_int64 num1, num2; num1 = 86400000; num1 *= 1000; num2 = num1 - 1; if (val >= 0) { ymd = days_to_ymdstruct(val / num1); tmp = val % num1; } else { ymd = days_to_ymdstruct((val - num2) / num1); tmp = num2 + (val + 1) % num1; } hms = seconds_to_hmsstruct(tmp / 1000000); us = (int)(tmp % 1000000); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; sec = hms.sec; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ns) { npy_int64 num1, num2, num3; num1 = 86400000; num1 *= 1000000000; num2 = num1 - 1; num3 = 1000000; num3 *= 1000000; if (val >= 0) { ymd = days_to_ymdstruct(val / num1); tmp = val % num1; } else { ymd = days_to_ymdstruct((val - num2) / num1); tmp = num2 + (val + 1) % num1; } hms = seconds_to_hmsstruct(tmp / 1000000000); tmp = tmp % 1000000000; us = (int)(tmp / 1000); ps = (int)((tmp % 1000) * (npy_int64)(1000)); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; sec = hms.sec; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_ps) { npy_int64 num1, num2, num3; num3 = 1000000000; num3 *= (npy_int64)(1000); num1 = (npy_int64)(86400) * num3; num2 = num1 - 1; if (val >= 0) { ymd = days_to_ymdstruct(val / num1); tmp = val % num1; } else { ymd = days_to_ymdstruct((val - num2) / num1); tmp = num2 + (val + 1) % num1; } hms = seconds_to_hmsstruct(tmp / num3); tmp = tmp % num3; us = (int)(tmp / 1000000); ps = (int)(tmp % 1000000); year = ymd.year; month = ymd.month; day = ymd.day; hour = hms.hour; min = hms.min; sec = hms.sec; } else if (fr == NPY_DATETIMEUNIT.NPY_FR_fs) { /* entire range is only += 2.6 hours */ npy_int64 num1, num2; num1 = 1000000000; num1 *= (npy_int64)(1000); num2 = num1 * (npy_int64)(1000); if (val >= 0) { sec = (int)(val / num2); tmp = val % num2; hms = seconds_to_hmsstruct(sec); hour = hms.hour; min = hms.min; sec = hms.sec; } else { /* tmp (number of fs) will be positive after this segment */ year = 1969; day = 31; month = 12; sec = (int)((val - (num2 - 1)) / num2); tmp = (num2 - 1) + (val + 1) % num2; if (sec == 0) { /* we are at the last second */ hour = 23; min = 59; sec = 59; } else { hour = 24 + (sec - 3599) / 3600; sec = 3599 + (sec + 1) % 3600; min = sec / 60; sec = sec % 60; } } us = (int)(tmp / 1000000000); tmp = tmp % 1000000000; ps = (int)(tmp / 1000); as1 = (int)((tmp % 1000) * (npy_int64)(1000)); } else if (fr == NPY_DATETIMEUNIT.NPY_FR_as) { /* entire range is only += 9.2 seconds */ npy_int64 num1, num2, num3; num1 = 1000000; num2 = num1 * (npy_int64)(1000000); num3 = num2 * (npy_int64)(1000000); if (val >= 0) { hour = 0; min = 0; sec = (int)(val / num3); tmp = val % num3; } else { year = 1969; day = 31; month = 12; hour = 23; min = 59; sec = (int)(60 + (val - (num3 - 1)) / num3); tmp = (num3 - 1) + (val + 1) % num3; } us = (int)(tmp / num2); tmp = tmp % num2; ps = (int)(tmp / num1); as1 = (int)(tmp % num1); } else { NpyErr_SetString(npyexc_type.NpyExc_RuntimeError, "invalid internal time resolution"); } result.year = year; result.month = month; result.day = day; result.hour = hour; result.min = min; result.sec = sec; result.us = us; result.ps = ps; result.as1 = as1; return; }