mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +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
|
/* Scan a string and return true if the string represents the human
|
||||||
readable format of an ISO time. This format is:
|
readable format of an ISO time. This format is:
|
||||||
yyyy-mm-dd[ hh[:mm[:ss]]]
|
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
|
int
|
||||||
isotime_human_p (const char *string)
|
isotime_human_p (const char *string, int date_only)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
int i;
|
int i;
|
||||||
@ -247,6 +249,8 @@ isotime_human_p (const char *string)
|
|||||||
return 1; /* Okay; only date given. */
|
return 1; /* Okay; only date given. */
|
||||||
if (!spacep (s))
|
if (!spacep (s))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (date_only)
|
||||||
|
return 1; /* Okay; only date was requested. */
|
||||||
s++;
|
s++;
|
||||||
if (spacep (s))
|
if (spacep (s))
|
||||||
return 1; /* Okay, second space stops scanning. */
|
return 1; /* Okay, second space stops scanning. */
|
||||||
@ -303,7 +307,7 @@ string2isotime (gnupg_isotime_t atime, const char *string)
|
|||||||
atime[15] = 0;
|
atime[15] = 0;
|
||||||
return 15;
|
return 15;
|
||||||
}
|
}
|
||||||
if (!isotime_human_p (string))
|
if (!isotime_human_p (string, 0))
|
||||||
return 0;
|
return 0;
|
||||||
atime[0] = string[0];
|
atime[0] = string[0];
|
||||||
atime[1] = string[1];
|
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.
|
/* This function is a copy of gpgme/src/conversion.c:_gpgme_timegm.
|
||||||
If you change it, then update the other one too. */
|
If you change it, then update the other one too. */
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
@ -37,10 +37,11 @@ char *elapsed_time_string (time_t since, time_t now);
|
|||||||
|
|
||||||
u32 scan_isodatestr (const char *string);
|
u32 scan_isodatestr (const char *string);
|
||||||
int isotime_p (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);
|
size_t string2isotime (gnupg_isotime_t atime, const char *string);
|
||||||
time_t isotime2epoch (const char *string);
|
time_t isotime2epoch (const char *string);
|
||||||
void epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
|
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);
|
time_t parse_timestamp (const char *timestamp, char **endp);
|
||||||
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
||||||
const char *strtimevalue (u32 stamp);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -182,6 +256,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
test_isotime2epoch ();
|
test_isotime2epoch ();
|
||||||
test_string2isotime ();
|
test_string2isotime ();
|
||||||
|
test_isodate_human_to_tm ();
|
||||||
|
|
||||||
return !!errcount;
|
return !!errcount;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user