// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ptypes

import (
	
	
	

	timestamppb 
)

// Range of google.protobuf.Duration as specified in timestamp.proto.
const (
	// Seconds field of the earliest valid Timestamp.
	// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
	minValidSeconds = -62135596800
	// Seconds field just after the latest valid Timestamp.
	// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
	maxValidSeconds = 253402300800
)

// Timestamp converts a timestamppb.Timestamp to a time.Time.
// It returns an error if the argument is invalid.
//
// Unlike most Go functions, if Timestamp returns an error, the first return
// value is not the zero time.Time. Instead, it is the value obtained from the
// time.Unix function when passed the contents of the Timestamp, in the UTC
// locale. This may or may not be a meaningful time; many invalid Timestamps
// do map to valid time.Times.
//
// A nil Timestamp returns an error. The first return value in that case is
// undefined.
//
// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead.
func ( *timestamppb.Timestamp) (time.Time, error) {
	// Don't return the zero value on error, because corresponds to a valid
	// timestamp. Instead return whatever time.Unix gives us.
	var  time.Time
	if  == nil {
		 = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
	} else {
		 = time.Unix(.Seconds, int64(.Nanos)).UTC()
	}
	return , validateTimestamp()
}

// TimestampNow returns a google.protobuf.Timestamp for the current time.
//
// Deprecated: Call the timestamppb.Now function instead.
func () *timestamppb.Timestamp {
	,  := TimestampProto(time.Now())
	if  != nil {
		panic("ptypes: time.Now() out of Timestamp range")
	}
	return 
}

// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
// It returns an error if the resulting Timestamp is invalid.
//
// Deprecated: Call the timestamppb.New function instead.
func ( time.Time) (*timestamppb.Timestamp, error) {
	 := &timestamppb.Timestamp{
		Seconds: .Unix(),
		Nanos:   int32(.Nanosecond()),
	}
	if  := validateTimestamp();  != nil {
		return nil, 
	}
	return , nil
}

// TimestampString returns the RFC 3339 string for valid Timestamps.
// For invalid Timestamps, it returns an error message in parentheses.
//
// Deprecated: Call the ts.AsTime method instead,
// followed by a call to the Format method on the time.Time value.
func ( *timestamppb.Timestamp) string {
	,  := Timestamp()
	if  != nil {
		return fmt.Sprintf("(%v)", )
	}
	return .Format(time.RFC3339Nano)
}

// validateTimestamp determines whether a Timestamp is valid.
// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01)
// and has a Nanos field in the range [0, 1e9).
//
// If the Timestamp is valid, validateTimestamp returns nil.
// Otherwise, it returns an error that describes the problem.
//
// Every valid Timestamp can be represented by a time.Time,
// but the converse is not true.
func ( *timestamppb.Timestamp) error {
	if  == nil {
		return errors.New("timestamp: nil Timestamp")
	}
	if .Seconds < minValidSeconds {
		return fmt.Errorf("timestamp: %v before 0001-01-01", )
	}
	if .Seconds >= maxValidSeconds {
		return fmt.Errorf("timestamp: %v after 10000-01-01", )
	}
	if .Nanos < 0 || .Nanos >= 1e9 {
		return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", )
	}
	return nil
}