【问题标题】:Conversion of Numpy datetime64 in C APIC API 中 Numpy datetime64 的转换
【发布时间】:2017-01-13 20:22:46
【问题描述】:

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

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

【问题讨论】:

  • 从某种意义上说,它是一个标准数组,每个项目有 8 个字节。处理转换的是数组dtype。例如 x.tolist() 生成 Python datetime 对象的列表。看起来单位信息在dtype.str'<M8[us]'
  • 貌似大部分numpydatetime操作都位于numpy/numpy/core/src/multiarray/datetime.c

标签: python c numpy


【解决方案1】:

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

将 datetime64 作为 int64 从 Python 传递:

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);

当然可以单独获取us部分:

uint64_t us = source % 1000000ull;

【讨论】:

  • 忘记了分隔符中的额外 000 个零,因为 gmtime 使用秒数(如文本中所述)。但是给定的分频器给出了毫秒。正确的是/1000000000ull
猜你喜欢
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 2019-03-29
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多