1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
* Structures and functions for:
26
* Calculating day number in Gregorian and Julian proleptic calendars.
27
* Converting between day numbers and dates in the calendars.
28
* Converting between different calendars.
29
* Calculating differences between dates.
31
* Works used in research:
33
* @cite "Calendrical Calculations", Dershowitz and Reingold
34
* @cite ISO 8601 http://en.wikipedia.org/wiki/ISO_8601
35
* @cite http://www.ddj.com/hpc-high-performance-computing/197006254
36
* @cite http://en.wikipedia.org/wiki/Julian_day#Calculation
39
#ifndef DRIZZLED_CALENDAR_H
40
#define DRIZZLED_CALENDAR_H
42
#define JULIAN_DAY_NUMBER_AT_ABSOLUTE_DAY_ONE INT64_C(1721425)
44
#define DAYS_IN_NORMAL_YEAR INT32_C(365)
45
#define DAYS_IN_LEAP_YEAR INT32_C(366)
47
#define GREGORIAN_START_YEAR 1582
48
#define GREGORIAN_START_MONTH 10
49
#define GREGORIAN_START_DAY 15
51
#define UNIX_EPOCH_MIN_YEARS 1970
52
#define UNIX_EPOCH_MAX_YEARS 2038
54
#define CALENDAR_YY_PART_YEAR 70
57
* The following constants define the system of calculating the number
58
* of days in various periods of time in the Gregorian calendar.
60
* Leap years (years containing 366 days) occur:
62
* - When the year is evenly divisible by 4
63
* - If the year is evenly divisible by 100, it must also
64
* be evenly divisible by 400.
66
#define GREGORIAN_DAYS_IN_400_YEARS UINT32_C(146097)
67
#define GREGORIAN_DAYS_IN_100_YEARS UINT32_C(36524)
68
#define GREGORIAN_DAYS_IN_4_YEARS UINT32_C(1461)
74
* Different calendars supported by the temporal library
86
* Calculates the Julian Day Number from the year, month
87
* and day supplied for a Gregorian Proleptic calendar date.
91
* Year month and day values are assumed to be valid. This
92
* method does no bounds checking or validation.
95
* @param Month of date
98
int64_t julian_day_number_from_gregorian_date(uint32_t year, uint32_t month, uint32_t day);
101
* Translates an absolute day number to a
104
* @param The absolute day number
106
int64_t absolute_day_number_to_julian_day_number(int64_t absolute_day);
109
* Translates a Julian day number to an
110
* absolute day number.
112
* @param The Julian day number
114
int64_t julian_day_number_to_absolute_day_number(int64_t julian_day);
117
* Given a supplied Julian Day Number, populates a year, month, and day
118
* with the date in the Gregorian Proleptic calendar which corresponds to
119
* the given Julian Day Number.
121
* @param Julian Day Number
122
* @param Pointer to year to populate
123
* @param Pointer to month to populate
124
* @param Pointer to the day to populate
126
void gregorian_date_from_julian_day_number(int64_t julian_day
128
, uint32_t *month_out
129
, uint32_t *day_out);
132
* Given a supplied Absolute Day Number, populates a year, month, and day
133
* with the date in the Gregorian Proleptic calendar which corresponds to
134
* the given Absolute Day Number.
136
* @param Absolute Day Number
137
* @param Pointer to year to populate
138
* @param Pointer to month to populate
139
* @param Pointer to the day to populate
141
void gregorian_date_from_absolute_day_number(int64_t absolute_day
143
, uint32_t *month_out
144
, uint32_t *day_out);
147
* Returns the number of days in a particular year.
149
* @param year to evaluate
150
* @param calendar to use
152
uint32_t days_in_year(uint32_t year, enum calendar calendar);
155
* Returns the number of days in a particular Gregorian Proleptic calendar year.
157
* @param year to evaluate
159
uint32_t days_in_year_gregorian(uint32_t year);
162
* Returns the number of days in a particular Julian Proleptic calendar year.
164
* @param year to evaluate
166
uint32_t days_in_year_julian(uint32_t year);
169
* Returns the number of leap years that have
170
* occurred in the Julian Proleptic calendar
171
* up to the supplied year.
173
* @param year to evaluate (1 - 9999)
175
int32_t number_of_leap_years_julian(uint32_t year);
178
* Returns the number of leap years that have
179
* occurred in the Gregorian Proleptic calendar
180
* up to the supplied year.
182
* @param year to evaluate (1 - 9999)
184
int32_t number_of_leap_years_gregorian(uint32_t year);
187
* Returns the number of days in a month, given
188
* a year and a month in the Gregorian calendar.
190
* @param Year in Gregorian Proleptic calendar
191
* @param Month in date
193
uint32_t days_in_gregorian_year_month(uint32_t year, uint32_t month);
195
inline static bool num_leap_years(uint32_t y, enum calendar c)
197
return (c == GREGORIAN
198
? number_of_leap_years_gregorian(y)
199
: number_of_leap_years_julian(y));
203
* Returns the number of the day in a week.
205
* @see temporal_to_number_days()
209
* Day Day Number Sunday first day?
210
* -------------- ----------- -----------------
226
* @param Number of days since start of Gregorian calendar.
227
* @param Consider Sunday the first day of the week?
229
uint32_t day_of_week(int64_t day_number, bool sunday_is_first_day_of_week);
232
* Given a year, month, and day, returns whether the date is
233
* valid for the Gregorian proleptic calendar.
239
bool is_valid_gregorian_date(uint32_t year, uint32_t month, uint32_t day);
242
* Returns whether the supplied date components are within the
243
* range of the UNIX epoch.
245
* Times in the range of 1970-01-01T00:00:00 to 2038-01-19T03:14:07
254
bool in_unix_epoch_range(uint32_t year
262
* Returns the number of the week from a supplied year, month, and
263
* date in the Gregorian proleptic calendar. We use strftime() and
264
* the %U, %W, and %V format specifiers depending on the value
265
* of the sunday_is_first_day_of_week parameter.
267
* @param Subject year
268
* @param Subject month
270
* @param Is sunday the first day of the week?
271
* @param Pointer to a uint32_t to hold the resulting year, which
272
* may be incremented or decremented depending on flags
274
uint32_t week_number_from_gregorian_date(uint32_t year
277
, bool sunday_is_first_day_of_week);
280
* Returns the ISO week number of a supplied year, month, and
281
* date in the Gregorian proleptic calendar. We use strftime() and
282
* the %V format specifier to do the calculation, which yields a
283
* correct ISO 8601:1988 week number.
285
* The final year_out parameter is a pointer to an integer which will
286
* be set to the year in which the week belongs, according to ISO8601:1988,
287
* which may be different from the Gregorian calendar year.
289
* @see http://en.wikipedia.org/wiki/ISO_8601
291
* @param Subject year
292
* @param Subject month
295
uint32_t iso_week_number_from_gregorian_date(uint32_t year
299
* Takes a number in the form [YY]YYMM and converts it into
300
* a number of months.
302
* @param Period in the form [YY]YYMM
304
uint32_t year_month_to_months(uint32_t year_month);
307
* Takes a number of months and converts it to
308
* a period in the form YYYYMM.
310
* @param Number of months
312
uint32_t months_to_year_month(uint32_t months);
315
* Simple function returning whether the supplied year
316
* is a leap year in the supplied calendar.
318
* @param Year to evaluate
319
* @param Calendar to use
321
inline static bool is_leap_year(uint32_t y, enum calendar c)
323
return (days_in_year(y, c) == 366);
327
* Simple function returning whether the supplied year
328
* is a leap year in the Gregorian proleptic calendar.
330
inline static bool is_gregorian_leap_year(uint32_t y)
332
return (days_in_year_gregorian(y) == 366);
336
* Simple function returning whether the supplied year
337
* is a leap year in the Julian proleptic calendar.
339
inline static bool is_julian_leap_year(uint32_t y)
341
return (days_in_year_julian(y) == 366);
344
} /* namespace drizzled */
346
#endif /* DRIZZLED_CALENDAR_H */