GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-43be353b3f
datetime.c
Go to the documentation of this file.
1 /*!
2  \file lib/db/dbmi_base/datetime.c
3 
4  \brief DBMI Library (base) - datetime conversions
5 
6  (C) 1999-2009, 2011 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Joel Jones (CERL/UIUC), Radim Blazek
12  \author Doxygenized by Martin Landa <landa.martin gmail.com> (2011)
13  */
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <grass/dbmi.h>
18 
19 static char ds = '-';
20 static char ts = ':';
21 
22 /*!
23  \brief Convert datetime value into string
24 
25  \param value pointer to dbValue
26  \param sqltype SQL data type
27  \param[out] string pointer to dbString
28 
29  \return DB_OK on success
30  */
32  dbString *string)
33 {
34  int to, from;
35  int year, month, day, hour, minute;
36  double seconds;
37  char *xs;
38  char buf[64];
39 
41  return db_set_string(string, "CURRENT");
42 
43  *buf = 0;
44 
45  year = db_get_value_year(value);
46  month = db_get_value_month(value);
47  day = db_get_value_day(value);
48  hour = db_get_value_hour(value);
49  minute = db_get_value_minute(value);
50  seconds = db_get_value_seconds(value);
51  if (seconds < 10.0)
52  xs = "0";
53  else
54  xs = "";
55 
56  db_interval_range(sqltype, &from, &to);
57  switch (from) {
58  case DB_YEAR:
59  switch (to) {
60  case DB_YEAR:
61  sprintf(buf, "%d", year);
62  break;
63  case DB_MONTH:
64  sprintf(buf, "%d%c%02d", year, ds, month);
65  break;
66  case DB_DAY:
67  sprintf(buf, "%d%c%02d%c%02d", year, ds, month, ds, day);
68  break;
69  case DB_HOUR:
70  sprintf(buf, "%d%c%02d%c%02d %02d", year, ds, month, ds, day, hour);
71  break;
72  case DB_MINUTE:
73  sprintf(buf, "%d%c%02d%c%02d %02d%c%02d", year, ds, month, ds, day,
74  hour, ts, minute);
75  break;
76  case DB_SECOND:
77  case DB_FRACTION:
78  sprintf(buf, "%d%c%02d%c%02d %02d%c%02d%c%s%.10g", year, ds, month,
79  ds, day, hour, ts, minute, ts, xs, seconds);
80  break;
81  }
82  break;
83  case DB_MONTH:
84  switch (to) {
85  case DB_MONTH:
86  sprintf(buf, "%d", month);
87  break;
88  case DB_DAY:
89  sprintf(buf, "%02d%c%02d", month, ds, day);
90  break;
91  case DB_HOUR:
92  sprintf(buf, "%02d%c%02d %02d", month, ds, day, hour);
93  break;
94  case DB_MINUTE:
95  sprintf(buf, "%02d%c%02d %02d%c%02d", month, ds, day, hour, ts,
96  minute);
97  break;
98  case DB_SECOND:
99  case DB_FRACTION:
100  sprintf(buf, "%02d%c%02d %02d%c%02d%c%s%.10g", month, ds, day, hour,
101  ts, minute, ts, xs, seconds);
102  break;
103  }
104  break;
105  case DB_DAY:
106  switch (to) {
107  case DB_DAY:
108  sprintf(buf, "%02d", day);
109  break;
110  case DB_HOUR:
111  sprintf(buf, "%02d %02d", day, hour);
112  break;
113  case DB_MINUTE:
114  sprintf(buf, "%02d %02d%c%02d", day, hour, ts, minute);
115  break;
116  case DB_SECOND:
117  case DB_FRACTION:
118  sprintf(buf, "%02d %02d%c%02d%c%s%.10g", day, hour, ts, minute, ts,
119  xs, seconds);
120  break;
121  }
122  break;
123  case DB_HOUR:
124  switch (to) {
125  case DB_HOUR:
126  sprintf(buf, "%02d", hour);
127  break;
128  case DB_MINUTE:
129  sprintf(buf, "%02d%c%02d", hour, ts, minute);
130  break;
131  case DB_SECOND:
132  case DB_FRACTION:
133  sprintf(buf, "%02d%c%02d%c%s%.10g", hour, ts, minute, ts, xs,
134  seconds);
135  break;
136  }
137  break;
138  case DB_MINUTE:
139  switch (to) {
140  case DB_MINUTE:
141  sprintf(buf, "%02d", minute);
142  break;
143  case DB_SECOND:
144  case DB_FRACTION:
145  sprintf(buf, "%02d%c%s%.10g", minute, ts, xs, seconds);
146  break;
147  }
148  break;
149  case DB_SECOND:
150  case DB_FRACTION:
151  switch (to) {
152  case DB_SECOND:
153  case DB_FRACTION:
154  sprintf(buf, "%g", seconds);
155  break;
156  }
157  break;
158  default:
159  switch (sqltype) {
160  case DB_SQL_TYPE_DATE:
161  sprintf(buf, "%d%c%02d%c%02d", year, ds, month, ds, day);
162  break;
163  case DB_SQL_TYPE_TIME:
164  sprintf(buf, "%02d%c%02d%c%s%.10g", hour, ts, minute, ts, xs,
165  seconds);
166  break;
168  sprintf(buf, "%d%c%02d%c%02d %02d%c%02d%c%s%.10g", year, ds, month,
169  ds, day, hour, ts, minute, ts, xs, seconds);
170  break;
171  }
172  }
173  return db_set_string(string, buf);
174 }
175 
176 /*!
177  \brief Convert datetime string to value
178 
179  The format of <em>buf</em> must be as follows
180  - buf == "CURRENT" in a case-insignificant fashion value is marked as current
181  - sqltype == DB_SQL_TYPE_DATE
182  "year*month*day"
183  - sqltype == DB_SQL_TYPE_TIME
184  "hour*minute*second"
185  - sqltype == DB_SQL_TYPE_TIMESTAMP
186  "year*month*day hour*minute*second"
187  - otherwise the to and from markings in sqltype are used,
188  where "*" represents any non-whitespace character
189 
190  \param buf input string buffer
191  \param sqltype SQL data type
192  \param[out] value pointer to dbValue to be set
193 
194  \return DB_OK
195  */
196 int db_convert_Cstring_to_value_datetime(const char *buf, int sqltype,
197  dbValue *value)
198 {
199  int from, to;
200  int year, month, day, hour, minute;
201  double seconds;
202 
203  year = month = day = 0;
204  hour = minute = 0;
205  seconds = 0;
206 
207  if (db_nocase_compare(buf, "CURRENT")) {
209  return DB_OK;
210  }
211 
212  db_interval_range(sqltype, &from, &to);
213  switch (from) {
214  case DB_YEAR:
215  switch (to) {
216  case DB_YEAR:
217  sscanf(buf, "%d", &year);
218  break;
219  case DB_MONTH:
220  sscanf(buf, "%d%*c%d", &year, &month);
221  break;
222  case DB_DAY:
223  sscanf(buf, "%d%*c%d%*c%d", &year, &month, &day);
224  break;
225  case DB_HOUR:
226  sscanf(buf, "%d%*c%d%*c%d %d", &year, &month, &day, &hour);
227  break;
228  case DB_MINUTE:
229  sscanf(buf, "%d%*c%d%*c%d %d%*c%d", &year, &month, &day, &hour,
230  &minute);
231  break;
232  case DB_SECOND:
233  case DB_FRACTION:
234  sscanf(buf, "%d%*c%d%*c%d %d%*c%d%*c%lf", &year, &month, &day,
235  &hour, &minute, &seconds);
236  break;
237  }
238  break;
239  case DB_MONTH:
240  switch (to) {
241  case DB_MONTH:
242  sscanf(buf, "%d", &month);
243  break;
244  case DB_DAY:
245  sscanf(buf, "%d%*c%d", &month, &day);
246  break;
247  case DB_HOUR:
248  sscanf(buf, "%d%*c%d %d", &month, &day, &hour);
249  break;
250  case DB_MINUTE:
251  sscanf(buf, "%d%*c%d %d%*c%d", &month, &day, &hour, &minute);
252  break;
253  case DB_SECOND:
254  case DB_FRACTION:
255  sscanf(buf, "%d%*c%d %d%*c%d%*c%lf", &month, &day, &hour, &minute,
256  &seconds);
257  break;
258  }
259  break;
260  case DB_DAY:
261  switch (to) {
262  case DB_DAY:
263  sscanf(buf, "%d", &day);
264  break;
265  case DB_HOUR:
266  sscanf(buf, "%d %d", &day, &hour);
267  break;
268  case DB_MINUTE:
269  sscanf(buf, "%d %d%*c%d", &day, &hour, &minute);
270  break;
271  case DB_SECOND:
272  case DB_FRACTION:
273  sscanf(buf, "%d %d%*c%d%*c%lf", &day, &hour, &minute, &seconds);
274  break;
275  }
276  break;
277  case DB_HOUR:
278  switch (to) {
279  case DB_HOUR:
280  sscanf(buf, "%d", &hour);
281  break;
282  case DB_MINUTE:
283  sscanf(buf, "%d%*c%d", &hour, &minute);
284  break;
285  case DB_SECOND:
286  case DB_FRACTION:
287  sscanf(buf, "%d%*c%d%*c%lf", &hour, &minute, &seconds);
288  break;
289  }
290  break;
291  case DB_MINUTE:
292  switch (to) {
293  case DB_MINUTE:
294  sscanf(buf, "%d", &minute);
295  break;
296  case DB_SECOND:
297  case DB_FRACTION:
298  sscanf(buf, "%d%*c%lf", &minute, &seconds);
299  break;
300  }
301  break;
302  case DB_SECOND:
303  case DB_FRACTION:
304  sscanf(buf, "%lf", &seconds);
305  break;
306  default:
307  switch (sqltype) {
308  case DB_SQL_TYPE_DATE:
309  sscanf(buf, "%d%*c%d%*c%d", &year, &month, &day);
310  break;
311  case DB_SQL_TYPE_TIME:
312  sscanf(buf, "%d%*c%d%*c%lf", &hour, &minute, &seconds);
313  break;
315  sscanf(buf, "%d%*c%d%*c%d %d%*c%d%*c%lf", &year, &month, &day,
316  &hour, &minute, &seconds);
317  break;
318  }
319  }
320 
321  db_set_value_year(value, year);
322  db_set_value_month(value, month);
323  db_set_value_day(value, day);
324  db_set_value_hour(value, hour);
325  db_set_value_minute(value, minute);
326  db_set_value_seconds(value, seconds);
327 
328  return DB_OK;
329 }
int db_convert_value_datetime_into_string(dbValue *value, int sqltype, dbString *string)
Convert datetime value into string.
Definition: datetime.c:31
int db_convert_Cstring_to_value_datetime(const char *buf, int sqltype, dbValue *value)
Convert datetime string to value.
Definition: datetime.c:196
#define DB_FRACTION
Definition: dbmi.h:103
#define DB_SQL_TYPE_TIME
Definition: dbmi.h:89
#define DB_MINUTE
Definition: dbmi.h:101
#define DB_MONTH
Definition: dbmi.h:98
#define DB_YEAR
Definition: dbmi.h:97
#define DB_SQL_TYPE_DATE
Definition: dbmi.h:88
#define DB_HOUR
Definition: dbmi.h:100
#define DB_OK
Definition: dbmi.h:71
#define DB_SQL_TYPE_TIMESTAMP
Definition: dbmi.h:90
#define DB_DAY
Definition: dbmi.h:99
#define DB_SECOND
Definition: dbmi.h:102
int db_get_value_month(dbValue *)
Get month value.
Definition: value.c:116
void db_set_value_hour(dbValue *, int)
Set hour value.
Definition: value.c:267
int db_get_value_day(dbValue *)
Get day value.
Definition: value.c:128
void db_set_value_datetime_current(dbValue *)
Set datetime to current.
Definition: value.c:315
void db_set_value_year(dbValue *, int)
Set year value.
Definition: value.c:231
double db_get_value_seconds(dbValue *)
Get seconds value.
Definition: value.c:164
int db_get_value_year(dbValue *)
Get year value.
Definition: value.c:104
int db_set_string(dbString *, const char *)
Inserts string to dbString (enlarge string)
Definition: string.c:41
void db_set_value_minute(dbValue *, int)
Set minute value.
Definition: value.c:279
void db_set_value_seconds(dbValue *, double)
Set seconds value.
Definition: value.c:291
int db_get_value_hour(dbValue *)
Get hour value.
Definition: value.c:140
int db_get_value_minute(dbValue *)
Get minute value.
Definition: value.c:152
int db_nocase_compare(const char *, const char *)
Compare strings case-insensitive.
Definition: case.c:69
int db_test_value_datetime_current(dbValue *)
Check if datatime is current.
Definition: value.c:305
void db_set_value_day(dbValue *, int)
Set day value.
Definition: value.c:255
void db_set_value_month(dbValue *, int)
Set month value.
Definition: value.c:243
void db_interval_range(int, int *, int *)
Define range based on SQL data type.
Definition: interval.c:24