diff --git a/README b/README
index 7bdf7bd..025d25f 100644
--- a/README
+++ b/README
@@ -73,7 +73,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
 =* tar             non-posix                    none
 =* tee             yes                          none
 #* test            yes                          none
-=* touch           yes                          none (-d) (-t)
+=* touch           yes                          none
 #* tr              yes                          none
 =* true            yes                          none
 =* tty             yes                          none
diff --git a/touch.1 b/touch.1
index 33a7bfb..3230b18 100644
--- a/touch.1
+++ b/touch.1
@@ -1,4 +1,4 @@
-.Dd February 19, 2015
+.Dd February 9, 2015
 .Dt TOUCH 1
 .Os sbase
 .Sh NAME
@@ -7,11 +7,11 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl acm
-.Op Fl r Ar ref_file | Fl t Ar timestamp
+.Op Fl d Ar time | Fl r Ar ref_file | Fl T Ar time | Fl t Ar time
 .Ar file ...
 .Sh DESCRIPTION
 .Nm
-sets the access or modification time of each
+sets the access and modification time of each
 .Ar file
 to the current time of day. If
 .Ar file
@@ -25,19 +25,30 @@ Set the access | modification time of
 Don't create
 .Ar file
 if it doesn't exist, not affecting exit status.
+.It Fl d Ar time
+Set the
+.Ar time
+of the format YYYY-MM-DDThh:mm:SS[Z] used for
+.Op Fl am .
 .It Fl r Ar ref_file
-Set the timestamp
-to be used with
+Set the
+.Ar time
+used for
 .Op Fl am
 to the modification time of
 .Ar ref_file .
-.It Fl t Ar timestamp
+.It Fl T Ar time
 Set the
-.Ar timestamp
-to be used with
+.Ar time
+used for
 .Op Fl am
 given as the number of seconds since the
 Unix epoch 1970-01-01T00:00:00Z.
+.It Fl t Ar time
+Set the
+.Ar time
+of the format [[CC]YY]MMDDhhmm[.SS] used for
+.Op Fl am .
 .El
 .Sh SEE ALSO
 .Xr date 1
@@ -46,10 +57,10 @@ The
 .Nm
 utility is compliant with the
 .St -p1003.1-2008
-specification except for
-.Fl d
-and the
-.Ar timestamp
-format of the
-.Fl t
-flag.
+specification, except from fractional seconds in the
+.Op Fl d
+argument.
+.Pp
+The
+.Op Fl T
+flag is an extension to this specification.
diff --git a/touch.c b/touch.c
index e836e27..41ff21c 100644
--- a/touch.c
+++ b/touch.c
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <utime.h>
@@ -43,6 +44,61 @@ touch(const char *file)
 	touch(file);
 }
 
+time_t
+parsetime(char *str, time_t current)
+{
+	struct tm *cur, t;
+	char *format;
+	size_t len = strlen(str);
+
+	cur = localtime(&current);
+	t.tm_isdst = -1;
+
+	switch (len) {
+	/* -t flag argument */
+	case 8:
+		t.tm_sec = 0;
+		t.tm_year = cur->tm_year;
+		format = "%m%d%H%M";
+		break;
+	case 10:
+		t.tm_sec = 0;
+		format = "%y%m%d%H%M";
+		break;
+	case 11:
+		t.tm_year = cur->tm_year;
+		format = "%m%d%H%M.%S";
+		break;
+	case 12:
+		t.tm_sec = 0;
+		format = "%Y%m%d%H%M";
+		break;
+	case 13:
+		format = "%y%m%d%H%M.%S";
+		break;
+	case 15:
+		format = "%Y%m%d%H%M.%S";
+		break;
+	/* -d flag argument */
+	case 19:
+		format = "%Y-%m-%dT%H:%M:%S";
+		break;
+	case 20:
+		/* only Zulu-timezone supported */
+		if (str[19] != 'Z')
+			goto default;
+		format = "%Y-%m-%dT%H:%M:%S%Z";
+		break;
+	default:
+		eprintf("Invalid date format length\n", str);
+	}
+
+	if (!strptime(str, format, &t))
+		weprintf("strptime %s: Invalid date format\n", str);
+
+	return mktime(&t);
+}
+
 static void
 usage(void)
 {
@@ -72,15 +128,20 @@ main(int argc, char *argv[])
 			eprintf("stat '%s':", ref);
 		t = st.st_mtime;
 		break;
-	case 't':
+	case 'T':
 		t = estrtonum(EARGF(usage()), 0, LLONG_MAX);
 		break;
+	case 't':
+		t = parsetime(EARGF(usage()), t);
+		break;
 	default:
 		usage();
 	} ARGEND;
 
 	if (argc < 1)
 		usage();
+	if (!aflag && !mflag)
+		aflag = mflag = 1;
 
 	for (; argc > 0; argc--, argv++)
 		touch(argv[0]);