forked from apache/arrow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatetime.h
More file actions
161 lines (132 loc) · 5.13 KB
/
Copy pathdatetime.h
File metadata and controls
161 lines (132 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#ifndef PYARROW_UTIL_DATETIME_H
#define PYARROW_UTIL_DATETIME_H
#include <algorithm>
#include <chrono>
#include "arrow/python/platform.h"
#include "arrow/python/visibility.h"
#include "arrow/status.h"
#include "arrow/type.h"
#include "arrow/util/logging.h"
// By default, PyDateTimeAPI is a *static* variable. This forces
// PyDateTime_IMPORT to be called in every C/C++ module using the
// C datetime API. This is error-prone and potentially costly.
// Instead, we redefine PyDateTimeAPI to point to a global variable,
// which is initialized once by calling InitDatetime().
#define PyDateTimeAPI ::arrow::py::internal::datetime_api
namespace arrow {
namespace py {
namespace internal {
extern PyDateTime_CAPI* datetime_api;
ARROW_PYTHON_EXPORT
void InitDatetime();
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_us(PyObject* pytime) {
return (static_cast<int64_t>(PyDateTime_TIME_GET_HOUR(pytime)) * 3600000000LL +
static_cast<int64_t>(PyDateTime_TIME_GET_MINUTE(pytime)) * 60000000LL +
static_cast<int64_t>(PyDateTime_TIME_GET_SECOND(pytime)) * 1000000LL +
PyDateTime_TIME_GET_MICROSECOND(pytime));
}
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_s(PyObject* pytime) { return PyTime_to_us(pytime) / 1000000; }
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_ms(PyObject* pytime) { return PyTime_to_us(pytime) / 1000; }
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_ns(PyObject* pytime) { return PyTime_to_us(pytime) * 1000; }
ARROW_PYTHON_EXPORT
Status PyTime_from_int(int64_t val, const TimeUnit::type unit, PyObject** out);
ARROW_PYTHON_EXPORT
Status PyDate_from_int(int64_t val, const DateUnit unit, PyObject** out);
ARROW_PYTHON_EXPORT
Status PyDateTime_from_int(int64_t val, const TimeUnit::type unit, PyObject** out);
using TimePoint =
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;
ARROW_PYTHON_EXPORT
Status PyDateTime_from_TimePoint(TimePoint val, PyObject** out);
ARROW_PYTHON_EXPORT
int64_t PyDate_to_days(PyDateTime_Date* pydate);
ARROW_PYTHON_EXPORT
inline int64_t PyDate_to_ms(PyDateTime_Date* pydate) {
return PyDate_to_days(pydate) * 24 * 3600 * 1000;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_s(PyDateTime_DateTime* pydatetime) {
int64_t total_seconds = 0;
total_seconds += PyDateTime_DATE_GET_SECOND(pydatetime);
total_seconds += PyDateTime_DATE_GET_MINUTE(pydatetime) * 60;
total_seconds += PyDateTime_DATE_GET_HOUR(pydatetime) * 3600;
return total_seconds +
(PyDate_to_ms(reinterpret_cast<PyDateTime_Date*>(pydatetime)) / 1000LL);
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_ms(PyDateTime_DateTime* pydatetime) {
int64_t date_ms = PyDateTime_to_s(pydatetime) * 1000;
int ms = PyDateTime_DATE_GET_MICROSECOND(pydatetime) / 1000;
return date_ms + ms;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_us(PyDateTime_DateTime* pydatetime) {
int64_t ms = PyDateTime_to_s(pydatetime) * 1000;
int us = PyDateTime_DATE_GET_MICROSECOND(pydatetime);
return ms * 1000 + us;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_ns(PyDateTime_DateTime* pydatetime) {
return PyDateTime_to_us(pydatetime) * 1000;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_s(PyDateTime_Delta* pytimedelta) {
int64_t total_seconds = 0;
#if PY_VERSION_HEX >= 0x03000000
total_seconds += PyDateTime_DELTA_GET_SECONDS(pytimedelta);
total_seconds += PyDateTime_DELTA_GET_DAYS(pytimedelta) * 24 * 3600;
#else
total_seconds += pytimedelta->seconds;
total_seconds += pytimedelta->days * 24 * 3600;
#endif
return total_seconds;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_ms(PyDateTime_Delta* pytimedelta) {
int64_t total_ms = PyDelta_to_s(pytimedelta) * 1000;
#if PY_VERSION_HEX >= 0x03000000
total_ms += PyDateTime_DELTA_GET_MICROSECONDS(pytimedelta) / 1000;
#else
total_ms += pytimedelta->microseconds / 1000;
#endif
return total_ms;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_us(PyDateTime_Delta* pytimedelta) {
int64_t total_us = 0;
total_us += PyDelta_to_s(pytimedelta) * 1000 * 1000;
#if PY_VERSION_HEX >= 0x03000000
total_us += PyDateTime_DELTA_GET_MICROSECONDS(pytimedelta);
#else
total_us += pytimedelta->microseconds;
#endif
return total_us;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_ns(PyDateTime_Delta* pytimedelta) {
return PyDelta_to_us(pytimedelta) * 1000;
}
} // namespace internal
} // namespace py
} // namespace arrow
#endif // PYARROW_UTIL_DATETIME_H