After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 753455 - datetime: allow passing just a time to gst_date_time_new_from_iso8601_string() and default to "today" as date then
datetime: allow passing just a time to gst_date_time_new_from_iso8601_string(...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other All
: Normal enhancement
: 1.5.90
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-08-10 12:34 UTC by Vivia Nikolaidou
Modified: 2015-08-16 13:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch file (4.03 KB, patch)
2015-08-10 12:34 UTC, Vivia Nikolaidou
none Details | Review
New patch. (9.58 KB, patch)
2015-08-10 15:39 UTC, Vivia Nikolaidou
committed Details | Review

Description Vivia Nikolaidou 2015-08-10 12:34:49 UTC
Created attachment 309007 [details] [review]
Patch file

If no date and only a time was given in gst_date_time_new_from_iso8601_string,
assume that it is "today" and try to parse the time-only string.
Comment 1 Vivia Nikolaidou 2015-08-10 13:01:36 UTC
Clarification: "today" is in the timezone provided by the user, if any, otherwise Z - just like the behavior of the existing code.
Comment 2 Tim-Philipp Müller 2015-08-10 13:18:57 UTC
Comment on attachment 309007 [details] [review]
Patch file

Thanks, looks mostly fine.

We should probably add a comment to the function docs giving some information on what formats it accepts (beyond just 'the most common formats'), i.e. also make it explicit that just passing in a time is acceptable as well now.

> 
>-  if (len < 4 || !g_ascii_isdigit (string[0]) || !g_ascii_isdigit (string[1])
>-      || !g_ascii_isdigit (string[2]) || !g_ascii_isdigit (string[3]))
>+  if (len < 4 || !g_ascii_isdigit (string[0]) || !g_ascii_isdigit (string[1]))
>     return NULL;

Here it would be nice to add a comment above that explains what the expected/allowed strings/formats/things are here (i.e. year or hour?)

 
>-  ret = sscanf (string, "%04d-%02d-%02d", &year, &month, &day);
>+  if (g_ascii_isdigit (string[2]) && g_ascii_isdigit (string[3])) {

I think we're now not bailing out when there are only 3 valid digits? (maybe add something to the unit test to check this)

> ymd_hms:
>+  if (year == -1 || month == -1 || day == -1) {
>+    GDateTime *g_date_now_utc, *g_date_now_in_given_tz;

Perhaps rename these to just 'now_utc' and 'now_in_given_tz', otherwise it looks like glib symbols.


>+    /* No date was supplied: make it today */
>+    g_date_now_utc = g_date_time_new_now_utc ();
>+    if (tzoffset != 0.0) {
>+      /* If a timezone offset was supplied, get the date of that timezone */
>+      gint offset_hours, offset_mins, offset_secs;
>+
>+      offset_hours = (gint) tzoffset;
>+      offset_mins = (gint) (60 * (tzoffset - offset_hours));
>+      offset_secs = (gint) (3600 * (tzoffset - offset_mins));
>+      g_date_now_in_given_tz =
>+          g_date_time_add_hours (g_date_now_utc, offset_hours);
>+      g_date_now_in_given_tz =
>+          g_date_time_add_minutes (g_date_now_in_given_tz, offset_mins);
>+      g_date_now_in_given_tz =
>+          g_date_time_add_seconds (g_date_now_in_given_tz, offset_secs);
>+    } else {
>+      g_date_now_in_given_tz = g_date_now_utc;
>+    }
>+    year = g_date_time_get_year (g_date_now_in_given_tz);
>+    month = g_date_time_get_month (g_date_now_in_given_tz);
>+    day = g_date_time_get_day_of_month (g_date_now_in_given_tz);
>+  }
>   return gst_date_time_new (tzoffset, year, month, day, hour, minute, second);

I think here you might be leaking the two GDateTime created earlier?

Also, did you check already if this code can be simplified e.g. by creating a GTimeZone or so?
Comment 3 Vivia Nikolaidou 2015-08-10 15:39:11 UTC
Thanks for the comments! Fixed in the code, except:

(In reply to Tim-Philipp Müller from comment #2)
> Comment on attachment 309007 [details] [review] [review]
>  
> >-  ret = sscanf (string, "%04d-%02d-%02d", &year, &month, &day);
> >+  if (g_ascii_isdigit (string[2]) && g_ascii_isdigit (string[3])) {
> 
> I think we're now not bailing out when there are only 3 valid digits? (maybe
> add something to the unit test to check this)

We are later, in this line:
  /* if hour or minute fails, then we will use only ymd. */
  hour = g_ascii_strtoull (string, (gchar **) & string, 10);
  if (hour > 24 || *string != ':')
    goto ymd;

I checked it manually but didn't find it necessary to add it in the unit test, do you still think it applies?

> >+    /* No date was supplied: make it today */
> >+    g_date_now_utc = g_date_time_new_now_utc ();
> >+    if (tzoffset != 0.0) {
> >+      /* If a timezone offset was supplied, get the date of that timezone */
> >+      gint offset_hours, offset_mins, offset_secs;
> >+
> >+      offset_hours = (gint) tzoffset;
> >+      offset_mins = (gint) (60 * (tzoffset - offset_hours));
> >+      offset_secs = (gint) (3600 * (tzoffset - offset_mins));
> >+      g_date_now_in_given_tz =
> >+          g_date_time_add_hours (g_date_now_utc, offset_hours);
> >+      g_date_now_in_given_tz =
> >+          g_date_time_add_minutes (g_date_now_in_given_tz, offset_mins);
> >+      g_date_now_in_given_tz =
> >+          g_date_time_add_seconds (g_date_now_in_given_tz, offset_secs);
> >+    } else {
> >+      g_date_now_in_given_tz = g_date_now_utc;
> >+    }
> >+    year = g_date_time_get_year (g_date_now_in_given_tz);
> >+    month = g_date_time_get_month (g_date_now_in_given_tz);
> >+    day = g_date_time_get_day_of_month (g_date_now_in_given_tz);
> >+  }
> >   return gst_date_time_new (tzoffset, year, month, day, hour, minute, second);
> 
> I think here you might be leaking the two GDateTime created earlier?

oops, yes :)
 
> Also, did you check already if this code can be simplified e.g. by creating
> a GTimeZone or so?

I didn't find a way to create a GTimeZone from a numeric offset, suggestions more than welcome!

However, I am now reusing the two offsets created earlier (seconds don't apply - shouldn't have used it!), and also using g_date_time_get_ymd to squeeze three lines of code into one.
Also initializing gmt_offset_{min,hour} to -99 instead of -1, because (especially for the hour!) -1 is a very valid value after my mild refactor.

Attaching new patch next.
Comment 4 Vivia Nikolaidou 2015-08-10 15:39:46 UTC
Created attachment 309017 [details] [review]
New patch.
Comment 5 Tim-Philipp Müller 2015-08-11 10:11:08 UTC
Thanks, pushed:

commit 88f6334af616b32fb8851d79faa8d31df552fea4
Author: Vivia Nikolaidou <vivia@ahiru.eu>
Date:   Mon Aug 10 15:31:37 2015 +0300

    datetime: accept just a time as ISO 8601 string and use today's date then
    
    If no date and only a time is given in gst_date_time_new_from_iso8601_string(),
    assume that it is "today" and try to parse the time-only string. "Today" is
    assumed to be in the timezone provided by the user (if any), otherwise Z -
    just like the behavior of the existing code.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=753455