liblog: logcat: Add year and zone to date on each line

- '-v year' modifier adds the four digit year prefix
- '-v <timezone>' modifier sets and prints the timezone suffix
- Only promise in logcat to support UTC as a timezone since
  all others are based on the configured environment
- '-v zone' modifier toggles the timezone suffix on or off
- '-T YYYY-MM-DD HH:MM:SS.mmm...' format is added

Bug: 23668700
Change-Id: I7521c1efb7455dc9a25434fce72a69a65dcf72ea
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index e598bb8..9440b68 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -260,7 +260,7 @@
                     "  -n <count>      Sets max number of rotated logs to <count>, default 4\n"
                     "  -v <format>     Sets the log print format, where <format> is:\n\n"
                     "                      brief color long printable process raw tag thread\n"
-                    "                      threadtime time usec\n\n"
+                    "                      threadtime time usec UTC year zone\n\n"
                     "  -D              print dividers between each log buffer\n"
                     "  -c              clear (flush) the entire log and exit\n"
                     "  -d              dump the log and then exit (don't block)\n"
@@ -268,7 +268,8 @@
                     "  -t '<time>'     print most recent lines since specified time (implies -d)\n"
                     "  -T <count>      print only the most recent <count> lines (does not imply -d)\n"
                     "  -T '<time>'     print most recent lines since specified time (not imply -d)\n"
-                    "                  count is pure numerical, time is 'MM-DD hh:mm:ss.mmm'\n"
+                    "                  count is pure numerical, time is 'MM-DD hh:mm:ss.mmm...'\n"
+                    "                  or 'YYYY-MM-DD hh:mm:ss.mmm...' format\n"
                     "  -g              get the size of the log's ring buffer and exit\n"
                     "  -L              dump logs from prior to last reboot\n"
                     "  -b <buffer>     Request alternate ring buffer, 'main', 'system', 'radio',\n"
@@ -377,7 +378,14 @@
     exit(EXIT_FAILURE);
 }
 
-static const char g_defaultTimeFormat[] = "%m-%d %H:%M:%S.%q";
+static char *parseTime(log_time &t, const char *cp) {
+
+    char *ep = t.strptime(cp, "%m-%d %H:%M:%S.%q");
+    if (ep) {
+        return ep;
+    }
+    return t.strptime(cp, "%Y-%m-%d %H:%M:%S.%q");
+}
 
 // Find last logged line in gestalt of all matching existing output files
 static log_time lastLogTime(char *outputFileName) {
@@ -423,7 +431,7 @@
         bool found = false;
         for (const auto& line : android::base::Split(file, "\n")) {
             log_time t(log_time::EPOCH);
-            char *ep = t.strptime(line.c_str(), g_defaultTimeFormat);
+            char *ep = parseTime(t, line.c_str());
             if (!ep || (*ep != ' ')) {
                 continue;
             }
@@ -522,11 +530,10 @@
                 /* FALLTHRU */
             case 'T':
                 if (strspn(optarg, "0123456789") != strlen(optarg)) {
-                    char *cp = tail_time.strptime(optarg, g_defaultTimeFormat);
+                    char *cp = parseTime(tail_time, optarg);
                     if (!cp) {
-                        logcat_panic(false,
-                                    "-%c \"%s\" not in \"%s\" time format\n",
-                                    ret, optarg, g_defaultTimeFormat);
+                        logcat_panic(false, "-%c \"%s\" not in time format\n",
+                                     ret, optarg);
                     }
                     if (*cp) {
                         char c = *cp;