diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 1e59bd9cc7cedc732729a66bac88d80614503608..5aab6837c55d9c69cd15a0f5ea8f85668cbb2a76 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -343,11 +343,8 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
         c->start_time = s->timestamp;
     else
 #endif
-    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
-        struct tm time = {0};
-        strptime(t->value, "%Y - %m - %dT%T", &time);
-        c->start_time = mktime(&time);
-    }
+    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+        c->start_time = ff_iso8601_to_unix_time(t->value);
 
     for (i=0; i < c->n_ast; i++) {
         if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) {
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 2d4136ab86fc2a4ef37e6e703b00952f8ad9ed3e..99bd71938fd61cb16e64ea07c2e13e5e7ba53b01 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -402,12 +402,8 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
         timestamp = s->timestamp;
     else
 #endif
-    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
-        struct tm time = {0};
-        strptime(t->value, "%Y - %m - %dT%T", &time);
-        timestamp = mktime(&time);
-    }
-
+    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+        timestamp = ff_iso8601_to_unix_time(t->value);
 
     // XXX drop frame
     uint32_t timecode =
diff --git a/libavformat/internal.h b/libavformat/internal.h
index aba890def492a217139be48f43de1c6129916d11..8440e6bd0a12f7d81994e8164e1a4ae6cf02fbb6 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -248,4 +248,9 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
 
 enum CodecID ff_guess_image2_codec(const char *filename);
 
+/**
+ * Convert a date string in ISO8601 format to Unix timestamp.
+ */
+int64_t ff_iso8601_to_unix_time(const char *datestr);
+
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 78e5db74445358cec280350b6b8486a95b0d264f..12ebef5426c9133ed034291999ac3f1da43cbdba 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2266,11 +2266,8 @@ static int mov_write_header(AVFormatContext *s)
         mov->time = s->timestamp;
     else
 #endif
-    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
-        struct tm time = {0};
-        strptime(t->value, "%Y - %m - %dT%T", &time);
-        mov->time = mktime(&time);
-    }
+    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+        mov->time = ff_iso8601_to_unix_time(t->value);
     mov->time += 0x7C25B080; //1970 based -> 1904 based
 
     if (mov->chapter_track)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index d7cc5c1c67fba149f8339183a6f624cac895c270..10ba6f376152a60884f4c4ae8a87d9589785f4ec 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -1519,11 +1519,8 @@ static int mxf_write_header(AVFormatContext *s)
         timestamp = s->timestamp;
     else
 #endif
-    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
-        struct tm time = {0};
-        strptime(t->value, "%Y - %m - %dT%T", &time);
-        timestamp = mktime(&time);
-    }
+    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+        timestamp = ff_iso8601_to_unix_time(t->value);
     if (timestamp)
         mxf->timestamp = mxf_parse_timestamp(timestamp);
     mxf->duration = -1;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index bbd1b2d07bc76fb0d591edde5b6ff8092cd63112..bb12e24d8c7bbddb37e10dfabbe56ade3a3743fd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3884,3 +3884,10 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
     }
     av_strlcat(buf, rel, size);
 }
+
+int64_t ff_iso8601_to_unix_time(const char *datestr)
+{
+    struct tm time = {0};
+    strptime(datestr, "%Y - %m - %dT%T", &time);
+    return mktime(&time);
+}