...

Source file src/github.com/aws/smithy-go/time/time.go

Documentation: github.com/aws/smithy-go/time

     1  package time
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math/big"
     7  	"strings"
     8  	"time"
     9  )
    10  
    11  const (
    12  	// dateTimeFormat is a IMF-fixdate formatted RFC3339 section 5.6
    13  	dateTimeFormatInput    = "2006-01-02T15:04:05.999999999Z"
    14  	dateTimeFormatInputNoZ = "2006-01-02T15:04:05.999999999"
    15  	dateTimeFormatOutput   = "2006-01-02T15:04:05.999Z"
    16  
    17  	// httpDateFormat is a date time defined by RFC 7231#section-7.1.1.1
    18  	// IMF-fixdate with no UTC offset.
    19  	httpDateFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
    20  	// Additional formats needed for compatibility.
    21  	httpDateFormatSingleDigitDay             = "Mon, _2 Jan 2006 15:04:05 GMT"
    22  	httpDateFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT"
    23  )
    24  
    25  var millisecondFloat = big.NewFloat(1e3)
    26  
    27  // FormatDateTime formats value as a date-time, (RFC3339 section 5.6)
    28  //
    29  // Example: 1985-04-12T23:20:50.52Z
    30  func FormatDateTime(value time.Time) string {
    31  	return value.UTC().Format(dateTimeFormatOutput)
    32  }
    33  
    34  // ParseDateTime parses a string as a date-time, (RFC3339 section 5.6)
    35  //
    36  // Example: 1985-04-12T23:20:50.52Z
    37  func ParseDateTime(value string) (time.Time, error) {
    38  	return tryParse(value,
    39  		dateTimeFormatInput,
    40  		dateTimeFormatInputNoZ,
    41  		time.RFC3339Nano,
    42  		time.RFC3339,
    43  	)
    44  }
    45  
    46  // FormatHTTPDate formats value as a http-date, (RFC 7231#section-7.1.1.1 IMF-fixdate)
    47  //
    48  // Example: Tue, 29 Apr 2014 18:30:38 GMT
    49  func FormatHTTPDate(value time.Time) string {
    50  	return value.UTC().Format(httpDateFormat)
    51  }
    52  
    53  // ParseHTTPDate parses a string as a http-date, (RFC 7231#section-7.1.1.1 IMF-fixdate)
    54  //
    55  // Example: Tue, 29 Apr 2014 18:30:38 GMT
    56  func ParseHTTPDate(value string) (time.Time, error) {
    57  	return tryParse(value,
    58  		httpDateFormat,
    59  		httpDateFormatSingleDigitDay,
    60  		httpDateFormatSingleDigitDayTwoDigitYear,
    61  		time.RFC850,
    62  		time.ANSIC,
    63  	)
    64  }
    65  
    66  // FormatEpochSeconds returns value as a Unix time in seconds with with decimal precision
    67  //
    68  // Example: 1515531081.123
    69  func FormatEpochSeconds(value time.Time) float64 {
    70  	ms := value.UnixNano() / int64(time.Millisecond)
    71  	return float64(ms) / 1e3
    72  }
    73  
    74  // ParseEpochSeconds returns value as a Unix time in seconds with with decimal precision
    75  //
    76  // Example: 1515531081.123
    77  func ParseEpochSeconds(value float64) time.Time {
    78  	f := big.NewFloat(value)
    79  	f = f.Mul(f, millisecondFloat)
    80  	i, _ := f.Int64()
    81  	// Offset to `UTC` because time.Unix returns the time value based on system
    82  	// local setting.
    83  	return time.Unix(0, i*1e6).UTC()
    84  }
    85  
    86  func tryParse(v string, formats ...string) (time.Time, error) {
    87  	var errs parseErrors
    88  	for _, f := range formats {
    89  		t, err := time.Parse(f, v)
    90  		if err != nil {
    91  			errs = append(errs, parseError{
    92  				Format: f,
    93  				Err:    err,
    94  			})
    95  			continue
    96  		}
    97  		return t, nil
    98  	}
    99  
   100  	return time.Time{}, fmt.Errorf("unable to parse time string, %w", errs)
   101  }
   102  
   103  type parseErrors []parseError
   104  
   105  func (es parseErrors) Error() string {
   106  	var s strings.Builder
   107  	for _, e := range es {
   108  		fmt.Fprintf(&s, "\n * %q: %v", e.Format, e.Err)
   109  	}
   110  
   111  	return "parse errors:" + s.String()
   112  }
   113  
   114  type parseError struct {
   115  	Format string
   116  	Err    error
   117  }
   118  
   119  // SleepWithContext will wait for the timer duration to expire, or until the context
   120  // is canceled. Whichever happens first. If the context is canceled the
   121  // Context's error will be returned.
   122  func SleepWithContext(ctx context.Context, dur time.Duration) error {
   123  	t := time.NewTimer(dur)
   124  	defer t.Stop()
   125  
   126  	select {
   127  	case <-t.C:
   128  		break
   129  	case <-ctx.Done():
   130  		return ctx.Err()
   131  	}
   132  
   133  	return nil
   134  }
   135  

View as plain text