diff -Naur a/toys/posix/touch.c b/toys/posix/touch.c
--- a/toys/posix/touch.c	2014-10-02 18:23:27.000000000 +0530
+++ b/toys/posix/touch.c	2014-10-07 09:44:47.419560489 +0530
@@ -4,7 +4,7 @@
  *
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html 
 
-USE_TOUCH(NEWTOY(touch, "acd:mr:t:[!dtr]", TOYFLAG_BIN))
+USE_TOUCH(NEWTOY(touch, "<1acd:mr:t:[!dtr]", TOYFLAG_BIN))
 
 config TOUCH
   bool "touch"
@@ -18,7 +18,7 @@
     -m	change modification time
     -c	don't create file
     -d	set time to DATE (in YYYY-MM-DDThh:mm:SS[.frac][tz] format)
-    -t	set time to TIME (in [[CC]YY]MMDDhhmm[.ss][frac] format)
+    -t	set time to TIME (in [[CC]YY]MMDDhhmm[.ss] format)
     -r	set time same as reference FILE
 */
 
@@ -71,43 +71,69 @@
 
     if (toys.optflags & FLAG_d) {
       date = TT.date;
-      i = strlen(date);
-      if (i) {
+      tv->tv_usec = 0;
+      if ((i = strlen(date))) {
         // Trailing Z means UTC timezone, don't expect libc to know this.
         if (toupper(date[i-1])=='Z') {
           date[i-1] = 0;
           setenv("TZ", "UTC0", 1);
           localtime_r(&(tv->tv_sec), &tm);
         }
-        s = strptime(date, "%Y-%m-%dT%T", &tm);
-        if (s && *s=='.') {
-          sscanf(s, ".%d%n", &i, &len);
+
+        strcpy(toybuf, "%Y-%m-%dT%T");
+        if (!(s = strchr(date, '-'))) goto BAD_DATE;
+        if ((i = s-date) == 2) *(toybuf+1)='y';
+        if ((s = strchr(date, ' '))) *(toybuf+8) = ' ';
+        s = strptime(date, toybuf, &tm);
+        if (s && (*s=='.' || *s==',')) {
+          sscanf(++s, "%d%n", &i, &len);
           s += len;
           tv->tv_usec = i;
         }
       } else s = 0;
 
-    // Set time from -t?
+      // Set time from -t?
 
-    } else {
-      strcpy(toybuf, "%Y%m%d%H%M");
+    } else { // [[CC]YY]MMDDhhmm[.SS]
       date = TT.time;
-      for (i=0;i<3;i++) {
-        s = strptime(date, toybuf+(i&2), &tm);
-        if (s) break;
-        toybuf[1]='y';
+      tm.tm_sec = tv->tv_usec = 0;
+      i = ((s = strchr(date, '.'))) ? s-date : strlen(date);
+
+      if (i == 8) { // "%m%d%H%M"
+        if (sscanf(date, "%2u%2u%2u%2u%n", &(tm.tm_mon), &(tm.tm_mday),
+              &(tm.tm_hour), &(tm.tm_min), &i) != 4)
+          goto BAD_DATE;
+      } else if (i == 10 || i == 12) { // "%y%m%d%H%M" or "%Y%m%d%H%M"
+        unsigned curyear = tm.tm_year;
+
+        if (i == 10) strcpy(toybuf, "%2u%2u%2u%2u%2u%n");
+        else strcpy(toybuf, "%4u%2u%2u%2u%2u%n");
+
+        if (sscanf(date, toybuf, &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday),
+              &(tm.tm_hour), &(tm.tm_min), &i) != 5)
+          goto BAD_DATE;
+        if (i == 10 && curyear >= 50) {
+          tm.tm_year += (curyear / 100) * 100;
+          if (curyear - 50 > tm.tm_year) tm.tm_year += 100;
+          if (curyear + 50 < tm.tm_year) tm.tm_year -= 100;
+        } else tm.tm_year -= 1900;
       }
-      if (s && *s=='.') {
-        int count = sscanf(s, ".%2d%u%n", &(tm.tm_sec), &i, &len);
+      else  goto BAD_DATE;
 
-        if (count==2) tv->tv_usec = i;
-        s += len;
+      tm.tm_mon -= 1; // range: 0-11
+      if ((s = date + i) && *s=='.') {
+        if ((sscanf(s+1, "%2u%n", &(tm.tm_sec), &i) != 1) || *(s+i+1)) {
+BAD_DATE:
+          error_exit("bad '%s'", date);
+        }
+        s += (i+1);
       }
     }
 
     errno = 0;
     tv->tv_sec = mktime(&tm);
-    if (!s || *s || errno == EOVERFLOW) perror_exit("bad '%s'", date);
+    if (!s || *s || errno == EOVERFLOW || tv->tv_sec == -1L)
+      perror_exit("bad '%s'", date);
   }
   tv[1]=tv[0];
 
@@ -125,7 +151,7 @@
     if ((flag == (FLAG_m|FLAG_a) || !fetch(*ss, tv, flag)) && !utimes(*ss, tv))
       ss++;
     else if (toys.optflags & FLAG_c) ss++;
-    else if (-1 != (fd = open(*ss, O_CREAT, 0666))) close(fd);
+    else if (access(*ss, F_OK) && (-1 != (fd = open(*ss, O_CREAT, 0666)))) close(fd);
     else perror_msg("'%s'", *ss++);
   }
 }
