[2] | 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
|
---|
[391] | 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
|
---|
[2] | 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 | {
|
---|
[391] | 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 */
|
---|
[2] | 41 | } PyDateTime_Delta;
|
---|
| 42 |
|
---|
| 43 | typedef struct
|
---|
| 44 | {
|
---|
[391] | 45 | PyObject_HEAD /* a pure abstract base class */
|
---|
[2] | 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 | */
|
---|
[391] | 52 | #define _PyTZINFO_HEAD \
|
---|
| 53 | PyObject_HEAD \
|
---|
| 54 | long hashcode; \
|
---|
| 55 | char hastzinfo; /* boolean flag */
|
---|
[2] | 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 | {
|
---|
[391] | 63 | _PyTZINFO_HEAD
|
---|
[2] | 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 | */
|
---|
[391] | 72 | #define _PyDateTime_TIMEHEAD \
|
---|
| 73 | _PyTZINFO_HEAD \
|
---|
| 74 | unsigned char data[_PyDateTime_TIME_DATASIZE];
|
---|
[2] | 75 |
|
---|
| 76 | typedef struct
|
---|
| 77 | {
|
---|
[391] | 78 | _PyDateTime_TIMEHEAD
|
---|
| 79 | } _PyDateTime_BaseTime; /* hastzinfo false */
|
---|
[2] | 80 |
|
---|
| 81 | typedef struct
|
---|
| 82 | {
|
---|
[391] | 83 | _PyDateTime_TIMEHEAD
|
---|
| 84 | PyObject *tzinfo;
|
---|
| 85 | } PyDateTime_Time; /* hastzinfo true */
|
---|
[2] | 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 | {
|
---|
[391] | 95 | _PyTZINFO_HEAD
|
---|
| 96 | unsigned char data[_PyDateTime_DATE_DATASIZE];
|
---|
[2] | 97 | } PyDateTime_Date;
|
---|
| 98 |
|
---|
[391] | 99 | #define _PyDateTime_DATETIMEHEAD \
|
---|
| 100 | _PyTZINFO_HEAD \
|
---|
| 101 | unsigned char data[_PyDateTime_DATETIME_DATASIZE];
|
---|
[2] | 102 |
|
---|
| 103 | typedef struct
|
---|
| 104 | {
|
---|
[391] | 105 | _PyDateTime_DATETIMEHEAD
|
---|
| 106 | } _PyDateTime_BaseDateTime; /* hastzinfo false */
|
---|
[2] | 107 |
|
---|
| 108 | typedef struct
|
---|
| 109 | {
|
---|
[391] | 110 | _PyDateTime_DATETIMEHEAD
|
---|
| 111 | PyObject *tzinfo;
|
---|
| 112 | } PyDateTime_DateTime; /* hastzinfo true */
|
---|
[2] | 113 |
|
---|
| 114 |
|
---|
| 115 | /* Apply for date and datetime instances. */
|
---|
| 116 | #define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
---|
[391] | 117 | ((PyDateTime_Date*)o)->data[1])
|
---|
[2] | 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])
|
---|
[391] | 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])
|
---|
[2] | 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])
|
---|
[391] | 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])
|
---|
[2] | 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,
|
---|
[391] | 151 | PyObject*, PyTypeObject*);
|
---|
[2] | 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 |
|
---|
[391] | 161 | #define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
|
---|
[2] | 162 |
|
---|
[391] | 163 |
|
---|
[2] | 164 | /* "magic" constant used to partially protect against developer mistakes. */
|
---|
| 165 | #define DATETIME_API_MAGIC 0x414548d5
|
---|
| 166 |
|
---|
| 167 | #ifdef Py_BUILD_CORE
|
---|
| 168 |
|
---|
| 169 | /* Macros for type checking when building the Python core. */
|
---|
| 170 | #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
|
---|
| 171 | #define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType)
|
---|
| 172 |
|
---|
| 173 | #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
|
---|
| 174 | #define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType)
|
---|
| 175 |
|
---|
| 176 | #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
|
---|
| 177 | #define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType)
|
---|
| 178 |
|
---|
| 179 | #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
|
---|
| 180 | #define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType)
|
---|
| 181 |
|
---|
| 182 | #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
|
---|
| 183 | #define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType)
|
---|
| 184 |
|
---|
| 185 | #else
|
---|
| 186 |
|
---|
| 187 | /* Define global variable for the C API and a macro for setting it. */
|
---|
[391] | 188 | static PyDateTime_CAPI *PyDateTimeAPI = NULL;
|
---|
[2] | 189 |
|
---|
| 190 | #define PyDateTime_IMPORT \
|
---|
[391] | 191 | PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
|
---|
[2] | 192 |
|
---|
| 193 | /* Macros for type checking when not building the Python core. */
|
---|
| 194 | #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
|
---|
| 195 | #define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType)
|
---|
| 196 |
|
---|
| 197 | #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
|
---|
| 198 | #define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType)
|
---|
| 199 |
|
---|
| 200 | #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
|
---|
| 201 | #define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType)
|
---|
| 202 |
|
---|
| 203 | #define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
|
---|
| 204 | #define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType)
|
---|
| 205 |
|
---|
| 206 | #define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
|
---|
| 207 | #define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType)
|
---|
| 208 |
|
---|
| 209 | /* Macros for accessing constructors in a simplified fashion. */
|
---|
| 210 | #define PyDate_FromDate(year, month, day) \
|
---|
[391] | 211 | PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
|
---|
[2] | 212 |
|
---|
| 213 | #define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
|
---|
[391] | 214 | PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
|
---|
| 215 | min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
|
---|
[2] | 216 |
|
---|
| 217 | #define PyTime_FromTime(hour, minute, second, usecond) \
|
---|
[391] | 218 | PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
|
---|
| 219 | Py_None, PyDateTimeAPI->TimeType)
|
---|
[2] | 220 |
|
---|
| 221 | #define PyDelta_FromDSU(days, seconds, useconds) \
|
---|
[391] | 222 | PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
|
---|
| 223 | PyDateTimeAPI->DeltaType)
|
---|
[2] | 224 |
|
---|
| 225 | /* Macros supporting the DB API. */
|
---|
| 226 | #define PyDateTime_FromTimestamp(args) \
|
---|
[391] | 227 | PyDateTimeAPI->DateTime_FromTimestamp( \
|
---|
| 228 | (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
|
---|
[2] | 229 |
|
---|
| 230 | #define PyDate_FromTimestamp(args) \
|
---|
[391] | 231 | PyDateTimeAPI->Date_FromTimestamp( \
|
---|
| 232 | (PyObject*) (PyDateTimeAPI->DateType), args)
|
---|
[2] | 233 |
|
---|
[391] | 234 | #endif /* Py_BUILD_CORE */
|
---|
[2] | 235 |
|
---|
| 236 | #ifdef __cplusplus
|
---|
| 237 | }
|
---|
| 238 | #endif
|
---|
| 239 | #endif
|
---|