1 /** 2 mirror datetime.h 3 */ 4 module deimos.python.datetime; 5 6 version(Python_3_1_Or_Later) { 7 version = PyCapsule; 8 }else version(Python_3_0_Or_Later) { 9 version = PyCObject; 10 }else version(Python_2_7_Or_Later) { 11 version = PyCapsule; 12 }else { 13 version = PyCObject; 14 } 15 16 import deimos.python.object; 17 import deimos.python.pyport; 18 version(PyCapsule) { 19 import deimos.python.pycapsule; 20 }else version(PyCObject) { 21 import deimos.python.cobject; 22 }else static assert(0); 23 24 25 extern(C): 26 // Python-header-file: Include/datetime.h: 27 28 /** # of bytes for year, month, and day. */ 29 enum _PyDateTime_DATE_DATASIZE = 4; 30 /** # of bytes for hour, minute, second, and usecond. */ 31 enum _PyDateTime_TIME_DATASIZE = 6; 32 /** # of bytes for year, month, day, hour, minute, second, and usecond. */ 33 enum _PyDateTime_DATETIME_DATASIZE = 10; 34 35 /// subclass of PyObject. 36 struct PyDateTime_Delta { 37 mixin PyObject_HEAD; 38 39 /** -1 when unknown */ 40 Py_hash_t hashcode; 41 /** -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ 42 int days; 43 /** 0 <= seconds < 24*3600 is invariant */ 44 int seconds; 45 /** 0 <= microseconds < 1000000 is invariant */ 46 int microseconds; 47 } 48 /** a pure abstract base clase */ 49 struct PyDateTime_TZInfo { 50 mixin PyObject_HEAD; 51 } 52 53 /** The datetime and time types have hashcodes, and an optional tzinfo member, 54 * present if and only if hastzinfo is true. 55 */ 56 template _PyTZINFO_HEAD() { 57 mixin PyObject_HEAD; 58 /// _ 59 Py_hash_t hashcode; 60 /// _ 61 ubyte hastzinfo; 62 } 63 64 /** No _PyDateTime_BaseTZInfo is allocated; it's just to have something 65 * convenient to cast to, when getting at the hastzinfo member of objects 66 * starting with _PyTZINFO_HEAD. 67 */ 68 struct _PyDateTime_BaseTZInfo { 69 mixin _PyTZINFO_HEAD; 70 } 71 72 /** All time objects are of PyDateTime_TimeType, but that can be allocated 73 * in two ways, with or without a tzinfo member. Without is the same as 74 * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an 75 * internal struct used to allocate the right amount of space for the 76 * "without" case. 77 */ 78 template _PyDateTime_TIMEHEAD() { 79 mixin _PyTZINFO_HEAD; 80 /// _ 81 ubyte[_PyDateTime_TIME_DATASIZE] data; 82 } 83 84 /// _ 85 struct _PyDateTime_BaseTime { 86 mixin _PyDateTime_TIMEHEAD; 87 } 88 89 /// _ 90 struct PyDateTime_Time { 91 mixin _PyDateTime_TIMEHEAD; 92 PyObject* tzinfo; 93 } 94 95 /** All datetime objects are of PyDateTime_DateTimeType, but that can be 96 * allocated in two ways too, just like for time objects above. In addition, 97 * the plain date type is a base class for datetime, so it must also have 98 * a hastzinfo member (although it's unused there). 99 */ 100 struct PyDateTime_Date { 101 mixin _PyTZINFO_HEAD; 102 /// _ 103 ubyte[_PyDateTime_DATE_DATASIZE] data; 104 } 105 106 /// _ 107 template _PyDateTime_DATETIMEHEAD() { 108 mixin _PyTZINFO_HEAD; 109 ubyte[_PyDateTime_DATETIME_DATASIZE] data; 110 } 111 112 /// _ 113 struct _PyDateTime_BaseDateTime { 114 mixin _PyDateTime_DATETIMEHEAD; 115 } 116 117 /// _ 118 struct PyDateTime_DateTime { 119 mixin _PyDateTime_DATETIMEHEAD; 120 PyObject* tzinfo; 121 } 122 123 // D translations of C macros: 124 /** Applies for date and datetime instances. */ 125 int PyDateTime_GET_YEAR()(PyObject* o) { 126 PyDateTime_Date* ot = cast(PyDateTime_Date*) o; 127 return (ot.data[0] << 8) | ot.data[1]; 128 } 129 /** Applies for date and datetime instances. */ 130 int PyDateTime_GET_MONTH()(PyObject* o) { 131 PyDateTime_Date* ot = cast(PyDateTime_Date*) o; 132 return ot.data[2]; 133 } 134 /** Applies for date and datetime instances. */ 135 int PyDateTime_GET_DAY()(PyObject* o) { 136 PyDateTime_Date* ot = cast(PyDateTime_Date*) o; 137 return ot.data[3]; 138 } 139 140 /** Applies for date and datetime instances. */ 141 int PyDateTime_DATE_GET_HOUR()(PyObject* o) { 142 PyDateTime_DateTime* ot = cast(PyDateTime_DateTime*) o; 143 return ot.data[4]; 144 } 145 /** Applies for date and datetime instances. */ 146 int PyDateTime_DATE_GET_MINUTE()(PyObject* o) { 147 PyDateTime_DateTime* ot = cast(PyDateTime_DateTime*) o; 148 return ot.data[5]; 149 } 150 /** Applies for date and datetime instances. */ 151 int PyDateTime_DATE_GET_SECOND()(PyObject* o) { 152 PyDateTime_DateTime* ot = cast(PyDateTime_DateTime*) o; 153 return ot.data[6]; 154 } 155 /** Applies for date and datetime instances. */ 156 int PyDateTime_DATE_GET_MICROSECOND()(PyObject* o) { 157 PyDateTime_DateTime* ot = cast(PyDateTime_DateTime*) o; 158 return (ot.data[7] << 16) | (ot.data[8] << 8) | ot.data[9]; 159 } 160 161 /** Applies for time instances. */ 162 int PyDateTime_TIME_GET_HOUR()(PyObject* o) { 163 PyDateTime_Time* ot = cast(PyDateTime_Time*) o; 164 return ot.data[0]; 165 } 166 /** Applies for time instances. */ 167 int PyDateTime_TIME_GET_MINUTE()(PyObject* o) { 168 PyDateTime_Time* ot = cast(PyDateTime_Time*) o; 169 return ot.data[1]; 170 } 171 /** Applies for time instances. */ 172 int PyDateTime_TIME_GET_SECOND()(PyObject* o) { 173 PyDateTime_Time* ot = cast(PyDateTime_Time*) o; 174 return ot.data[2]; 175 } 176 /** Applies for time instances. */ 177 int PyDateTime_TIME_GET_MICROSECOND()(PyObject* o) { 178 PyDateTime_Time* ot = cast(PyDateTime_Time*) o; 179 return (ot.data[3] << 16) | (ot.data[4] << 8) | ot.data[5]; 180 } 181 182 /** Structure for C API. */ 183 struct PyDateTime_CAPI { 184 /** type objects */ 185 PyTypeObject* DateType; 186 /// ditto 187 PyTypeObject* DateTimeType; 188 /// ditto 189 PyTypeObject* TimeType; 190 /// ditto 191 PyTypeObject* DeltaType; 192 /// ditto 193 PyTypeObject* TZInfoType; 194 195 /** constructors */ 196 PyObject* function(int, int, int, PyTypeObject*) Date_FromDate; 197 /// ditto 198 PyObject* function(int, int, int, int, int, int, int, 199 PyObject*, PyTypeObject*) DateTime_FromDateAndTime; 200 /// ditto 201 PyObject* function(int, int, int, int, PyObject*, PyTypeObject*) Time_FromTime; 202 /// ditto 203 PyObject* function(int, int, int, int, PyTypeObject*) Delta_FromDelta; 204 205 /** constructors for the DB API */ 206 PyObject* function(PyObject*, PyObject*, PyObject*) DateTime_FromTimestamp; 207 /// ditto 208 PyObject* function(PyObject*, PyObject*) Date_FromTimestamp; 209 } 210 211 // went away in python 3. who cares? 212 enum DATETIME_API_MAGIC = 0x414548d5; 213 214 version(PyCapsule) { 215 enum PyDateTime_CAPSULE_NAME = "datetime.datetime_CAPI"; 216 } 217 218 /// _ 219 static PyDateTime_CAPI* PyDateTimeAPI; 220 PyDateTime_CAPI* PyDateTime_IMPORT()() { 221 if (PyDateTimeAPI == null) { 222 version(PyCapsule) { 223 PyDateTimeAPI = cast(PyDateTime_CAPI*) 224 PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0); 225 }else { 226 PyDateTimeAPI = cast(PyDateTime_CAPI*) 227 PyCObject_Import("datetime", "datetime_CAPI"); 228 } 229 } 230 return PyDateTimeAPI; 231 } 232 233 // D translations of C macros: 234 /// _ 235 int PyDate_Check()(PyObject* op) { 236 return PyObject_TypeCheck(op, PyDateTimeAPI.DateType); 237 } 238 /// _ 239 int PyDate_CheckExact()(PyObject* op) { 240 return Py_TYPE(op) == PyDateTimeAPI.DateType; 241 } 242 /// _ 243 int PyDateTime_Check()(PyObject* op) { 244 return PyObject_TypeCheck(op, PyDateTimeAPI.DateTimeType); 245 } 246 /// _ 247 int PyDateTime_CheckExact()(PyObject* op) { 248 return Py_TYPE(op) == PyDateTimeAPI.DateTimeType; 249 } 250 /// _ 251 int PyTime_Check()(PyObject* op) { 252 return PyObject_TypeCheck(op, PyDateTimeAPI.TimeType); 253 } 254 /// _ 255 int PyTime_CheckExact()(PyObject* op) { 256 return Py_TYPE(op) == PyDateTimeAPI.TimeType; 257 } 258 /// _ 259 int PyDelta_Check()(PyObject* op) { 260 return PyObject_TypeCheck(op, PyDateTimeAPI.DeltaType); 261 } 262 /// _ 263 int PyDelta_CheckExact()(PyObject* op) { 264 return Py_TYPE(op) == PyDateTimeAPI.DeltaType; 265 } 266 /// _ 267 int PyTZInfo_Check()(PyObject* op) { 268 return PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType); 269 } 270 /// _ 271 int PyTZInfo_CheckExact()(PyObject* op) { 272 return Py_TYPE(op) == PyDateTimeAPI.TZInfoType; 273 } 274 275 /// _ 276 PyObject* PyDate_FromDate()(int year, int month, int day) { 277 return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType); 278 } 279 /// _ 280 PyObject* PyDateTime_FromDateAndTime()(int year, int month, int day, int hour, int min, int sec, int usec) { 281 return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, 282 min, sec, usec, cast(PyObject*) Py_None(), PyDateTimeAPI.DateTimeType); 283 } 284 /// _ 285 PyObject* PyTime_FromTime()(int hour, int minute, int second, int usecond) { 286 return PyDateTimeAPI.Time_FromTime(hour, minute, second, usecond, 287 cast(PyObject*) Py_None(), PyDateTimeAPI.TimeType); 288 } 289 /// _ 290 PyObject* PyDelta_FromDSU()(int days, int seconds, int useconds) { 291 return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, 292 PyDateTimeAPI.DeltaType); 293 } 294 /// _ 295 PyObject* PyDateTime_FromTimestamp()(PyObject* args) { 296 return PyDateTimeAPI.DateTime_FromTimestamp( 297 cast(PyObject*) (PyDateTimeAPI.DateTimeType), args, null); 298 } 299 /// _ 300 PyObject* PyDate_FromTimestamp()(PyObject* args) { 301 return PyDateTimeAPI.Date_FromTimestamp( 302 cast(PyObject*) (PyDateTimeAPI.DateType), args); 303 } 304 305