1/* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#ifndef __G_DATE_H__
28#define __G_DATE_H__
29
30#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
31#error "Only <glib.h> can be included directly."
32#endif
33
34#include <time.h>
35
36#include <glib/gtypes.h>
37#include <glib/gquark.h>
38
39G_BEGIN_DECLS
40
41typedef gint32 GTime GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime);
42typedef guint16 GDateYear;
43typedef guint8 GDateDay; /* day of the month */
44typedef struct _GDate GDate;
45
46/* enum used to specify order of appearance in parsed date strings */
47typedef enum
48{
49 G_DATE_DAY = 0,
50 G_DATE_MONTH = 1,
51 G_DATE_YEAR = 2
52} GDateDMY;
53
54/* actual week and month values */
55typedef enum
56{
57 G_DATE_BAD_WEEKDAY = 0,
58 G_DATE_MONDAY = 1,
59 G_DATE_TUESDAY = 2,
60 G_DATE_WEDNESDAY = 3,
61 G_DATE_THURSDAY = 4,
62 G_DATE_FRIDAY = 5,
63 G_DATE_SATURDAY = 6,
64 G_DATE_SUNDAY = 7
65} GDateWeekday;
66typedef enum
67{
68 G_DATE_BAD_MONTH = 0,
69 G_DATE_JANUARY = 1,
70 G_DATE_FEBRUARY = 2,
71 G_DATE_MARCH = 3,
72 G_DATE_APRIL = 4,
73 G_DATE_MAY = 5,
74 G_DATE_JUNE = 6,
75 G_DATE_JULY = 7,
76 G_DATE_AUGUST = 8,
77 G_DATE_SEPTEMBER = 9,
78 G_DATE_OCTOBER = 10,
79 G_DATE_NOVEMBER = 11,
80 G_DATE_DECEMBER = 12
81} GDateMonth;
82
83#define G_DATE_BAD_JULIAN 0U
84#define G_DATE_BAD_DAY 0U
85#define G_DATE_BAD_YEAR 0U
86
87/* Note: directly manipulating structs is generally a bad idea, but
88 * in this case it's an *incredibly* bad idea, because all or part
89 * of this struct can be invalid at any given time. Use the functions,
90 * or you will get hosed, I promise.
91 */
92struct _GDate
93{
94 guint julian_days : 32; /* julian days representation - we use a
95 * bitfield hoping that 64 bit platforms
96 * will pack this whole struct in one big
97 * int
98 */
99
100 guint julian : 1; /* julian is valid */
101 guint dmy : 1; /* dmy is valid */
102
103 /* DMY representation */
104 guint day : 6;
105 guint month : 4;
106 guint year : 16;
107};
108
109/* g_date_new() returns an invalid date, you then have to _set() stuff
110 * to get a usable object. You can also allocate a GDate statically,
111 * then call g_date_clear() to initialize.
112 */
113GLIB_AVAILABLE_IN_ALL
114GDate* g_date_new (void);
115GLIB_AVAILABLE_IN_ALL
116GDate* g_date_new_dmy (GDateDay day,
117 GDateMonth month,
118 GDateYear year);
119GLIB_AVAILABLE_IN_ALL
120GDate* g_date_new_julian (guint32 julian_day);
121GLIB_AVAILABLE_IN_ALL
122void g_date_free (GDate *date);
123GLIB_AVAILABLE_IN_2_56
124GDate* g_date_copy (const GDate *date);
125
126/* check g_date_valid() after doing an operation that might fail, like
127 * _parse. Almost all g_date operations are undefined on invalid
128 * dates (the exceptions are the mutators, since you need those to
129 * return to validity).
130 */
131GLIB_AVAILABLE_IN_ALL
132gboolean g_date_valid (const GDate *date);
133GLIB_AVAILABLE_IN_ALL
134gboolean g_date_valid_day (GDateDay day) G_GNUC_CONST;
135GLIB_AVAILABLE_IN_ALL
136gboolean g_date_valid_month (GDateMonth month) G_GNUC_CONST;
137GLIB_AVAILABLE_IN_ALL
138gboolean g_date_valid_year (GDateYear year) G_GNUC_CONST;
139GLIB_AVAILABLE_IN_ALL
140gboolean g_date_valid_weekday (GDateWeekday weekday) G_GNUC_CONST;
141GLIB_AVAILABLE_IN_ALL
142gboolean g_date_valid_julian (guint32 julian_date) G_GNUC_CONST;
143GLIB_AVAILABLE_IN_ALL
144gboolean g_date_valid_dmy (GDateDay day,
145 GDateMonth month,
146 GDateYear year) G_GNUC_CONST;
147
148GLIB_AVAILABLE_IN_ALL
149GDateWeekday g_date_get_weekday (const GDate *date);
150GLIB_AVAILABLE_IN_ALL
151GDateMonth g_date_get_month (const GDate *date);
152GLIB_AVAILABLE_IN_ALL
153GDateYear g_date_get_year (const GDate *date);
154GLIB_AVAILABLE_IN_ALL
155GDateDay g_date_get_day (const GDate *date);
156GLIB_AVAILABLE_IN_ALL
157guint32 g_date_get_julian (const GDate *date);
158GLIB_AVAILABLE_IN_ALL
159guint g_date_get_day_of_year (const GDate *date);
160/* First monday/sunday is the start of week 1; if we haven't reached
161 * that day, return 0. These are not ISO weeks of the year; that
162 * routine needs to be added.
163 * these functions return the number of weeks, starting on the
164 * corresponding day
165 */
166GLIB_AVAILABLE_IN_ALL
167guint g_date_get_monday_week_of_year (const GDate *date);
168GLIB_AVAILABLE_IN_ALL
169guint g_date_get_sunday_week_of_year (const GDate *date);
170GLIB_AVAILABLE_IN_ALL
171guint g_date_get_iso8601_week_of_year (const GDate *date);
172
173/* If you create a static date struct you need to clear it to get it
174 * in a safe state before use. You can clear a whole array at
175 * once with the ndates argument.
176 */
177GLIB_AVAILABLE_IN_ALL
178void g_date_clear (GDate *date,
179 guint n_dates);
180
181/* The parse routine is meant for dates typed in by a user, so it
182 * permits many formats but tries to catch common typos. If your data
183 * needs to be strictly validated, it is not an appropriate function.
184 */
185GLIB_AVAILABLE_IN_ALL
186void g_date_set_parse (GDate *date,
187 const gchar *str);
188GLIB_AVAILABLE_IN_ALL
189void g_date_set_time_t (GDate *date,
190 time_t timet);
191G_GNUC_BEGIN_IGNORE_DEPRECATIONS
192GLIB_DEPRECATED_IN_2_62_FOR(g_date_set_time_t)
193void g_date_set_time_val (GDate *date,
194 GTimeVal *timeval);
195GLIB_DEPRECATED_FOR(g_date_set_time_t)
196void g_date_set_time (GDate *date,
197 GTime time_);
198G_GNUC_END_IGNORE_DEPRECATIONS
199GLIB_AVAILABLE_IN_ALL
200void g_date_set_month (GDate *date,
201 GDateMonth month);
202GLIB_AVAILABLE_IN_ALL
203void g_date_set_day (GDate *date,
204 GDateDay day);
205GLIB_AVAILABLE_IN_ALL
206void g_date_set_year (GDate *date,
207 GDateYear year);
208GLIB_AVAILABLE_IN_ALL
209void g_date_set_dmy (GDate *date,
210 GDateDay day,
211 GDateMonth month,
212 GDateYear y);
213GLIB_AVAILABLE_IN_ALL
214void g_date_set_julian (GDate *date,
215 guint32 julian_date);
216GLIB_AVAILABLE_IN_ALL
217gboolean g_date_is_first_of_month (const GDate *date);
218GLIB_AVAILABLE_IN_ALL
219gboolean g_date_is_last_of_month (const GDate *date);
220
221/* To go forward by some number of weeks just go forward weeks*7 days */
222GLIB_AVAILABLE_IN_ALL
223void g_date_add_days (GDate *date,
224 guint n_days);
225GLIB_AVAILABLE_IN_ALL
226void g_date_subtract_days (GDate *date,
227 guint n_days);
228
229/* If you add/sub months while day > 28, the day might change */
230GLIB_AVAILABLE_IN_ALL
231void g_date_add_months (GDate *date,
232 guint n_months);
233GLIB_AVAILABLE_IN_ALL
234void g_date_subtract_months (GDate *date,
235 guint n_months);
236
237/* If it's feb 29, changing years can move you to the 28th */
238GLIB_AVAILABLE_IN_ALL
239void g_date_add_years (GDate *date,
240 guint n_years);
241GLIB_AVAILABLE_IN_ALL
242void g_date_subtract_years (GDate *date,
243 guint n_years);
244GLIB_AVAILABLE_IN_ALL
245gboolean g_date_is_leap_year (GDateYear year) G_GNUC_CONST;
246GLIB_AVAILABLE_IN_ALL
247guint8 g_date_get_days_in_month (GDateMonth month,
248 GDateYear year) G_GNUC_CONST;
249GLIB_AVAILABLE_IN_ALL
250guint8 g_date_get_monday_weeks_in_year (GDateYear year) G_GNUC_CONST;
251GLIB_AVAILABLE_IN_ALL
252guint8 g_date_get_sunday_weeks_in_year (GDateYear year) G_GNUC_CONST;
253
254/* Returns the number of days between the two dates. If date2 comes
255 before date1, a negative value is return. */
256GLIB_AVAILABLE_IN_ALL
257gint g_date_days_between (const GDate *date1,
258 const GDate *date2);
259
260/* qsort-friendly (with a cast...) */
261GLIB_AVAILABLE_IN_ALL
262gint g_date_compare (const GDate *lhs,
263 const GDate *rhs);
264GLIB_AVAILABLE_IN_ALL
265void g_date_to_struct_tm (const GDate *date,
266 struct tm *tm);
267
268GLIB_AVAILABLE_IN_ALL
269void g_date_clamp (GDate *date,
270 const GDate *min_date,
271 const GDate *max_date);
272
273/* Swap date1 and date2's values if date1 > date2. */
274GLIB_AVAILABLE_IN_ALL
275void g_date_order (GDate *date1, GDate *date2);
276
277/* Just like strftime() except you can only use date-related formats.
278 * Using a time format is undefined.
279 */
280GLIB_AVAILABLE_IN_ALL
281gsize g_date_strftime (gchar *s,
282 gsize slen,
283 const gchar *format,
284 const GDate *date);
285
286#define g_date_weekday g_date_get_weekday GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_weekday)
287#define g_date_month g_date_get_month GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_month)
288#define g_date_year g_date_get_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_year)
289#define g_date_day g_date_get_day GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_day)
290#define g_date_julian g_date_get_julian GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_julian)
291#define g_date_day_of_year g_date_get_day_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_day_of_year)
292#define g_date_monday_week_of_year g_date_get_monday_week_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_monday_week_of_year)
293#define g_date_sunday_week_of_year g_date_get_sunday_week_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_sunday_week_of_year)
294#define g_date_days_in_month g_date_get_days_in_month GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_days_in_month)
295#define g_date_monday_weeks_in_year g_date_get_monday_weeks_in_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_monday_weeks_in_year)
296#define g_date_sunday_weeks_in_year g_date_get_sunday_weeks_in_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_sunday_weeks_in_year)
297
298G_END_DECLS
299
300#endif /* __G_DATE_H__ */
301