...

Source file src/github.com/golang/protobuf/ptypes/duration.go

Documentation: github.com/golang/protobuf/ptypes

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ptypes
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"time"
    11  
    12  	durationpb "github.com/golang/protobuf/ptypes/duration"
    13  )
    14  
    15  // Range of google.protobuf.Duration as specified in duration.proto.
    16  // This is about 10,000 years in seconds.
    17  const (
    18  	maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
    19  	minSeconds = -maxSeconds
    20  )
    21  
    22  // Duration converts a durationpb.Duration to a time.Duration.
    23  // Duration returns an error if dur is invalid or overflows a time.Duration.
    24  //
    25  // Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead.
    26  func Duration(dur *durationpb.Duration) (time.Duration, error) {
    27  	if err := validateDuration(dur); err != nil {
    28  		return 0, err
    29  	}
    30  	d := time.Duration(dur.Seconds) * time.Second
    31  	if int64(d/time.Second) != dur.Seconds {
    32  		return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur)
    33  	}
    34  	if dur.Nanos != 0 {
    35  		d += time.Duration(dur.Nanos) * time.Nanosecond
    36  		if (d < 0) != (dur.Nanos < 0) {
    37  			return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur)
    38  		}
    39  	}
    40  	return d, nil
    41  }
    42  
    43  // DurationProto converts a time.Duration to a durationpb.Duration.
    44  //
    45  // Deprecated: Call the durationpb.New function instead.
    46  func DurationProto(d time.Duration) *durationpb.Duration {
    47  	nanos := d.Nanoseconds()
    48  	secs := nanos / 1e9
    49  	nanos -= secs * 1e9
    50  	return &durationpb.Duration{
    51  		Seconds: int64(secs),
    52  		Nanos:   int32(nanos),
    53  	}
    54  }
    55  
    56  // validateDuration determines whether the durationpb.Duration is valid
    57  // according to the definition in google/protobuf/duration.proto.
    58  // A valid durpb.Duration may still be too large to fit into a time.Duration
    59  // Note that the range of durationpb.Duration is about 10,000 years,
    60  // while the range of time.Duration is about 290 years.
    61  func validateDuration(dur *durationpb.Duration) error {
    62  	if dur == nil {
    63  		return errors.New("duration: nil Duration")
    64  	}
    65  	if dur.Seconds < minSeconds || dur.Seconds > maxSeconds {
    66  		return fmt.Errorf("duration: %v: seconds out of range", dur)
    67  	}
    68  	if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 {
    69  		return fmt.Errorf("duration: %v: nanos out of range", dur)
    70  	}
    71  	// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
    72  	if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) {
    73  		return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur)
    74  	}
    75  	return nil
    76  }
    77  

View as plain text