9 #include <grass/datetime.h>
12 static int scan_absolute(DateTime *,
const char *);
13 static int more(
const char **);
14 static int minus_sign(
const char **);
15 static int is_bc(
const char **);
16 static int is_relative(
const char *);
17 static int relative_term(
const char **,
double *,
int *,
int *,
int *);
18 static int scan_tz(
const char *,
int *);
19 static int get_word(
const char **,
char *);
20 static char lowercase(
char);
21 static int which_month(
const char *,
int *);
22 static int scan_relative(DateTime *,
const char *);
23 static int is_space(
char);
24 static int is_digit(
char);
25 static void skip_space(
const char **);
26 static int get_int(
const char **,
int *,
int *);
27 static int get_double(
const char **,
double *,
int *,
int *);
45 if (is_relative(buf)) {
46 if (scan_relative(dt, buf))
50 if (scan_absolute(dt, buf))
55 static const char *month_names[] = {
56 "jan",
"feb",
"mar",
"apr",
"may",
"jun",
57 "jul",
"aug",
"sep",
"oct",
"nov",
"dec"
60 static int scan_absolute(DateTime * dt,
const char *
buf)
69 int year, month, day = 0, hour, minute;
77 if (!get_int(&p, &n, &ndigits)) {
78 if (!get_word(&p, word))
80 if (!which_month(word, &month))
82 if (!get_int(&p, &year, &ndigits))
91 if (bc || !get_word(&p, word)) {
98 if (!which_month(word, &month))
100 if (!get_int(&p, &year, &ndigits))
106 if (!get_int(&p, &hour, &ndigits))
112 if (!get_int(&p, &minute, &ndigits))
116 to = DATETIME_MINUTE;
120 if (!get_double(&p, &second, &ndigits, &fracsec))
124 to = DATETIME_SECOND;
127 if (!get_word(&p, word))
129 if (!scan_tz(word, &tz))
138 for (n = DATETIME_YEAR; n <= to; n++) {
156 case DATETIME_MINUTE:
160 case DATETIME_SECOND:
175 static int scan_relative(DateTime * dt,
const char *buf)
179 int ndigits, ndecimal;
182 int year = 0, month = 0, day = 0, hour = 0, minute = 0, fracsec = 0;
184 int from = DATETIME_SECOND + 1, to = DATETIME_YEAR - 1;
187 neg = minus_sign(&p);
191 while (relative_term(&p, &x, &ndigits, &ndecimal, &pos)) {
197 if (pos != DATETIME_SECOND && ndecimal != 0)
213 case DATETIME_MINUTE:
216 case DATETIME_SECOND:
228 for (pos = from; pos <= to; pos++) {
246 case DATETIME_MINUTE:
250 case DATETIME_SECOND:
262 static int is_space(
char c)
264 return (c ==
' ' || c ==
'\t' || c ==
'\n');
267 static int is_digit(
char c)
269 return (c >=
'0' && c <=
'9');
272 static void skip_space(
const char **
s)
274 while (is_space(**s))
278 static int get_int(
const char **s,
int *n,
int *ndigits)
285 for (*ndigits = 0; is_digit(*p); (*ndigits)++) {
292 return (*ndigits > 0);
295 static int get_double(
const char **s,
double *x,
int *ndigits,
308 for (*ndigits = 0; is_digit(*p); (*ndigits)++)
312 while (is_digit(*p)) {
318 if (sscanf(buf,
"%lf", x) != 1)
347 static int get_word(
const char **s,
char *word)
354 for (any = 0; *p && !is_space(*p); any = 1)
355 *word++ = lowercase(*p++);
361 static char lowercase(
char c)
363 if (c >=
'A' && c <=
'Z')
368 static int which_month(
const char *
name,
int *n)
372 for (i = 0; i < 12; i++)
373 if (strcmp(name, month_names[i]) == 0) {
380 static int is_bc(
const char **s)
386 if (!get_word(&p, word))
388 if (strcmp(
"bc", word) != 0)
394 static int scan_tz(
const char *word,
int *tz)
400 else if (word[0] ==
'-')
405 if (!is_digit(word[1]))
407 if (!is_digit(word[2]))
409 if (!is_digit(word[3]))
411 if (!is_digit(word[4]))
414 *tz = (word[1] -
'0') * 600 + (word[2] -
'0') * 60 +
415 (word[3] -
'0') * 10 + (word[4] -
'0');
425 static int relative_term(
const char **s,
426 double *x,
int *ndigits,
int *ndecimal,
int *pos)
432 if (!get_double(&p, x, ndigits, ndecimal) || !get_word(&p, word))
435 if (strcmp(word,
"year") == 0 || strcmp(word,
"years") == 0)
436 *pos = DATETIME_YEAR;
437 else if (strcmp(word,
"month") == 0 || strcmp(word,
"months") == 0 ||
438 strcmp(word,
"mon") == 0)
439 *pos = DATETIME_MONTH;
440 else if (strcmp(word,
"day") == 0 || strcmp(word,
"days") == 0)
442 else if (strcmp(word,
"hour") == 0 || strcmp(word,
"hours") == 0)
443 *pos = DATETIME_HOUR;
444 else if (strcmp(word,
"minute") == 0 || strcmp(word,
"minutes") == 0 ||
445 strcmp(word,
"min") == 0)
446 *pos = DATETIME_MINUTE;
447 else if (strcmp(word,
"second") == 0 || strcmp(word,
"seconds") == 0 ||
448 strcmp(word,
"sec") == 0)
449 *pos = DATETIME_SECOND;
456 static int minus_sign(
const char **s)
466 static int is_relative(
const char *buf)
473 (void)minus_sign(&p);
474 return relative_term(&p, &x, &n, &n, &n) != 0;
477 static int more(
const char **s)
int datetime_set_hour(DateTime *dt, int hour)
returns 0 on success or negative value on error
int datetime_set_day(DateTime *dt, int day)
if dt.mode = ABSOLUTE, then the dt.year, dt.month:
int datetime_set_type(DateTime *dt, int mode, int from, int to, int fracsec)
int datetime_set_year(DateTime *dt, int year)
if dt.mode = ABSOLUTE, this also sets dt.day = 0
int datetime_set_timezone(DateTime *dt, int minutes)
returns 0 on success
int datetime_set_month(DateTime *dt, int month)
if dt.mode = ABSOLUTE, this also sets dt.day = 0
int datetime_set_second(DateTime *dt, double second)
returns 0 on success or negative value on error
int datetime_error(int code, char *msg)
record 'code' and 'msg' as error code/msg (in static variables) code==0 will clear the error (ie set ...
int datetime_set_minute(DateTime *dt, int minute)
returns 0 on success or negative value on error
void datetime_set_negative(DateTime *dt)
Makes the DateTime negative. (B.C. for ABSOLUTE DateTimes)
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
int datetime_scan(DateTime *dt, const char *buf)
Convert the ascii string into a DateTime. This determines the mode/from/to based on the string...