tar: support -T - and -X -
[oweals/busybox.git] / libbb / time.c
index 8d176e52e3a9d1ace0ef784e39ce1b465f264b2b..e2b938471357a264e34ebe08dbf750a5d5080d1f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2007 Denys Vlasenko
  *
- * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
 #include "libbb.h"
 
@@ -91,8 +91,15 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
                 * .SS  Seconds, a number from 0 to 61 (with leap seconds)
                 * Everything but the minutes is optional
                 *
-                * This coincides with the format of "touch -t TIME"
+                * "touch -t DATETIME" format: [[[[[YY]YY]MM]DD]hh]mm[.ss]
+                * Some, but not all, Unix "date DATETIME" commands
+                * move [[YY]YY] past minutes mm field (!).
+                * Coreutils date does it, and SUS mandates it.
+                * (date -s DATETIME does not support this format. lovely!)
+                * In bbox, this format is special-cased in date applet
+                * (IOW: this function assumes "touch -t" format).
                 */
+               unsigned cur_year = ptm->tm_year;
                int len = strchrnul(date_str, '.') - date_str;
 
                /* MM[.SS] */
@@ -133,6 +140,17 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
                                        &end) >= 5) {
                        /* Adjust month from 1-12 to 0-11 */
                        ptm->tm_mon -= 1;
+                       if ((int)cur_year >= 50) { /* >= 1950 */
+                               /* Adjust year: */
+                               /* 1. Put it in the current century */
+                               ptm->tm_year += (cur_year / 100) * 100;
+                               /* 2. If too far in the past, +100 years */
+                               if (ptm->tm_year < cur_year - 50)
+                                       ptm->tm_year += 100;
+                               /* 3. If too far in the future, -100 years */
+                               if (ptm->tm_year > cur_year + 50)
+                                       ptm->tm_year -= 100;
+                       }
                } else
                /* ccyymmddHHMM[.SS] */
                if (len == 12 && sscanf(date_str, "%4u%2u%2u%2u%2u%c",