--- a/libpurple/tests/test_util.c Wed Sep 29 16:36:42 2021 -0500
+++ b/libpurple/tests/test_util.c Wed Oct 06 04:04:56 2021 -0500
@@ -160,23 +160,51 @@
+ gchar *oldtz = g_strdup(g_getenv("TZ")); + timestamp = purple_str_to_time("2010-08-27.134202-0700PDT", FALSE, &tm, &tz_off, &rest); + fail_unless(1282941722 == timestamp); + fail_unless((-7 * 60 * 60) == tz_off); + assert_string_equal("PDT", rest); fail_unless(377182200 == purple_str_to_time("19811214T12:50:00", TRUE, NULL, NULL, NULL));
- fail_unless(377203800 == purple_str_to_time("19811214T12:50:00-06", FALSE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21", TRUE, NULL, NULL, NULL));
fail_unless(1282941722 == purple_str_to_time("2010-08-27.204202", TRUE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21.3234", TRUE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21Z", TRUE, NULL, NULL, NULL));
fail_unless(1631512800 == purple_str_to_time("09-13-2021", TRUE, NULL, NULL, NULL));
- timestamp = purple_str_to_time("2010-08-27.134202-0700PDT", FALSE, &tm, &tz_off, &rest);
- fail_unless(1282941722 == timestamp);
- fail_unless((-7 * 60 * 60) == tz_off);
- assert_string_equal("PDT", rest);
+ /* For testing local time we use Asia/Kathmandu because it's +05:45 and + * doesn't have DST which means the test should always pass regardless of + * the time of year, at least until Kathmandu changes something. + g_setenv("TZ", "Asia/Kathmandu", TRUE); + /* There's a timezone in this timestamp, so the returned value will be in + * UTC with the offset added/subtracted. + fail_unless(377203800 == purple_str_to_time("19811214T12:50:00-06", FALSE, NULL, NULL, NULL)); + /* This also has a tz, so the returned value will be utc with the given + fail_unless(1569746481 == purple_str_to_time("2019-09-29T08:41:21.401000+00:00", FALSE, NULL, NULL, NULL)); + /* while it looks like the time is specified, this time is not valid + * according to our parser, so it's just the date which will be handled by timestamp = purple_str_to_time("09/13/202115:34:34", TRUE, NULL, NULL, &rest);
- fail_unless(1631512800 == timestamp);
+ fail_unless(1631470500 == timestamp); assert_string_equal("15:34:34", rest);
+ /* finally revert the TZ environment variable */ + g_setenv("TZ", oldtz, TRUE); --- a/libpurple/util.c Wed Sep 29 16:36:42 2021 -0500
+++ b/libpurple/util.c Wed Oct 06 04:04:56 2021 -0500
@@ -756,6 +756,7 @@
gboolean mktime_with_utc = FALSE, matched = FALSE;
+ gchar *hours = NULL, *minutes = NULL, *seconds = NULL; long tzoff = PURPLE_NO_TZ_OFF;
@@ -818,83 +819,80 @@
- match = g_match_info_fetch_named(info, "hours");
- if(match != NULL && *match != '\0') {
- t.tm_hour = atoi(match);
- match = g_match_info_fetch_named(info, "minutes");
- if(match != NULL && *match != '\0') {
- t.tm_min = atoi(match);
- match = g_match_info_fetch_named(info, "seconds");
- if(match != NULL && *match != '\0') {
- t.tm_sec = atoi(match);
- /* check if this is utc time */
- match = g_match_info_fetch_named(info, "utc");
- if(match != NULL && *match != '\0') {
- /* free match if it was just an empty string */
- /* if match is null, check if we have tzsign which is required */
- match = g_match_info_fetch_named(info, "tzsign");
- gint tzsign = -1, tzhour = 0, tzminute = 0;
- /* Figure out if we're ahead or behind of utc, assuming ahead by
+ hours = g_match_info_fetch_named(info, "hours"); + minutes = g_match_info_fetch_named(info, "minutes"); + seconds = g_match_info_fetch_named(info, "seconds"); + if(hours != NULL && *hours != '\0' && + minutes != NULL && *minutes != '\0' && + seconds != NULL && *seconds != '\0') + t.tm_hour = atoi(hours); + t.tm_min = atoi(minutes); + t.tm_sec = atoi(seconds); + /* check if this is utc time */ + match = g_match_info_fetch_named(info, "utc"); + if(match != NULL && *match != '\0') { + mktime_with_utc = TRUE; + /* free match if it was just an empty string */
- match = g_match_info_fetch_named(info, "tzhour");
- if(match != NULL && *match != '\0') {
- /* get the tz minute */
- match = g_match_info_fetch_named(info, "tzminute");
- if(match != NULL && *match != '\0') {
- tzminute = atoi(match);
- /* we need at least either an hour or minute to offset the timezone */
- if(tzhour > 0 || tzminute > 0) {
+ /* if match is null, check if we have tzsign which is required */ + match = g_match_info_fetch_named(info, "tzsign"); + gint tzsign = -1, tzhour = 0, tzminute = 0; + /* Figure out if we're ahead or behind of utc, assuming ahead by + match = g_match_info_fetch_named(info, "tzhour"); + if(match != NULL && *match != '\0') { + /* get the tz minute */ + match = g_match_info_fetch_named(info, "tzminute"); + if(match != NULL && *match != '\0') { + tzminute = atoi(match); + /* if the timezone is utc +00:00 or -00:00 tzoff will multiple out to + * be zero like it should be. tzoff = tzsign * ((tzhour * 3600) + (tzminute * 60));
- /* If we have a time, figure out if we need to adjust our tz offset. */
- if(t.tm_hour > 0 || t.tm_min > 0 || t.tm_sec > 0) {
+ /* If we have a time, figure out if we need to adjust our tz offset. */
+ t.tm_isdst = -1; /* -1 means dst info is not available */