diff --git a/cmd/crictl/container.go b/cmd/crictl/container.go
index 9778484a8a..6f607812aa 100644
--- a/cmd/crictl/container.go
+++ b/cmd/crictl/container.go
@@ -17,6 +17,7 @@ limitations under the License.
 package main
 
 import (
+	"encoding/json"
 	"fmt"
 	"log"
 	"os"
@@ -459,6 +460,24 @@ func RemoveContainer(client pb.RuntimeServiceClient, ID string) error {
 	return nil
 }
 
+// marshalContainerStatus converts container status into string and converts
+// the timestamps into readable format.
+func marshalContainerStatus(cs *pb.ContainerStatus) (string, error) {
+	statusStr, err := protobufObjectToJSON(cs)
+	if err != nil {
+		return "", err
+	}
+	jsonMap := make(map[string]interface{})
+	err = json.Unmarshal([]byte(statusStr), &jsonMap)
+	if err != nil {
+		return "", err
+	}
+	jsonMap["createdAt"] = time.Unix(0, cs.CreatedAt).Format(time.RFC3339Nano)
+	jsonMap["startedAt"] = time.Unix(0, cs.StartedAt).Format(time.RFC3339Nano)
+	jsonMap["finishedAt"] = time.Unix(0, cs.FinishedAt).Format(time.RFC3339Nano)
+	return marshalMapInOrder(jsonMap, *cs)
+}
+
 // ContainerStatus sends a ContainerStatusRequest to the server, and parses
 // the returned ContainerStatusResponse.
 func ContainerStatus(client pb.RuntimeServiceClient, ID, output string, quiet bool) error {
@@ -480,9 +499,14 @@ func ContainerStatus(client pb.RuntimeServiceClient, ID, output string, quiet bo
 		return err
 	}
 
+	status, err := marshalContainerStatus(r.Status)
+	if err != nil {
+		return err
+	}
+
 	switch output {
 	case "json", "yaml":
-		return outputStatusInfo(r.Status, r.Info, output)
+		return outputStatusInfo(status, r.Info, output)
 	case "table": // table output is after this switch block
 	default:
 		return fmt.Errorf("output option cannot be %s", output)
diff --git a/cmd/crictl/image.go b/cmd/crictl/image.go
index 2d154ef86b..6e3c606046 100644
--- a/cmd/crictl/image.go
+++ b/cmd/crictl/image.go
@@ -217,9 +217,13 @@ var imageStatusCommand = cli.Command{
 			output = "json"
 		}
 
+		status, err := protobufObjectToJSON(r.Image)
+		if err != nil {
+			return err
+		}
 		switch output {
 		case "json", "yaml":
-			return outputStatusInfo(r.Image, r.Info, output)
+			return outputStatusInfo(status, r.Info, output)
 		case "table": // table output is after this switch block
 		default:
 			return fmt.Errorf("output option cannot be %s", output)
diff --git a/cmd/crictl/info.go b/cmd/crictl/info.go
index 7db4ea6784..7c2371f70d 100644
--- a/cmd/crictl/info.go
+++ b/cmd/crictl/info.go
@@ -57,5 +57,9 @@ func Info(cliContext *cli.Context, client pb.RuntimeServiceClient) error {
 		return err
 	}
 
-	return outputStatusInfo(r.Status, r.Info, cliContext.String("output"))
+	status, err := protobufObjectToJSON(r.Status)
+	if err != nil {
+		return err
+	}
+	return outputStatusInfo(status, r.Info, cliContext.String("output"))
 }
diff --git a/cmd/crictl/sandbox.go b/cmd/crictl/sandbox.go
index aa0d36285f..2f78140420 100644
--- a/cmd/crictl/sandbox.go
+++ b/cmd/crictl/sandbox.go
@@ -17,6 +17,7 @@ limitations under the License.
 package main
 
 import (
+	"encoding/json"
 	"fmt"
 	"log"
 	"os"
@@ -272,6 +273,22 @@ func RemovePodSandbox(client pb.RuntimeServiceClient, ID string) error {
 	return nil
 }
 
+// marshalPodSandboxStatus converts pod sandbox status into string and converts
+// the timestamps into readable format.
+func marshalPodSandboxStatus(ps *pb.PodSandboxStatus) (string, error) {
+	statusStr, err := protobufObjectToJSON(ps)
+	if err != nil {
+		return "", err
+	}
+	jsonMap := make(map[string]interface{})
+	err = json.Unmarshal([]byte(statusStr), &jsonMap)
+	if err != nil {
+		return "", err
+	}
+	jsonMap["createdAt"] = time.Unix(0, ps.CreatedAt).Format(time.RFC3339Nano)
+	return marshalMapInOrder(jsonMap, *ps)
+}
+
 // PodSandboxStatus sends a PodSandboxStatusRequest to the server, and parses
 // the returned PodSandboxStatusResponse.
 func PodSandboxStatus(client pb.RuntimeServiceClient, ID, output string, quiet bool) error {
@@ -294,9 +311,13 @@ func PodSandboxStatus(client pb.RuntimeServiceClient, ID, output string, quiet b
 		return err
 	}
 
+	status, err := marshalPodSandboxStatus(r.Status)
+	if err != nil {
+		return err
+	}
 	switch output {
 	case "json", "yaml":
-		return outputStatusInfo(r.Status, r.Info, output)
+		return outputStatusInfo(status, r.Info, output)
 	case "table": // table output is after this switch block
 	default:
 		return fmt.Errorf("output option cannot be %s", output)
diff --git a/cmd/crictl/util.go b/cmd/crictl/util.go
index 6150f03dc0..69e40c8fb6 100644
--- a/cmd/crictl/util.go
+++ b/cmd/crictl/util.go
@@ -21,6 +21,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"os"
+	"reflect"
 	"sort"
 	"strings"
 
@@ -207,14 +208,17 @@ func outputProtobufObjAsYAML(obj proto.Message) error {
 	return nil
 }
 
-func outputStatusInfo(status proto.Message, info map[string]string, format string) error {
-	statusByte, err := protobufObjectToJSON(status)
-	if err != nil {
-		return err
+func outputStatusInfo(status string, info map[string]string, format string) error {
+	// Sort all keys
+	var keys []string
+	for k := range info {
+		keys = append(keys, k)
 	}
-	jsonInfo := "{" + "\"status\":" + string(statusByte) + ","
-	for k, v := range info {
-		jsonInfo += "\"" + k + "\"" + ":" + v + ","
+	sort.Strings(keys)
+
+	jsonInfo := "{" + "\"status\":" + status + ","
+	for _, k := range keys {
+		jsonInfo += "\"" + k + "\"" + ":" + info[k] + ","
 	}
 	jsonInfo = jsonInfo[:len(jsonInfo)-1]
 	jsonInfo += "}"
@@ -249,3 +253,40 @@ func parseLabelStringSlice(ss []string) (map[string]string, error) {
 	}
 	return labels, nil
 }
+
+// marshalMapInOrder marshalls a map into json in the order of the original
+// data structure.
+func marshalMapInOrder(m map[string]interface{}, t interface{}) (string, error) {
+	s := "{"
+	v := reflect.ValueOf(t)
+	for i := 0; i < v.Type().NumField(); i++ {
+		field := jsonFieldFromTag(v.Type().Field(i).Tag)
+		if field == "" {
+			continue
+		}
+		value, err := json.Marshal(m[field])
+		if err != nil {
+			return "", err
+		}
+		s += fmt.Sprintf("%q:%s,", field, value)
+	}
+	s = s[:len(s)-1]
+	s += "}"
+	var buf bytes.Buffer
+	if err := json.Indent(&buf, []byte(s), "", "  "); err != nil {
+		return "", err
+	}
+	return buf.String(), nil
+}
+
+// jsonFieldFromTag gets json field name from field tag.
+func jsonFieldFromTag(tag reflect.StructTag) string {
+	field := strings.Split(tag.Get("json"), ",")[0]
+	for _, f := range strings.Split(tag.Get("protobuf"), ",") {
+		if !strings.HasPrefix(f, "json=") {
+			continue
+		}
+		field = strings.TrimPrefix(f, "json=")
+	}
+	return field
+}