在C API中转换Numpy datetime64

时间:2017-01-13 20:22:47

标签: python c numpy

如何在C中使用从Python传递的datetime64?我在Numpy标题中发现了一些不推荐使用的函数,如PyArray_DatetimeToDatetimeStruct(),但找不到与datetime64相关的任何内容。

看起来它是一个整数数组以及后端的一些元数据,但如果是这样,你如何确定单位?

1 个答案:

答案 0 :(得分:1)

对于那些想知道将来如何做到这一点的人来说,这是我最终的解决方案。

将日期时间64作为Python中的int64传递:

dt = np.datetime64(datetime.utcnow())
my_C_func(dt.astype(np.int64))

C中的解码源自gmtime()的源。此代码假定日期时间以微秒为单位,您可以通过检查dtype来确定(感谢@hpaulj)。 start是来自Python的datetime64。

inline int
is_leapyear(uint64_t year)
{
    return (year & 0x3) == 0 && /* year % 4 == 0 */
           ((year % 100) != 0 ||
            (year % 400) == 0);
}
#define YEARSIZE(year) (is_leapyear(year) ? 366u : 365u)

...

uint64_t us_per_day = 1000ull * 1000ull * 60ull * 60ull * 24ull;
register uint64_t dayclock = start % us_per_day;
register uint64_t dayno = start / us_per_day;

uint64_t year = 1970ull;

uint64_t us = dayclock % 1000000ull;
uint64_t sec = (dayclock / 1000000ull) % 60ull;
uint64_t minute = (dayclock % 3600000000ull) / 60000000ull;
uint64_t hour = dayclock / 3600000000ull;
while (dayno >= YEARSIZE(year))
{
    dayno -= YEARSIZE(year);
    year++;
}

uint64_t day = dayno + 1;

如果你不需要比秒更准确的东西,你可以简单地这样做:

uint64_t other_start = start / 1000000ull;
struct tm* ptm;
ptm = gmtime((time_t*)&other_start);

printf("\tGMTIME VERSION:\n");
printf("\tyear: %d\n", ptm->tm_year);    
printf("\tday: %d\n", ptm->tm_yday);
printf("\thours: %d\n", ptm->tm_hour);
printf("\tminutes: %d\n", ptm->tm_min);
printf("\tsec: %d\n", ptm->tm_sec);

当然,我们可以单独获得美国部分:

uint64_t us = source % 1000000ull;
相关问题