...

Source file src/github.com/gogo/protobuf/types/timestamp.go

Documentation: github.com/gogo/protobuf/types

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2016 The Go Authors.  All rights reserved.
     4  // https://github.com/golang/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //     * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  package types
    33  
    34  // This file implements operations on google.protobuf.Timestamp.
    35  
    36  import (
    37  	"errors"
    38  	"fmt"
    39  	"time"
    40  )
    41  
    42  const (
    43  	// Seconds field of the earliest valid Timestamp.
    44  	// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
    45  	minValidSeconds = -62135596800
    46  	// Seconds field just after the latest valid Timestamp.
    47  	// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
    48  	maxValidSeconds = 253402300800
    49  )
    50  
    51  // validateTimestamp determines whether a Timestamp is valid.
    52  // A valid timestamp represents a time in the range
    53  // [0001-01-01, 10000-01-01) and has a Nanos field
    54  // in the range [0, 1e9).
    55  //
    56  // If the Timestamp is valid, validateTimestamp returns nil.
    57  // Otherwise, it returns an error that describes
    58  // the problem.
    59  //
    60  // Every valid Timestamp can be represented by a time.Time, but the converse is not true.
    61  func validateTimestamp(ts *Timestamp) error {
    62  	if ts == nil {
    63  		return errors.New("timestamp: nil Timestamp")
    64  	}
    65  	if ts.Seconds < minValidSeconds {
    66  		return fmt.Errorf("timestamp: %#v before 0001-01-01", ts)
    67  	}
    68  	if ts.Seconds >= maxValidSeconds {
    69  		return fmt.Errorf("timestamp: %#v after 10000-01-01", ts)
    70  	}
    71  	if ts.Nanos < 0 || ts.Nanos >= 1e9 {
    72  		return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts)
    73  	}
    74  	return nil
    75  }
    76  
    77  // TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.
    78  // It returns an error if the argument is invalid.
    79  //
    80  // Unlike most Go functions, if Timestamp returns an error, the first return value
    81  // is not the zero time.Time. Instead, it is the value obtained from the
    82  // time.Unix function when passed the contents of the Timestamp, in the UTC
    83  // locale. This may or may not be a meaningful time; many invalid Timestamps
    84  // do map to valid time.Times.
    85  //
    86  // A nil Timestamp returns an error. The first return value in that case is
    87  // undefined.
    88  func TimestampFromProto(ts *Timestamp) (time.Time, error) {
    89  	// Don't return the zero value on error, because corresponds to a valid
    90  	// timestamp. Instead return whatever time.Unix gives us.
    91  	var t time.Time
    92  	if ts == nil {
    93  		t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
    94  	} else {
    95  		t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
    96  	}
    97  	return t, validateTimestamp(ts)
    98  }
    99  
   100  // TimestampNow returns a google.protobuf.Timestamp for the current time.
   101  func TimestampNow() *Timestamp {
   102  	ts, err := TimestampProto(time.Now())
   103  	if err != nil {
   104  		panic("ptypes: time.Now() out of Timestamp range")
   105  	}
   106  	return ts
   107  }
   108  
   109  // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
   110  // It returns an error if the resulting Timestamp is invalid.
   111  func TimestampProto(t time.Time) (*Timestamp, error) {
   112  	ts := &Timestamp{
   113  		Seconds: t.Unix(),
   114  		Nanos:   int32(t.Nanosecond()),
   115  	}
   116  	if err := validateTimestamp(ts); err != nil {
   117  		return nil, err
   118  	}
   119  	return ts, nil
   120  }
   121  
   122  // TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
   123  // Timestamps, it returns an error message in parentheses.
   124  func TimestampString(ts *Timestamp) string {
   125  	t, err := TimestampFromProto(ts)
   126  	if err != nil {
   127  		return fmt.Sprintf("(%v)", err)
   128  	}
   129  	return t.Format(time.RFC3339Nano)
   130  }
   131  

View as plain text