11 static int scan_absolute(
DateTime *,
const char *);
12 static int more(
const char **);
13 static int minus_sign(
const char **);
14 static int is_bc(
const char **);
15 static int is_relative(
const char *);
16 static int relative_term(
const char **,
double *,
int *,
int *,
int *);
17 static int scan_tz(
const char *,
int *);
18 static int get_word(
const char **,
char *);
19 static char lowercase(
char);
20 static int which_month(
const char *,
int *);
21 static int scan_relative(
DateTime *,
const char *);
22 static int is_space(
char);
23 static int is_digit(
char);
24 static void skip_space(
const char **);
25 static int get_int(
const char **,
int *,
int *);
26 static int get_double(
const char **,
double *,
int *,
int *);
43 if (is_relative(buf)) {
44 if (scan_relative(dt, buf))
48 if (scan_absolute(dt, buf))
53 static const char *month_names[] = {
"jan",
"feb",
"mar",
"apr",
"may",
"jun",
54 "jul",
"aug",
"sep",
"oct",
"nov",
"dec"};
56 static int scan_absolute(
DateTime *dt,
const char *buf)
65 int year, month, day = 0, hour, minute;
73 if (!get_int(&p, &n, &ndigits)) {
74 if (!get_word(&p, word))
76 if (!which_month(word, &month))
78 if (!get_int(&p, &year, &ndigits))
87 if (bc || !get_word(&p, word)) {
94 if (!which_month(word, &month))
96 if (!get_int(&p, &year, &ndigits))
102 if (!get_int(&p, &hour, &ndigits))
108 if (!get_int(&p, &minute, &ndigits))
116 if (!get_double(&p, &second, &ndigits, &fracsec))
123 if (!get_word(&p, word))
125 if (!scan_tz(word, &tz))
170 static int scan_relative(
DateTime *dt,
const char *buf)
174 int ndigits, ndecimal;
177 int year = 0, month = 0, day = 0, hour = 0, minute = 0, fracsec = 0;
182 neg = minus_sign(&p);
186 while (relative_term(&p, &
x, &ndigits, &ndecimal, &pos)) {
223 for (pos = from; pos <= to; pos++) {
257 static int is_space(
char c)
259 return (c ==
' ' || c ==
'\t' || c ==
'\n');
262 static int is_digit(
char c)
264 return (c >=
'0' && c <=
'9');
267 static void skip_space(
const char **s)
269 while (is_space(**s))
273 static int get_int(
const char **s,
int *n,
int *ndigits)
280 for (*ndigits = 0; is_digit(*p); (*ndigits)++) {
287 return (*ndigits > 0);
290 static int get_double(
const char **s,
double *
x,
304 for (*ndigits = 0; is_digit(*p); (*ndigits)++)
308 while (is_digit(*p)) {
314 if (sscanf(buf,
"%lf",
x) != 1)
342 static int get_word(
const char **s,
char *word)
349 for (any = 0; *p && !is_space(*p); any = 1)
350 *word++ = lowercase(*p++);
356 static char lowercase(
char c)
358 if (c >=
'A' && c <=
'Z')
363 static int which_month(
const char *
name,
int *n)
367 for (i = 0; i < 12; i++)
368 if (strcmp(
name, month_names[i]) == 0) {
375 static int is_bc(
const char **s)
381 if (!get_word(&p, word))
383 if (strcmp(
"bc", word) != 0)
389 static int scan_tz(
const char *word,
int *tz)
395 else if (word[0] ==
'-')
400 if (!is_digit(word[1]))
402 if (!is_digit(word[2]))
404 if (!is_digit(word[3]))
406 if (!is_digit(word[4]))
409 *tz = (word[1] -
'0') * 600 + (word[2] -
'0') * 60 + (word[3] -
'0') * 10 +
420 static int relative_term(
const char **s,
double *
x,
int *ndigits,
int *ndecimal,
427 if (!get_double(&p,
x, ndigits, ndecimal) || !get_word(&p, word))
430 if (strcmp(word,
"year") == 0 || strcmp(word,
"years") == 0)
432 else if (strcmp(word,
"month") == 0 || strcmp(word,
"months") == 0 ||
433 strcmp(word,
"mon") == 0)
435 else if (strcmp(word,
"day") == 0 || strcmp(word,
"days") == 0)
437 else if (strcmp(word,
"hour") == 0 || strcmp(word,
"hours") == 0)
439 else if (strcmp(word,
"minute") == 0 || strcmp(word,
"minutes") == 0 ||
440 strcmp(word,
"min") == 0)
442 else if (strcmp(word,
"second") == 0 || strcmp(word,
"seconds") == 0 ||
443 strcmp(word,
"sec") == 0)
451 static int minus_sign(
const char **s)
461 static int is_relative(
const char *buf)
468 (void)minus_sign(&p);
469 return relative_term(&p, &
x, &n, &n, &n) != 0;
472 static int more(
const char **s)
#define DATETIME_ABSOLUTE
#define DATETIME_RELATIVE
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 ...
void datetime_set_negative(DateTime *dt)
Makes the DateTime negative. (B.C. for ABSOLUTE DateTimes)
int datetime_set_day(DateTime *dt, int day)
if dt.mode = ABSOLUTE, then the dt.year, dt.month:
int datetime_set_month(DateTime *dt, int month)
if dt.mode = ABSOLUTE, this also sets dt.day = 0
int datetime_set_type(DateTime *dt, int mode, int from, int to, int fracsec)
int datetime_set_timezone(DateTime *dt, int minutes)
returns 0 on success
int datetime_set_hour(DateTime *dt, int hour)
returns 0 on success or negative value on error
int datetime_set_year(DateTime *dt, int year)
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_set_minute(DateTime *dt, int minute)
returns 0 on success or negative value on error
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,...