github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/ptypes/timestamp.go (about)

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2016 The Go Authors.  All rights reserved.
     4  // https://yougam/libraries/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 ptypes
    33  
    34  // This file implements operations on google.protobuf.Timestamp.
    35  
    36  import (
    37  	"errors"
    38  	"fmt"
    39  	"time"
    40  
    41  	tspb "github.com/insionng/yougam/libraries/golang/protobuf/ptypes/timestamp"
    42  )
    43  
    44  const (
    45  	// Seconds field of the earliest valid Timestamp.
    46  	// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
    47  	minValidSeconds = -62135596800
    48  	// Seconds field just after the latest valid Timestamp.
    49  	// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
    50  	maxValidSeconds = 253402300800
    51  )
    52  
    53  // validateTimestamp determines whether a Timestamp is valid.
    54  // A valid timestamp represents a time in the range
    55  // [0001-01-01, 10000-01-01) and has a Nanos field
    56  // in the range [0, 1e9).
    57  //
    58  // If the Timestamp is valid, validateTimestamp returns nil.
    59  // Otherwise, it returns an error that describes
    60  // the problem.
    61  //
    62  // Every valid Timestamp can be represented by a time.Time, but the converse is not true.
    63  func validateTimestamp(ts *tspb.Timestamp) error {
    64  	if ts == nil {
    65  		return errors.New("timestamp: nil Timestamp")
    66  	}
    67  	if ts.Seconds < minValidSeconds {
    68  		return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
    69  	}
    70  	if ts.Seconds >= maxValidSeconds {
    71  		return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
    72  	}
    73  	if ts.Nanos < 0 || ts.Nanos >= 1e9 {
    74  		return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
    75  	}
    76  	return nil
    77  }
    78  
    79  // Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
    80  // It returns an error if the argument is invalid.
    81  //
    82  // Unlike most Go functions, if Timestamp returns an error, the first return value
    83  // is not the zero time.Time. Instead, it is the value obtained from the
    84  // time.Unix function when passed the contents of the Timestamp, in the UTC
    85  // locale. This may or may not be a meaningful time; many invalid Timestamps
    86  // do map to valid time.Times.
    87  //
    88  // A nil Timestamp returns an error. The first return value in that case is
    89  // undefined.
    90  func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
    91  	// Don't return the zero value on error, because corresponds to a valid
    92  	// timestamp. Instead return whatever time.Unix gives us.
    93  	var t time.Time
    94  	if ts == nil {
    95  		t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
    96  	} else {
    97  		t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
    98  	}
    99  	return t, validateTimestamp(ts)
   100  }
   101  
   102  // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
   103  // It returns an error if the resulting Timestamp is invalid.
   104  func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
   105  	seconds := t.Unix()
   106  	nanos := int32(t.Sub(time.Unix(seconds, 0)))
   107  	ts := &tspb.Timestamp{
   108  		Seconds: seconds,
   109  		Nanos:   nanos,
   110  	}
   111  	if err := validateTimestamp(ts); err != nil {
   112  		return nil, err
   113  	}
   114  	return ts, nil
   115  }
   116  
   117  // TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
   118  // Timestamps, it returns an error message in parentheses.
   119  func TimestampString(ts *tspb.Timestamp) string {
   120  	t, err := Timestamp(ts)
   121  	if err != nil {
   122  		return fmt.Sprintf("(%v)", err)
   123  	}
   124  	return t.Format(time.RFC3339Nano)
   125  }