void QtCamMetaData::setDateTime(const QDateTime& dateTime) { QDate d = dateTime.date(); QTime t = dateTime.time(); int day = d.day(); int month = d.month(); int year = d.year(); int hour = t.hour(); int minute = t.minute(); // GstDateTime seconds expects microseconds to be there too :| gdouble seconds = t.second(); seconds += t.msec()/(1000.0); // Current UTC time. Created through string so that the link between // current and utc is lost and secsTo returns non-zero values. QDateTime utcTime = QDateTime::fromString(dateTime.toUTC().toString()); gfloat tzoffset = (utcTime.secsTo(dateTime)/3600.0); GstDateTime *dt = gst_date_time_new(tzoffset, year, month, day, hour, minute, seconds); d_ptr->addTag(GST_TAG_DATE_TIME, dt); gst_date_time_unref(dt); }
GstDateTime * gst_date_time_new_local_time (gint year, gint month, gint day, gint hour, gint minute, gdouble seconds) { GstDateTime *dt; dt = gst_date_time_new (0, year, month, day, hour, minute, seconds); gst_date_time_set_local_timezone (dt); return dt; }
GstDateTime * gst_date_time_new_from_unix_epoch_utc (gint64 secs) { GstDateTime *dt; struct tm tm; time_t tt; memset (&tm, 0, sizeof (tm)); tt = (time_t) secs; #ifdef HAVE_GMTIME_R gmtime_r (&tt, &tm); #else memcpy (&tm, gmtime (&tt), sizeof (struct tm)); #endif dt = gst_date_time_new (0, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); return dt; }
/** * gst_date_time_new_from_iso8601_string: * @string: ISO 8601-formatted datetime string. * * Tries to parse common variants of ISO-8601 datetime strings into a * #GstDateTime. Possible input formats are (for example): * 2012-06-30T22:46:43Z, 2012, 2012-06, 2012-06-30, 2012-06-30T22:46:43-0430, * 2012-06-30T22:46Z, 2012-06-30T22:46-0430, 2012-06-30 22:46, * 2012-06-30 22:46:43, 2012-06-00, 2012-00-00, 2012-00-30, 22:46:43Z, 22:46Z, * 22:46:43-0430, 22:46-0430, 22:46:30, 22:46 * If no date is provided, it is assumed to be "today" in the timezone * provided (if any), otherwise UTC. * * Free-function: gst_date_time_unref * * Returns: (transfer full) (nullable): a newly created #GstDateTime, * or %NULL on error */ GstDateTime * gst_date_time_new_from_iso8601_string (const gchar * string) { gint year = -1, month = -1, day = -1, hour = -1, minute = -1; gint gmt_offset_hour = -99, gmt_offset_min = -99; gdouble second = -1.0; gfloat tzoffset = 0.0; guint64 usecs; gint len, ret; g_return_val_if_fail (string != NULL, NULL); GST_DEBUG ("Parsing '%s' into a datetime", string); len = strlen (string); /* The input string is expected to start either with a year (4 digits) or * with an hour (2 digits). Hour must be followed by minute. In any case, * the string must be at least 4 characters long and start with 2 digits */ if (len < 4 || !g_ascii_isdigit (string[0]) || !g_ascii_isdigit (string[1])) return NULL; if (g_ascii_isdigit (string[2]) && g_ascii_isdigit (string[3])) { ret = sscanf (string, "%04d-%02d-%02d", &year, &month, &day); if (ret == 0) return NULL; if (ret == 3 && day <= 0) { ret = 2; day = -1; } if (ret >= 2 && month <= 0) { ret = 1; month = day = -1; } if (ret >= 1 && (year <= 0 || year > 9999 || month > 12 || day > 31)) return NULL; else if (ret >= 1 && len < 16) /* YMD is 10 chars. XMD + HM will be 16 chars. if it is less, * it make no sense to continue. We will stay with YMD. */ goto ymd; string += 10; /* Exit if there is no expeceted value on this stage */ if (!(*string == 'T' || *string == '-' || *string == ' ')) goto ymd; string += 1; } /* 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; /* minute */ minute = g_ascii_strtoull (string + 1, (gchar **) & string, 10); if (minute > 59) goto ymd; /* second */ if (*string == ':') { second = g_ascii_strtoull (string + 1, (gchar **) & string, 10); /* if we fail here, we still can reuse hour and minute. We * will still attempt to parse any timezone information */ if (second > 59) { second = -1.0; } else { /* microseconds */ if (*string == '.' || *string == ',') { const gchar *usec_start = string + 1; guint digits; usecs = g_ascii_strtoull (string + 1, (gchar **) & string, 10); if (usecs != G_MAXUINT64 && string > usec_start) { digits = (guint) (string - usec_start); second += (gdouble) usecs / pow (10.0, digits); } } } } if (*string == 'Z') goto ymd_hms; else { /* reuse some code from gst-plugins-base/gst-libs/gst/tag/gstxmptag.c */ gint gmt_offset = -1; gchar *plus_pos = NULL; gchar *neg_pos = NULL; gchar *pos = NULL; GST_LOG ("Checking for timezone information"); /* check if there is timezone info */ plus_pos = strrchr (string, '+'); neg_pos = strrchr (string, '-'); if (plus_pos) pos = plus_pos + 1; else if (neg_pos) pos = neg_pos + 1; if (pos && strlen (pos) >= 3) { gint ret_tz; if (pos[2] == ':') ret_tz = sscanf (pos, "%d:%d", &gmt_offset_hour, &gmt_offset_min); else ret_tz = sscanf (pos, "%02d%02d", &gmt_offset_hour, &gmt_offset_min); GST_DEBUG ("Parsing timezone: %s", pos); if (ret_tz == 2) { if (neg_pos != NULL && neg_pos + 1 == pos) { gmt_offset_hour *= -1; gmt_offset_min *= -1; } gmt_offset = gmt_offset_hour * 60 + gmt_offset_min; tzoffset = gmt_offset / 60.0; GST_LOG ("Timezone offset: %f (%d minutes)", tzoffset, gmt_offset); } else GST_WARNING ("Failed to parse timezone information"); } } ymd_hms: if (year == -1 || month == -1 || day == -1) { GDateTime *now_utc, *now_in_given_tz; /* No date was supplied: make it today */ now_utc = g_date_time_new_now_utc (); if (tzoffset != 0.0) { /* If a timezone offset was supplied, get the date of that timezone */ g_assert (gmt_offset_min != -99); g_assert (gmt_offset_hour != -99); now_in_given_tz = g_date_time_add_minutes (now_utc, (60 * gmt_offset_hour) + gmt_offset_min); g_date_time_unref (now_utc); } else { now_in_given_tz = now_utc; } g_date_time_get_ymd (now_in_given_tz, &year, &month, &day); g_date_time_unref (now_in_given_tz); } return gst_date_time_new (tzoffset, year, month, day, hour, minute, second); ymd: if (year == -1) { /* No date was supplied and time failed to parse */ return NULL; } return gst_date_time_new_ymd (year, month, day); }
/** * gst_date_time_new_ymd: * @year: the gregorian year * @month: the gregorian month * @day: the day of the gregorian month * * Creates a new #GstDateTime using the date and times in the gregorian calendar * in the local timezone. * * @year should be from 1 to 9999, @month should be from 1 to 12, @day from * 1 to 31. * * If value is -1 then all over value will be ignored. For example * if @month == -1, then #GstDateTime will created only for @year. If * @day == -1, then #GstDateTime will created for @year and @month and * so on. * * Free-function: gst_date_time_unref * * Return value: (transfer full): the newly created #GstDateTime */ GstDateTime * gst_date_time_new_ymd (gint year, gint month, gint day) { return gst_date_time_new (0.0, year, month, day, -1, -1, -1); }
/** * gst_date_time_new_ym: * @year: the gregorian year * @month: the gregorian month * * Creates a new #GstDateTime using the date and times in the gregorian calendar * in the local timezone. * * @year should be from 1 to 9999, @month should be from 1 to 12. * * If value is -1 then all over value will be ignored. For example * if @month == -1, then #GstDateTime will created only for @year. * * Free-function: gst_date_time_unref * * Return value: (transfer full): the newly created #GstDateTime */ GstDateTime * gst_date_time_new_ym (gint year, gint month) { return gst_date_time_new (0.0, year, month, -1, -1, -1, -1); }
/** * gst_date_time_new_y: * @year: the gregorian year * * Creates a new #GstDateTime using the date and times in the gregorian calendar * in the local timezone. * * @year should be from 1 to 9999. * * Free-function: gst_date_time_unref * * Return value: (transfer full): the newly created #GstDateTime */ GstDateTime * gst_date_time_new_y (gint year) { return gst_date_time_new (0.0, year, -1, -1, -1, -1, -1); }
/** * gst_date_time_new_from_iso8601_string: * @string: ISO 8601-formatted datetime string. * * Tries to parse common variants of ISO-8601 datetime strings into a * #GstDateTime. * * Free-function: gst_date_time_unref * * Returns: (transfer full): a newly created #GstDateTime, or NULL on error */ GstDateTime * gst_date_time_new_from_iso8601_string (const gchar * string) { gint year = -1, month = -1, day = -1, hour = -1, minute = -1; gdouble second = -1.0; gfloat tzoffset = 0.0; guint64 usecs; gint len, ret; g_return_val_if_fail (string != NULL, NULL); GST_DEBUG ("Parsing '%s' into a datetime", string); len = strlen (string); if (len < 4 || !g_ascii_isdigit (string[0]) || !g_ascii_isdigit (string[1]) || !g_ascii_isdigit (string[2]) || !g_ascii_isdigit (string[3])) return NULL; ret = sscanf (string, "%04d-%02d-%02d", &year, &month, &day); if (ret == 0) return NULL; if (ret == 3 && day <= 0) { ret = 2; day = -1; } if (ret >= 2 && month <= 0) { ret = 1; month = day = -1; } if (ret >= 1 && year <= 0) return NULL; else if (ret >= 1 && len < 16) /* YMD is 10 chars. XMD + HM will be 16 chars. if it is less, * it make no sense to continue. We will stay with YMD. */ goto ymd; string += 10; /* Exit if there is no expeceted value on this stage */ if (!(*string == 'T' || *string == '-' || *string == ' ')) goto ymd; /* if hour or minute fails, then we will use onlly ymd. */ hour = g_ascii_strtoull (string + 1, (gchar **) & string, 10); if (hour > 24 || *string != ':') goto ymd; /* minute */ minute = g_ascii_strtoull (string + 1, (gchar **) & string, 10); if (minute > 59) goto ymd; /* second */ if (*string == ':') { second = g_ascii_strtoull (string + 1, (gchar **) & string, 10); /* if we fail here, we still can reuse hour and minute. We * will still attempt to parse any timezone information */ if (second > 59) { second = -1.0; } else { /* microseconds */ if (*string == '.' || *string == ',') { const gchar *usec_start = string + 1; guint digits; usecs = g_ascii_strtoull (string + 1, (gchar **) & string, 10); if (usecs != G_MAXUINT64 && string > usec_start) { digits = (guint) (string - usec_start); second += (gdouble) usecs / pow (10.0, digits); } } } } if (*string == 'Z') goto ymd_hms; else { /* reuse some code from gst-plugins-base/gst-libs/gst/tag/gstxmptag.c */ gint gmt_offset_hour = -1, gmt_offset_min = -1, gmt_offset = -1; gchar *plus_pos = NULL; gchar *neg_pos = NULL; gchar *pos = NULL; GST_LOG ("Checking for timezone information"); /* check if there is timezone info */ plus_pos = strrchr (string, '+'); neg_pos = strrchr (string, '-'); if (plus_pos) pos = plus_pos + 1; else if (neg_pos) pos = neg_pos + 1; if (pos) { gint ret_tz; if (pos[2] == ':') ret_tz = sscanf (pos, "%d:%d", &gmt_offset_hour, &gmt_offset_min); else ret_tz = sscanf (pos, "%02d%02d", &gmt_offset_hour, &gmt_offset_min); GST_DEBUG ("Parsing timezone: %s", pos); if (ret_tz == 2) { gmt_offset = gmt_offset_hour * 60 + gmt_offset_min; if (neg_pos != NULL && neg_pos + 1 == pos) gmt_offset *= -1; tzoffset = gmt_offset / 60.0; GST_LOG ("Timezone offset: %f (%d minutes)", tzoffset, gmt_offset); } else GST_WARNING ("Failed to parse timezone information"); } } ymd_hms: return gst_date_time_new (tzoffset, year, month, day, hour, minute, second); ymd: return gst_date_time_new_ymd (year, month, day); }