1 | /* datetime.h
|
---|
2 | */
|
---|
3 |
|
---|
4 | #ifndef DATETIME_H
|
---|
5 | #define DATETIME_H
|
---|
6 | #ifdef __cplusplus
|
---|
7 | extern "C" {
|
---|
8 | #endif
|
---|
9 |
|
---|
10 | /* Fields are packed into successive bytes, each viewed as unsigned and
|
---|
11 | * big-endian, unless otherwise noted:
|
---|
12 | *
|
---|
13 | * byte offset
|
---|
14 | * 0 year 2 bytes, 1-9999
|
---|
15 | * 2 month 1 byte, 1-12
|
---|
16 | * 3 day 1 byte, 1-31
|
---|
17 | * 4 hour 1 byte, 0-23
|
---|
18 | * 5 minute 1 byte, 0-59
|
---|
19 | * 6 second 1 byte, 0-59
|
---|
20 | * 7 usecond 3 bytes, 0-999999
|
---|
21 | * 10
|
---|
22 | */
|
---|
23 |
|
---|
24 | /* # of bytes for year, month, and day. */
|
---|
25 | #define _PyDateTime_DATE_DATASIZE 4
|
---|
26 |
|
---|
27 | /* # of bytes for hour, minute, second, and usecond. */
|
---|
28 | #define _PyDateTime_TIME_DATASIZE 6
|
---|
29 |
|
---|
30 | /* # of bytes for year, month, day, hour, minute, second, and usecond. */
|
---|
31 | #define _PyDateTime_DATETIME_DATASIZE 10
|
---|
32 |
|
---|
33 |
|
---|
34 | typedef struct
|
---|
35 | {
|
---|
36 | PyObject_HEAD
|
---|
37 | long hashcode; /* -1 when unknown */
|
---|
38 | int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
|
---|
39 | int seconds; /* 0 <= seconds < 24*3600 is invariant */
|
---|
40 | int microseconds; /* 0 <= microseconds < 1000000 is invariant */
|
---|
41 | } PyDateTime_Delta;
|
---|
42 |
|
---|
43 | typedef struct
|
---|
44 | {
|
---|
45 | PyObject_HEAD /* a pure abstract base clase */
|
---|
46 | } PyDateTime_TZInfo;
|
---|
47 |
|
---|
48 |
|
---|
49 | /* The datetime and time types have hashcodes, and an optional tzinfo member,
|
---|
50 | * present if and only if hastzinfo is true.
|
---|
51 | */
|
---|
52 | #define _PyTZINFO_HEAD \
|
---|
53 | PyObject_HEAD \
|
---|
54 | long hashcode; \
|
---|
55 | char hastzinfo; /* boolean flag */
|
---|
56 |
|
---|
57 | /* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
|
---|
58 | * convenient to cast to, when getting at the hastzinfo member of objects
|
---|
59 | * starting with _PyTZINFO_HEAD.
|
---|
60 | */
|
---|
61 | typedef struct
|
---|
62 | {
|
---|
63 | _PyTZINFO_HEAD
|
---|
64 | } _PyDateTime_BaseTZInfo;
|
---|
65 |
|
---|
66 | /* All time objects are of PyDateTime_TimeType, but that can be allocated
|
---|
67 | * in two ways, with or without a tzinfo member. Without is the same as
|
---|
68 | * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an
|
---|
69 | * internal struct used to allocate the right amount of space for the
|
---|
70 | * "without" case.
|
---|
71 | */
|
---|
72 | #define _PyDateTime_TIMEHEAD \
|
---|
73 | _PyTZINFO_HEAD \
|
---|
74 | unsigned char data[_PyDateTime_TIME_DATASIZE];
|
---|
75 |
|
---|
76 | typedef struct
|
---|
77 | {
|
---|
78 | _PyDateTime_TIMEHEAD
|
---|
79 | } _PyDateTime_BaseTime; /* hastzinfo false */
|
---|
80 |
|
---|
81 | typedef struct
|
---|
82 | {
|
---|
83 | _PyDateTime_TIMEHEAD
|
---|
84 | PyObject *tzinfo;
|
---|
85 | } PyDateTime_Time; /* hastzinfo true */
|
---|
86 |
|
---|
87 |
|
---|
88 | /* All datetime objects are of PyDateTime_DateTimeType, but that can be
|
---|
89 | * allocated in two ways too, just like for time objects above. In addition,
|
---|
90 | * the plain date type is a base class for datetime, so it must also have
|
---|
91 | * a hastzinfo member (although it's unused there).
|
---|
92 | */
|
---|
93 | typedef struct
|
---|
94 | {
|
---|
95 | _PyTZINFO_HEAD
|
---|
96 | unsigned char data[_PyDateTime_DATE_DATASIZE];
|
---|
97 | } PyDateTime_Date;
|
---|
98 |
|
---|
99 | #define _PyDateTime_DATETIMEHEAD \
|
---|
100 | _PyTZINFO_HEAD \
|
---|
101 | unsigned char data[_PyDateTime_DATETIME_DATASIZE];
|
---|
102 |
|
---|
103 | typedef struct
|
---|
104 | {
|
---|
105 | _PyDateTime_DATETIMEHEAD
|
---|
106 | } _PyDateTime_BaseDateTime; /* hastzinfo false */
|
---|
107 |
|
---|
108 | typedef struct
|
---|
109 | {
|
---|
110 | _PyDateTime_DATETIMEHEAD
|
---|
111 | PyObject *tzinfo;
|
---|
112 | } PyDateTime_DateTime; /* hastzinfo true */
|
---|
113 |
|
---|
114 |
|
---|
115 | /* Apply for date and datetime instances. */
|
---|
116 | #define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
---|
117 | ((PyDateTime_Date*)o)->data[1])
|
---|
118 | #define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
|
---|
119 | #define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3])
|
---|
120 |
|
---|
121 | #define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4])
|
---|
122 | #define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5])
|
---|
123 | #define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6])
|
---|
124 | #define PyDateTime_DATE_GET_MICROSECOND(o) \
|
---|
125 | ((((PyDateTime_DateTime*)o)->data[7] << 16) | \
|
---|
126 | (((PyDateTime_DateTime*)o)->data[8] << 8) | \
|
---|
127 | ((PyDateTime_DateTime*)o)->data[9])
|
---|
128 |
|
---|
129 | /* Apply for time instances. */
|
---|
130 | #define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
|
---|
131 | #define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])
|
---|
132 | #define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2])
|
---|
133 | #define PyDateTime_TIME_GET_MICROSECOND(o) \
|
---|
134 | ((((PyDateTime_Time*)o)->data[3] << 16) | \
|
---|
135 | (((PyDateTime_Time*)o)->data[4] << 8) | \
|
---|
136 | ((PyDateTime_Time*)o)->data[5])
|
---|
137 |
|
---|
138 |
|
---|
139 | /* Define structure for C API. */
|
---|
140 | typedef struct {
|
---|
141 | /* type objects */
|
---|
142 | PyTypeObject *DateType;
|
---|
143 | PyTypeObject *DateTimeType;
|
---|
144 | PyTypeObject *TimeType;
|
---|
145 | PyTypeObject *DeltaType;
|
---|
146 | PyTypeObject *TZInfoType;
|
---|
147 |
|
---|
148 | /* constructors */
|
---|
149 | PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
|
---|
150 | PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
|
---|
151 | PyObject*, PyTypeObject*);
|
---|
152 | PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
|
---|
153 | PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
|
---|
154 |
|
---|
155 | /* constructors for the DB API */
|
---|
156 | PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
|
---|
157 | PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
|
---|
158 |
|
---|
159 | } PyDateTime_CAPI;
|
---|
160 |
|
---|
161 |
|
---|
162 | /* "magic" constant used to partially protect against developer mistakes. */
|
---|
163 | #define DATETIME_API_MAGIC 0x414548d5
|
---|
164 |
|
---|
165 | #ifdef Py_BUILD_CORE
|
---|
166 |
|
---|
167 | /* Macros for type checking when building the Python core. */
|
---|
168 | #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
|
---|
169 | #define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType)
|
---|
170 |
|
---|
171 | #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
|
---|
172 | #define PyDateTime_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeType)
|
---|
173 |
|
---|
174 | #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
|
---|
175 | #define PyTime_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeType)
|
---|
176 |
|
---|
177 | #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
|
---|
178 | #define PyDelta_CheckExact(op) ((op)->ob_type == &PyDateTime_DeltaType)
|
---|
179 |
|
---|
180 | #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
|
---|
181 | #define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType)
|
---|
182 |
|
---|
183 | #else
|
---|
184 |
|
---|
185 | /* Define global variable for the C API and a macro for setting it. */
|
---|
186 | static PyDateTime_CAPI *PyDateTimeAPI;
|
---|
187 |
|
---|
188 | #define PyDateTime_IMPORT \
|
---|
189 | PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \
|
---|
190 | "datetime_CAPI")
|
---|
191 |
|
---|
192 | /* This macro would be used if PyCObject_ImportEx() was created.
|
---|
193 | #define PyDateTime_IMPORT \
|
---|
194 | PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \
|
---|
195 | "datetime_CAPI", \
|
---|
196 | DATETIME_API_MAGIC)
|
---|
197 | */
|
---|
198 |
|
---|
199 | /* Macros for type checking when not building the Python core. */
|
---|
200 | #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
|
---|
201 | #define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType)
|
---|
202 |
|
---|
203 | #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
|
---|
204 | #define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType)
|
---|
205 |
|
---|
206 | #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
|
---|
207 | #define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType)
|
---|
208 |
|
---|
209 | #define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
|
---|
210 | #define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType)
|
---|
211 |
|
---|
212 | #define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
|
---|
213 | #define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType)
|
---|
214 |
|
---|
215 | /* Macros for accessing constructors in a simplified fashion. */
|
---|
216 | #define PyDate_FromDate(year, month, day) \
|
---|
217 | PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
|
---|
218 |
|
---|
219 | #define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
|
---|
220 | PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
|
---|
221 | min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
|
---|
222 |
|
---|
223 | #define PyTime_FromTime(hour, minute, second, usecond) \
|
---|
224 | PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
|
---|
225 | Py_None, PyDateTimeAPI->TimeType)
|
---|
226 |
|
---|
227 | #define PyDelta_FromDSU(days, seconds, useconds) \
|
---|
228 | PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
|
---|
229 | PyDateTimeAPI->DeltaType)
|
---|
230 |
|
---|
231 | /* Macros supporting the DB API. */
|
---|
232 | #define PyDateTime_FromTimestamp(args) \
|
---|
233 | PyDateTimeAPI->DateTime_FromTimestamp( \
|
---|
234 | (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
|
---|
235 |
|
---|
236 | #define PyDate_FromTimestamp(args) \
|
---|
237 | PyDateTimeAPI->Date_FromTimestamp( \
|
---|
238 | (PyObject*) (PyDateTimeAPI->DateType), args)
|
---|
239 |
|
---|
240 | #endif /* Py_BUILD_CORE */
|
---|
241 |
|
---|
242 | #ifdef __cplusplus
|
---|
243 | }
|
---|
244 | #endif
|
---|
245 | #endif
|
---|