2
2
"""
3
3
Cython implementations of functions resembling the stdlib calendar module
4
4
"""
5
-
5
+ from libc.stdlib cimport abs as c_abs
6
6
cimport cython
7
7
from numpy cimport (
8
8
int32_t,
@@ -20,6 +20,7 @@ cdef int32_t* days_per_month_array = [
20
20
31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ]
21
21
22
22
cdef int * sakamoto_arr = [0 , 3 , 2 , 5 , 0 , 3 , 5 , 1 , 4 , 6 , 2 , 4 ]
23
+ cdef int * em = [0 ,0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 ]
23
24
24
25
# The first 13 entries give the month days elapsed as of the first of month N
25
26
# (or the total number of days in the year for N=13) in non-leap years.
@@ -73,14 +74,23 @@ cpdef int32_t get_days_in_month(int year, Py_ssize_t month) noexcept nogil:
73
74
"""
74
75
return days_per_month_array[12 * is_leapyear(year) + month - 1 ]
75
76
77
+ @ cython.wraparound (False )
78
+ @ cython.boundscheck (False )
79
+ @ cython.cdivision (True )
80
+ cdef long quot(long a , long b) noexcept nogil:
81
+ cdef long x
82
+ x = a/ b
83
+ if ( a < 0 ):
84
+ x -= ( a % b != 0 )
85
+ return x
76
86
77
87
@ cython.wraparound (False )
78
88
@ cython.boundscheck (False )
79
- @cython.cdivision
89
+ @ cython.cdivision ( True )
80
90
cdef int dayofweek(int y, int m, int d) noexcept nogil:
81
91
"""
82
92
Find the day of week for the date described by the Y/M/D triple y, m, d
83
- using Sakamoto's method, from wikipedia.
93
+ using Gauss' method, from wikipedia.
84
94
85
95
0 represents Monday. See [1]_.
86
96
@@ -103,16 +113,26 @@ cdef int dayofweek(int y, int m, int d) noexcept nogil:
103
113
[1] https://docs.python.org/3/library/calendar.html#calendar.weekday
104
114
105
115
[2] https://en.wikipedia.org/wiki/\
106
- Determination_of_the_day_of_the_week#Sakamoto.27s_methods
116
+ Determination_of_the_day_of_the_week#Gauss's_algorithm
107
117
"""
108
- cdef:
109
- int day
110
-
111
- y -= m < 3
112
- day = (y + y / 4 - y / 100 + y / 400 + sakamoto_arr[m - 1 ] + d) % 7
113
- # convert to python day
114
- return (day + 6 ) % 7
115
-
118
+
119
+ cdef:
120
+ long c
121
+ int g
122
+ int f
123
+ int e
124
+
125
+ if (m < 3 ):
126
+ y -= 1
127
+
128
+ c = quot(y, 100 )
129
+ g = y - quot(y, 100 ) * 100
130
+ f = 5 * (c - quot(c, 4 ) * 4 )
131
+ e = em[m]
132
+
133
+ if (m > 2 ):
134
+ e -= 1 ;
135
+ return (- 1 + d + e + f + g + g/ 4 ) % 7
116
136
117
137
cdef bint is_leapyear(int64_t year) noexcept nogil:
118
138
"""
0 commit comments