mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
common: Add new function isodate_human_to_tm
* common/gettime.c (isotime_human_p): Add arg date_only. (isodate_human_to_tm): New. * common/t-gettime.c (test_isodate_human_to_tm): New. (main): Call new test. -- This function in intended as replacement for strptime (foo, "%Y-%m-%d", &bar) which is not available under Windows.
This commit is contained in:
parent
6ad95fe6f1
commit
f6670100b7
@ -216,9 +216,11 @@ isotime_p (const char *string)
|
||||
/* Scan a string and return true if the string represents the human
|
||||
readable format of an ISO time. This format is:
|
||||
yyyy-mm-dd[ hh[:mm[:ss]]]
|
||||
Scanning stops at the second space or at a comma. */
|
||||
Scanning stops at the second space or at a comma. If DATE_ONLY is
|
||||
true the time part is not expected and the scanning stops at the
|
||||
first space or at a comma. */
|
||||
int
|
||||
isotime_human_p (const char *string)
|
||||
isotime_human_p (const char *string, int date_only)
|
||||
{
|
||||
const char *s;
|
||||
int i;
|
||||
@ -247,6 +249,8 @@ isotime_human_p (const char *string)
|
||||
return 1; /* Okay; only date given. */
|
||||
if (!spacep (s))
|
||||
return 0;
|
||||
if (date_only)
|
||||
return 1; /* Okay; only date was requested. */
|
||||
s++;
|
||||
if (spacep (s))
|
||||
return 1; /* Okay, second space stops scanning. */
|
||||
@ -303,7 +307,7 @@ string2isotime (gnupg_isotime_t atime, const char *string)
|
||||
atime[15] = 0;
|
||||
return 15;
|
||||
}
|
||||
if (!isotime_human_p (string))
|
||||
if (!isotime_human_p (string, 0))
|
||||
return 0;
|
||||
atime[0] = string[0];
|
||||
atime[1] = string[1];
|
||||
@ -393,6 +397,36 @@ epoch2isotime (gnupg_isotime_t timebuf, time_t atime)
|
||||
}
|
||||
|
||||
|
||||
/* Parse a short ISO date string (YYYY-MM-DD) into a TM structure.
|
||||
Returns 0 on success. */
|
||||
int
|
||||
isodate_human_to_tm (const char *string, struct tm *t)
|
||||
{
|
||||
int year, month, day;
|
||||
|
||||
if (!isotime_human_p (string, 1))
|
||||
return -1;
|
||||
|
||||
year = atoi_4 (string);
|
||||
month = atoi_2 (string + 5);
|
||||
day = atoi_2 (string + 8);
|
||||
|
||||
/* Basic checks. */
|
||||
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31)
|
||||
return -1;
|
||||
|
||||
memset (t, 0, sizeof *t);
|
||||
t->tm_sec = 0;
|
||||
t->tm_min = 0;
|
||||
t->tm_hour = 0;
|
||||
t->tm_mday = day;
|
||||
t->tm_mon = month-1;
|
||||
t->tm_year = year - 1900;
|
||||
t->tm_isdst = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function is a copy of gpgme/src/conversion.c:_gpgme_timegm.
|
||||
If you change it, then update the other one too. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
|
@ -37,10 +37,11 @@ char *elapsed_time_string (time_t since, time_t now);
|
||||
|
||||
u32 scan_isodatestr (const char *string);
|
||||
int isotime_p (const char *string);
|
||||
int isotime_human_p (const char *string);
|
||||
int isotime_human_p (const char *string, int date_only);
|
||||
size_t string2isotime (gnupg_isotime_t atime, const char *string);
|
||||
time_t isotime2epoch (const char *string);
|
||||
void epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
|
||||
int isodate_human_to_tm (const char *string, struct tm *t);
|
||||
time_t parse_timestamp (const char *timestamp, char **endp);
|
||||
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
||||
const char *strtimevalue (u32 stamp);
|
||||
|
@ -174,6 +174,80 @@ test_string2isotime (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_isodate_human_to_tm (void)
|
||||
{
|
||||
struct {
|
||||
const char *string;
|
||||
int okay;
|
||||
int year, mon, mday;
|
||||
} array [] = {
|
||||
{ "1970-01-01", 1, 1970, 1, 1 },
|
||||
{ "1970-02-01", 1, 1970, 2, 1 },
|
||||
{ "1970-12-31", 1, 1970, 12, 31 },
|
||||
{ "1971-01-01", 1, 1971, 1, 1 },
|
||||
{ "1998-08-15", 1, 1998, 8, 15 },
|
||||
{ "2015-04-10", 1, 2015, 4, 10 },
|
||||
{ "2015-04-10 11:30",1, 2015, 4, 10 },
|
||||
{ "1969-12-31", 0, 0, 0, 0 },
|
||||
{ "1900-01-01", 0, 0, 0, 0 },
|
||||
{ "", 0, 0, 0, 0 },
|
||||
{ "1970-12-32", 0, 0, 0, 0 },
|
||||
{ "1970-13-01", 0, 0, 0, 0 },
|
||||
{ "1970-01-00", 0, 0, 0, 0 },
|
||||
{ "1970-00-01", 0, 0, 0, 0 },
|
||||
{ "1970-00-01", 0, 0, 0, 0 },
|
||||
{ "1970", 0, 0, 0, 0 },
|
||||
{ "1970-01", 0, 0, 0, 0 },
|
||||
{ "1970-01-1", 0, 0, 0, 0 },
|
||||
{ "1970-1--01", 0, 0, 0, 0 },
|
||||
{ "1970-01-01,", 1, 1970, 1, 1 },
|
||||
{ "1970-01-01 ", 1, 1970, 1, 1 },
|
||||
{ "1970-01-01\t", 1, 1970, 1, 1 },
|
||||
{ "1970-01-01;", 0, 0, 0, 0 },
|
||||
{ "1970-01-01:", 0, 0, 0, 0 },
|
||||
{ "1970_01-01", 0, 0, 0, 0 },
|
||||
{ "1970-01_01", 0, 0, 0, 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
int idx;
|
||||
int okay;
|
||||
struct tm tmbuf;
|
||||
|
||||
for (idx=0; array[idx].string; idx++)
|
||||
{
|
||||
okay = !isodate_human_to_tm (array[idx].string, &tmbuf);
|
||||
if (okay != array[idx].okay)
|
||||
{
|
||||
fail (idx);
|
||||
if (verbose)
|
||||
fprintf (stderr, "string '%s' expected: %d, got: %d\n",
|
||||
array[idx].string, (int)array[idx].okay, okay);
|
||||
}
|
||||
else if (!okay)
|
||||
;
|
||||
else if (tmbuf.tm_year + 1900 != array[idx].year
|
||||
|| tmbuf.tm_mon +1 != array[idx].mon
|
||||
|| tmbuf.tm_mday != array[idx].mday)
|
||||
{
|
||||
fail (idx);
|
||||
if (verbose)
|
||||
fprintf (stderr, "string '%s' returned %04d-%02d-%02d\n",
|
||||
array[idx].string,
|
||||
tmbuf.tm_year + 1900, tmbuf.tm_mon + 1, tmbuf.tm_mday);
|
||||
}
|
||||
else if (tmbuf.tm_sec || tmbuf.tm_min || tmbuf.tm_hour
|
||||
|| tmbuf.tm_isdst != -1)
|
||||
{
|
||||
fail (idx);
|
||||
if (verbose)
|
||||
fprintf (stderr, "string '%s' returned bad time part\n",
|
||||
array[idx].string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -182,6 +256,7 @@ main (int argc, char **argv)
|
||||
|
||||
test_isotime2epoch ();
|
||||
test_string2isotime ();
|
||||
test_isodate_human_to_tm ();
|
||||
|
||||
return !!errcount;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user