]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/parseutils.c
avfilter/af_sofalizer: fix crash with odd IR size
[ffmpeg] / libavutil / parseutils.c
index 9fb8d0adb78fd4144866b214d33b8d7f001dc38e..0097bec3b94b71dc27e7b153677fb05671810f9b 100644 (file)
 #include "random_seed.h"
 #include "time_internal.h"
 #include "parseutils.h"
+#include "time.h"
 
 #ifdef TEST
 
 #define av_get_random_seed av_get_random_seed_deterministic
 static uint32_t av_get_random_seed_deterministic(void);
 
-#define time(t) 1331972053
+#define av_gettime() 1331972053200000
 
 #endif
 
@@ -558,28 +559,34 @@ time_t av_timegm(struct tm *tm)
 int av_parse_time(int64_t *timeval, const char *timestr, int duration)
 {
     const char *p, *q;
-    int64_t t;
+    int64_t t, now64;
     time_t now;
     struct tm dt = { 0 }, tmbuf;
     int today = 0, negative = 0, microseconds = 0;
     int i;
     static const char * const date_fmt[] = {
-        "%Y-%m-%d",
+        "%Y - %m - %d",
         "%Y%m%d",
     };
     static const char * const time_fmt[] = {
         "%H:%M:%S",
         "%H%M%S",
     };
+    static const char * const tz_fmt[] = {
+        "%H:%M",
+        "%H%M",
+        "%H",
+    };
 
     p = timestr;
     q = NULL;
     *timeval = INT64_MIN;
     if (!duration) {
-        now = time(0);
+        now64 = av_gettime();
+        now = now64 / 1000000;
 
         if (!av_strcasecmp(timestr, "now")) {
-            *timeval = (int64_t) now * 1000000;
+            *timeval = now64;
             return 0;
         }
 
@@ -598,8 +605,11 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
         }
         p = q;
 
-        if (*p == 'T' || *p == 't' || *p == ' ')
+        if (*p == 'T' || *p == 't')
             p++;
+        else
+            while (av_isspace(*p))
+                p++;
 
         /* parse the hour-minute-second part */
         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
@@ -653,7 +663,23 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
     } else {
         int is_utc = *q == 'Z' || *q == 'z';
+        int tzoffset = 0;
         q += is_utc;
+        if (!today && !is_utc && (*q == '+' || *q == '-')) {
+            struct tm tz = { 0 };
+            int sign = (*q == '+' ? -1 : 1);
+            q++;
+            p = q;
+            for (i = 0; i < FF_ARRAY_ELEMS(tz_fmt); i++) {
+                q = av_small_strptime(p, tz_fmt[i], &tz);
+                if (q)
+                    break;
+            }
+            if (!q)
+                return AVERROR(EINVAL);
+            tzoffset = sign * (tz.tm_hour * 60 + tz.tm_min) * 60;
+            is_utc = 1;
+        }
         if (today) { /* fill in today's date */
             struct tm dt2 = is_utc ? *gmtime_r(&now, &tmbuf) : *localtime_r(&now, &tmbuf);
             dt2.tm_hour = dt.tm_hour;
@@ -662,6 +688,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
             dt = dt2;
         }
         t = is_utc ? av_timegm(&dt) : mktime(&dt);
+        t += tzoffset;
     }
 
     /* Check that we are at the end of the string */
@@ -858,7 +885,10 @@ int main(void)
             "now",
             "12:35:46",
             "2000-12-20 0:02:47.5z",
+            "2012 - 02-22  17:44:07",
             "2000-12-20T010247.6",
+            "2000-12-12 1:35:46+05:30",
+            "2002-12-12 22:30:40-02",
         };
         static const char * const duration_string[] = {
             "2:34:56.79",
@@ -870,7 +900,7 @@ int main(void)
 
         av_log_set_level(AV_LOG_DEBUG);
         putenv(tzstr);
-        printf("(now is 2012-03-17 09:14:13 +0100, local time is UTC+1)\n");
+        printf("(now is 2012-03-17 09:14:13.2 +0100, local time is UTC+1)\n");
         for (i = 0;  i < FF_ARRAY_ELEMS(time_string); i++) {
             printf("%-24s -> ", time_string[i]);
             if (av_parse_time(&tv, time_string[i], 0)) {