@@ -144,62 +144,49 @@ void timelib_isodate_from_date(timelib_sll y, timelib_sll m, timelib_sll d, time
144
144
* id = timelib_day_of_week_ex (y , m , d , 1 );
145
145
}
146
146
147
- static timelib_sll timelib_daynr_from_weeknr_ex (timelib_sll iy , timelib_sll iw , timelib_sll id , timelib_sll * y )
147
+ timelib_sll timelib_daynr_from_weeknr (timelib_sll iy , timelib_sll iw , timelib_sll id )
148
148
{
149
149
timelib_sll dow , day ;
150
150
151
151
/* Figure out the dayofweek for y-1-1 */
152
152
dow = timelib_day_of_week (iy , 1 , 1 );
153
153
/* then use that to figure out the offset for day 1 of week 1 */
154
154
day = 0 - (dow > 4 ? dow - 7 : dow );
155
- /* and adjust the year to the natural year if we need to */
156
- * y = (iw == 1 && day < 0 && id < dow ) ? iy - 1 : iy ;
157
155
158
156
/* Add weeks and days */
159
157
return day + ((iw - 1 ) * 7 ) + id ;
160
158
}
161
159
162
- timelib_sll timelib_daynr_from_weeknr (timelib_sll iy , timelib_sll iw , timelib_sll id )
163
- {
164
- timelib_sll dummy_iso_year ;
165
-
166
- return timelib_daynr_from_weeknr_ex (iy , iw , id , & dummy_iso_year );
167
- }
168
-
169
160
void timelib_date_from_isodate (timelib_sll iy , timelib_sll iw , timelib_sll id , timelib_sll * y , timelib_sll * m , timelib_sll * d )
170
161
{
171
- timelib_sll daynr = timelib_daynr_from_weeknr_ex (iy , iw , id , y ) + 1 ;
162
+ timelib_sll daynr = timelib_daynr_from_weeknr (iy , iw , id ) + 1 ;
172
163
int * table ;
164
+ bool is_leap_year ;
173
165
174
- * m = 0 ;
166
+ // Invariant: is_leap_year == timelib_is_leap(*y)
167
+ * y = iy ;
168
+ is_leap_year = timelib_is_leap (* y );
175
169
176
- if (daynr <= 0 ) {
177
- * y += 1 ;
170
+ // Establish invariant that daynr >= 0
171
+ while (daynr <= 0 ) {
172
+ * y -= 1 ;
173
+ daynr += (is_leap_year = timelib_is_leap (* y )) ? 366 : 365 ;
178
174
}
179
175
180
- if (timelib_is_leap (* y )) {
181
- table = ml_table_leap ;
182
- if (daynr > 366 ) {
183
- * y += 1 ;
184
- daynr -= 366 ;
185
- }
186
- } else {
187
- table = ml_table_common ;
188
- if (daynr > 365 ) {
189
- * y += 1 ;
190
- daynr -= 365 ;
191
- }
176
+ // Establish invariant that daynr <= number of days in *yr
177
+ while (daynr > (is_leap_year ? 366 : 365 )) {
178
+ daynr -= is_leap_year ? 366 : 365 ;
179
+ * y += 1 ;
180
+ is_leap_year = timelib_is_leap (* y );
192
181
}
193
182
194
- do {
195
- daynr -= table [* m ];
196
- (* m )++ ;
197
- } while (daynr > table [* m ]);
183
+ table = is_leap_year ? ml_table_leap : ml_table_common ;
198
184
199
- if (daynr <= 0 ) {
200
- daynr += 31 ;
201
- * y -= 1 ;
202
- * m = 12 ;
185
+ // Establish invariant that daynr <= number of days in *m
186
+ * m = 1 ;
187
+ while (daynr > table [* m ]) {
188
+ daynr -= table [* m ];
189
+ * m += 1 ;
203
190
}
204
191
205
192
* d = daynr ;
0 commit comments