1from cpython.object cimport PyObject
2
3cdef extern from "Python.h":
4    ctypedef struct PyTypeObject:
5        pass
6
7cdef extern from "datetime.h":
8
9    ctypedef extern class datetime.date[object PyDateTime_Date]:
10        pass
11
12    ctypedef extern class datetime.time[object PyDateTime_Time]:
13        pass
14
15    ctypedef extern class datetime.datetime[object PyDateTime_DateTime]:
16        pass
17
18    ctypedef extern class datetime.timedelta[object PyDateTime_Delta]:
19        pass
20
21    ctypedef extern class datetime.tzinfo[object PyDateTime_TZInfo]:
22        pass
23
24    ctypedef struct PyDateTime_Date:
25        pass
26
27    ctypedef struct PyDateTime_Time:
28        char hastzinfo
29        PyObject *tzinfo
30
31    ctypedef struct PyDateTime_DateTime:
32        char hastzinfo
33        PyObject *tzinfo
34
35    ctypedef struct PyDateTime_Delta:
36        int days
37        int seconds
38        int microseconds
39
40    # Define structure for C API.
41    ctypedef struct PyDateTime_CAPI:
42        # type objects
43        PyTypeObject *DateType
44        PyTypeObject *DateTimeType
45        PyTypeObject *TimeType
46        PyTypeObject *DeltaType
47        PyTypeObject *TZInfoType
48
49        # constructors
50        object (*Date_FromDate)(int, int, int, PyTypeObject*)
51        object (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*)
52        object (*Time_FromTime)(int, int, int, int, object, PyTypeObject*)
53        object (*Delta_FromDelta)(int, int, int, int, PyTypeObject*)
54
55        # constructors for the DB API
56        object (*DateTime_FromTimestamp)(object, object, object)
57        object (*Date_FromTimestamp)(object, object)
58
59    # Check type of the object.
60    bint PyDate_Check(object op)
61    bint PyDate_CheckExact(object op)
62
63    bint PyDateTime_Check(object op)
64    bint PyDateTime_CheckExact(object op)
65
66    bint PyTime_Check(object op)
67    bint PyTime_CheckExact(object op)
68
69    bint PyDelta_Check(object op)
70    bint PyDelta_CheckExact(object op)
71
72    bint PyTZInfo_Check(object op)
73    bint PyTZInfo_CheckExact(object op)
74
75    # Getters for date and datetime (C macros).
76    int PyDateTime_GET_YEAR(object o)
77    int PyDateTime_GET_MONTH(object o)
78    int PyDateTime_GET_DAY(object o)
79
80    # Getters for datetime (C macros).
81    int PyDateTime_DATE_GET_HOUR(object o)
82    int PyDateTime_DATE_GET_MINUTE(object o)
83    int PyDateTime_DATE_GET_SECOND(object o)
84    int PyDateTime_DATE_GET_MICROSECOND(object o)
85
86    # Getters for time (C macros).
87    int PyDateTime_TIME_GET_HOUR(object o)
88    int PyDateTime_TIME_GET_MINUTE(object o)
89    int PyDateTime_TIME_GET_SECOND(object o)
90    int PyDateTime_TIME_GET_MICROSECOND(object o)
91
92    # Getters for timedelta (C macros).
93    int PyDateTime_DELTA_GET_DAYS(object o)
94    int PyDateTime_DELTA_GET_SECONDS(object o)
95    int PyDateTime_DELTA_GET_MICROSECONDS(object o)
96
97    # PyDateTime CAPI object.
98    PyDateTime_CAPI *PyDateTimeAPI
99
100    void PyDateTime_IMPORT()
101
102# Datetime C API initialization function.
103# You have to call it before any usage of DateTime CAPI functions.
104cdef inline void import_datetime():
105    PyDateTime_IMPORT
106
107# Create date object using DateTime CAPI factory function.
108# Note, there are no range checks for any of the arguments.
109cdef inline object date_new(int year, int month, int day):
110    return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType)
111
112# Create time object using DateTime CAPI factory function
113# Note, there are no range checks for any of the arguments.
114cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz):
115    return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType)
116
117# Create datetime object using DateTime CAPI factory function.
118# Note, there are no range checks for any of the arguments.
119cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz):
120    return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType)
121
122# Create timedelta object using DateTime CAPI factory function.
123# Note, there are no range checks for any of the arguments.
124cdef inline object timedelta_new(int days, int seconds, int useconds):
125    return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType)
126
127# More recognizable getters for date/time/datetime/timedelta.
128# There are no setters because datetime.h hasn't them.
129# This is because of immutable nature of these objects by design.
130# If you would change time/date/datetime/timedelta object you need to recreate.
131
132# Get tzinfo of time
133cdef inline object time_tzinfo(object o):
134    if (<PyDateTime_Time*>o).hastzinfo:
135        return <object>(<PyDateTime_Time*>o).tzinfo
136    else:
137        return None
138
139# Get tzinfo of datetime
140cdef inline object datetime_tzinfo(object o):
141    if (<PyDateTime_DateTime*>o).hastzinfo:
142        return <object>(<PyDateTime_DateTime*>o).tzinfo
143    else:
144        return None
145
146# Get year of date
147cdef inline int date_year(object o):
148    return PyDateTime_GET_YEAR(o)
149
150# Get month of date
151cdef inline int date_month(object o):
152    return PyDateTime_GET_MONTH(o)
153
154# Get day of date
155cdef inline int date_day(object o):
156    return PyDateTime_GET_DAY(o)
157
158# Get year of datetime
159cdef inline int datetime_year(object o):
160    return PyDateTime_GET_YEAR(o)
161
162# Get month of datetime
163cdef inline int datetime_month(object o):
164    return PyDateTime_GET_MONTH(o)
165
166# Get day of datetime
167cdef inline int datetime_day(object o):
168    return PyDateTime_GET_DAY(o)
169
170# Get hour of time
171cdef inline int time_hour(object o):
172    return PyDateTime_TIME_GET_HOUR(o)
173
174# Get minute of time
175cdef inline int time_minute(object o):
176    return PyDateTime_TIME_GET_MINUTE(o)
177
178# Get second of time
179cdef inline int time_second(object o):
180    return PyDateTime_TIME_GET_SECOND(o)
181
182# Get microsecond of time
183cdef inline int time_microsecond(object o):
184    return PyDateTime_TIME_GET_MICROSECOND(o)
185
186# Get hour of datetime
187cdef inline int datetime_hour(object o):
188    return PyDateTime_DATE_GET_HOUR(o)
189
190# Get minute of datetime
191cdef inline int datetime_minute(object o):
192    return PyDateTime_DATE_GET_MINUTE(o)
193
194# Get second of datetime
195cdef inline int datetime_second(object o):
196    return PyDateTime_DATE_GET_SECOND(o)
197
198# Get microsecond of datetime
199cdef inline int datetime_microsecond(object o):
200    return PyDateTime_DATE_GET_MICROSECOND(o)
201
202# Get days of timedelta
203cdef inline int timedelta_days(object o):
204    return (<PyDateTime_Delta*>o).days
205
206# Get seconds of timedelta
207cdef inline int timedelta_seconds(object o):
208    return (<PyDateTime_Delta*>o).seconds
209
210# Get microseconds of timedelta
211cdef inline int timedelta_microseconds(object o):
212    return (<PyDateTime_Delta*>o).microseconds
213