All places where we use strptime/timegm()/mktime() are handling
conversion of dates in a format compatible with ISO 8601, so we
can use the GDateTime APIs to simplify code.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/domain_conf.c | 32 +++++--------------
src/esx/esx_vi_types.c | 71 +++++-------------------------------------
src/vz/vz_sdk.c | 10 +++---
3 files changed, 20 insertions(+), 93 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index afa072e17d..ee33b7caf0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13673,33 +13673,17 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
validTo = virXMLPropString(node, "passwdValidTo");
if (validTo) {
- char *tmp;
- struct tm tm;
- memset(&tm, 0, sizeof(tm));
- /* Expect: YYYY-MM-DDTHH:MM:SS (%d-%d-%dT%d:%d:%d) eg 2010-11-28T14:29:01 */
- if (/* year */
- virStrToLong_i(validTo, &tmp, 10, &tm.tm_year) < 0 || *tmp !=
'-' ||
- /* month */
- virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mon) < 0 || *tmp !=
'-' ||
- /* day */
- virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mday) < 0 || *tmp !=
'T' ||
- /* hour */
- virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_hour) < 0 || *tmp !=
':' ||
- /* minute */
- virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_min) < 0 || *tmp !=
':' ||
- /* second */
- virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_sec) < 0 || *tmp !=
'\0') {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse password validity time '%s',
expect YYYY-MM-DDTHH:MM:SS"),
- validTo);
- VIR_FREE(def->passwd);
+ g_autoptr(GDateTime) then = NULL;
+ g_autoptr(GTimeZone) tz = g_time_zone_new_utc();
+
+ then = g_date_time_new_from_iso8601(validTo, tz);
+ if (!then) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("password validity time '%s' values out of
range"), validTo);
return -1;
}
- tm.tm_year -= 1900; /* Human epoch starts at 0 BC, not 1900BC */
- tm.tm_mon--; /* Humans start months at 1, computers at 0 */
-
- def->validTo = timegm(&tm);
+ def->validTo = (int)g_date_time_to_unix(then);
def->expires = true;
}
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index 1deb5026b7..434313dfa4 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -1473,27 +1473,14 @@ int
esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
long long *secondsSinceEpoch)
{
- char value[64] = "";
- char *tmp;
- struct tm tm;
- int milliseconds;
- char sign;
- int tz_hours;
- int tz_minutes;
- int tz_offset = 0;
+ g_autoptr(GDateTime) then = NULL;
+ g_autoptr(GTimeZone) tz = NULL;
if (!dateTime || !secondsSinceEpoch) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
return -1;
}
- if (virStrcpyStatic(value, dateTime->value) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("xsd:dateTime value '%s' too long for
destination"),
- dateTime->value);
- return -1;
- }
-
/*
* expected format: [-]CCYY-MM-DDTHH:MM:SS[.ssssss][((+|-)HH:MM|Z)]
* typical example: 2010-04-05T12:13:55.316789+02:00
@@ -1502,66 +1489,22 @@ esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
*
* map negative years to 0, since the base for time_t is the year 1970.
*/
- if (*value == '-') {
+ if (*(dateTime->value) == '-') {
*secondsSinceEpoch = 0;
return 0;
}
- tmp = strptime(value, "%Y-%m-%dT%H:%M:%S", &tm);
+ tz = g_time_zone_new_utc();
+ then = g_date_time_new_from_iso8601(dateTime->value, tz);
- if (!tmp) {
+ if (!then) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("xsd:dateTime value '%s' has unexpected
format"),
dateTime->value);
return -1;
}
- if (*tmp != '\0') {
- /* skip .ssssss part if present */
- if (*tmp == '.' &&
- virStrToLong_i(tmp + 1, &tmp, 10, &milliseconds) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("xsd:dateTime value '%s' has unexpected
format"),
- dateTime->value);
- return -1;
- }
-
- /* parse timezone offset if present. if missing assume UTC */
- if (*tmp == '+' || *tmp == '-') {
- sign = *tmp;
-
- if (virStrToLong_i(tmp + 1, &tmp, 10, &tz_hours) < 0 ||
- *tmp != ':' ||
- virStrToLong_i(tmp + 1, NULL, 10, &tz_minutes) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("xsd:dateTime value '%s' has unexpected
format"),
- dateTime->value);
- return -1;
- }
-
- tz_offset = tz_hours * 60 * 60 + tz_minutes * 60;
-
- if (sign == '-')
- tz_offset = -tz_offset;
- } else if (STREQ(tmp, "Z")) {
- /* Z refers to UTC. tz_offset is already initialized to zero */
- } else {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("xsd:dateTime value '%s' has unexpected
format"),
- dateTime->value);
- return -1;
- }
- }
-
- /*
- * xsd:dateTime represents local time relative to the optional timezone
- * given as offset. pretend the local time is in UTC and use timegm in
- * order to avoid interference with the timezone to this computer.
- * apply timezone correction afterwards, because it's simpler than
- * handling all the possible over- and underflows when trying to apply
- * it to the tm struct.
- */
- *secondsSinceEpoch = timegm(&tm) - tz_offset;
+ *secondsSinceEpoch = g_date_time_to_unix(then);
return 0;
}
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 59d7d31419..c98542c244 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -4607,17 +4607,17 @@ int prlsdkSetMemsize(virDomainObjPtr dom, unsigned int memsize)
static long long
prlsdkParseDateTime(const char *str)
{
- struct tm tm;
- const char *tmp;
+ g_autoptr(GDateTime) then = NULL;
+ g_autoptr(GTimeZone) tz = g_time_zone_new_local();
- tmp = strptime(str, "%Y-%m-%d %H:%M:%S", &tm);
- if (!tmp || *tmp != '\0') {
+ then = g_date_time_new_from_iso8601(str, tz);
+ if (!then) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected DateTime format: '%s'"), str);
return -1;
}
- return mktime(&tm);
+ return g_date_time_to_unix(then);
}
static virDomainSnapshotObjListPtr
--
2.24.1