diff -Nur zstd-1.5.0/programs/fileio.c new-zstd-1.5.0/programs/fileio.c
--- zstd-1.5.0/programs/fileio.c	2021-05-14 22:59:34.000000000 +0800
+++ new-zstd-1.5.0/programs/fileio.c	2021-10-25 10:30:36.546222652 +0800
@@ -1638,6 +1638,7 @@
     int closeDstFile = 0;
     int result;
     stat_t statbuf;
+    int transferMTime = 0;
     assert(ress.srcFile != NULL);
     if (ress.dstFile == NULL) {
         int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
@@ -1645,6 +1646,7 @@
           && UTIL_stat(srcFileName, &statbuf)
           && UTIL_isRegularFileStat(&statbuf) ) {
             dstFilePermissions = statbuf.st_mode;
+	    transferMTime = 1;
         }
 
         closeDstFile = 1;
@@ -1671,6 +1673,12 @@
             DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
             result=1;
         }
+
+	if (transferMTime) {
+		UTIL_utime(dstFileName, &statbuf);
+	}
+
+
         if ( (result != 0)  /* operation failure */
           && strcmp(dstFileName, stdoutmark)  /* special case : don't remove() stdout */
           ) {
@@ -2537,6 +2545,7 @@
     int result;
     stat_t statbuf;
     int releaseDstFile = 0;
+    int transferMTime = 0;
 
     if ((ress.dstFile == NULL) && (prefs->testMode==0)) {
         int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
@@ -2544,6 +2553,7 @@
           && UTIL_stat(srcFileName, &statbuf)
           && UTIL_isRegularFileStat(&statbuf) ) {
             dstFilePermissions = statbuf.st_mode;
+	    transferMTime = 1;
         }
 
         releaseDstFile = 1;
@@ -2568,7 +2578,9 @@
             DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
             result = 1;
         }
-
+	if (transferMTime) {
+		UTIL_utime(dstFileName, &statbuf);
+	}
         if ( (result != 0)  /* operation failure */
           && strcmp(dstFileName, stdoutmark)  /* special case : don't remove() stdout */
           ) {
diff -Nur zstd-1.5.0/programs/util.c new-zstd-1.5.0/programs/util.c
--- zstd-1.5.0/programs/util.c	2021-05-14 22:59:34.000000000 +0800
+++ new-zstd-1.5.0/programs/util.c	2021-10-25 10:30:43.246350653 +0800
@@ -31,6 +31,7 @@
 #  if PLATFORM_POSIX_VERSION < 200809L || !defined(st_mtime)
 #    include <utime.h>    /* utime */
 #  else
+#    include <utime.h>
 #    include <fcntl.h>    /* AT_FDCWD */
 #    include <sys/stat.h> /* utimensat */
 #  endif
@@ -159,6 +160,31 @@
     return chmod(filename, permissions);
 }
 
+/*set access and modification times */
+int UTIL_utime(const char* filename, const stat_t *statbuf)
+{
+    int ret;
+    /* We check that st_mtime is a macro here in order to give us confidence
+     * that struct stat has a struct timespec st_mtim member. We need this
+     * check because there are some platforms that claim to be POSIX 2008
+     * compliant but which do not have st_mtim...
+     * */
+#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_time)
+    /* (atime, mtime)*/
+    struct timespec timebuf[2] = { {0, UTIME_NOW} };
+    timebuf[1] = statbuf->st_mtim;
+    ret = utimensat(AT_FDCWD, filename, timebuf, 0);
+#else
+    struct utimbuf timebuf;
+    timebuf.actime = time(NULL);
+    timebuf.modtime = statbuf->st_mtime;
+    ret = utime(filename, &timebuf);
+#endif
+    errno = 0;
+    return ret;
+}
+
+
 int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
 {
     int res = 0;
@@ -168,25 +194,7 @@
         return -1;
 
     /* set access and modification times */
-    /* We check that st_mtime is a macro here in order to give us confidence
-     * that struct stat has a struct timespec st_mtim member. We need this
-     * check because there are some platforms that claim to be POSIX 2008
-     * compliant but which do not have st_mtim... */
-#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
-    {
-        /* (atime, mtime) */
-        struct timespec timebuf[2] = { {0, UTIME_NOW} };
-        timebuf[1] = statbuf->st_mtim;
-        res += utimensat(AT_FDCWD, filename, timebuf, 0);
-    }
-#else
-    {
-        struct utimbuf timebuf;
-        timebuf.actime = time(NULL);
-        timebuf.modtime = statbuf->st_mtime;
-        res += utime(filename, &timebuf);
-    }
-#endif
+    res += UTIL_utime(filename, statbuf);
 
 #if !defined(_WIN32)
     res += chown(filename, statbuf->st_uid, statbuf->st_gid);  /* Copy ownership */
diff -Nur zstd-1.5.0/programs/util.h new-zstd-1.5.0/programs/util.h
--- zstd-1.5.0/programs/util.h	2021-05-14 22:59:34.000000000 +0800
+++ new-zstd-1.5.0/programs/util.h	2021-10-25 10:30:43.246350653 +0800
@@ -135,6 +135,16 @@
  */
 int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
 
+/**
+ * Set atime to now and mtime to the st_mtim in statbuf.
+ *
+ * Directly wraps utime() or utimensat(). Returns -1 on error.
+ * Does not validate filename is valid.
+ * */
+int UTIL_utime(const char* filename, const stat_t *statbuf);
+
+
+
 /*
  * These helpers operate on a pre-populated stat_t, i.e., the result of
  * calling one of the above functions.
