github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/tpl/time/time.go (about)

     1  // Copyright 2017 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  // Package time provides template functions for measuring and displaying time.
    15  package time
    16  
    17  import (
    18  	"fmt"
    19  	"time"
    20  	_time "time"
    21  
    22  	"github.com/gohugoio/hugo/common/htime"
    23  
    24  	"github.com/gohugoio/locales"
    25  
    26  	"github.com/spf13/cast"
    27  )
    28  
    29  // New returns a new instance of the time-namespaced template functions.
    30  func New(translator locales.Translator, location *time.Location) *Namespace {
    31  	return &Namespace{
    32  		timeFormatter: htime.NewTimeFormatter(translator),
    33  		location:      location,
    34  	}
    35  }
    36  
    37  // Namespace provides template functions for the "time" namespace.
    38  type Namespace struct {
    39  	timeFormatter htime.TimeFormatter
    40  	location      *time.Location
    41  }
    42  
    43  // AsTime converts the textual representation of the datetime string into
    44  // a time.Time interface.
    45  func (ns *Namespace) AsTime(v interface{}, args ...interface{}) (interface{}, error) {
    46  	loc := ns.location
    47  	if len(args) > 0 {
    48  		locStr, err := cast.ToStringE(args[0])
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  		loc, err = _time.LoadLocation(locStr)
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  	}
    57  
    58  	return htime.ToTimeInDefaultLocationE(v, loc)
    59  
    60  }
    61  
    62  // Format converts the textual representation of the datetime string into
    63  // the other form or returns it of the time.Time value. These are formatted
    64  // with the layout string
    65  func (ns *Namespace) Format(layout string, v interface{}) (string, error) {
    66  	t, err := htime.ToTimeInDefaultLocationE(v, ns.location)
    67  	if err != nil {
    68  		return "", err
    69  	}
    70  
    71  	return ns.timeFormatter.Format(t, layout), nil
    72  }
    73  
    74  // Now returns the current local time.
    75  func (ns *Namespace) Now() _time.Time {
    76  	return _time.Now()
    77  }
    78  
    79  // ParseDuration parses a duration string.
    80  // A duration string is a possibly signed sequence of
    81  // decimal numbers, each with optional fraction and a unit suffix,
    82  // such as "300ms", "-1.5h" or "2h45m".
    83  // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
    84  // See https://golang.org/pkg/time/#ParseDuration
    85  func (ns *Namespace) ParseDuration(in interface{}) (_time.Duration, error) {
    86  	s, err := cast.ToStringE(in)
    87  	if err != nil {
    88  		return 0, err
    89  	}
    90  
    91  	return _time.ParseDuration(s)
    92  }
    93  
    94  var durationUnits = map[string]_time.Duration{
    95  	"nanosecond":  _time.Nanosecond,
    96  	"ns":          _time.Nanosecond,
    97  	"microsecond": _time.Microsecond,
    98  	"us":          _time.Microsecond,
    99  	"µs":          _time.Microsecond,
   100  	"millisecond": _time.Millisecond,
   101  	"ms":          _time.Millisecond,
   102  	"second":      _time.Second,
   103  	"s":           _time.Second,
   104  	"minute":      _time.Minute,
   105  	"m":           _time.Minute,
   106  	"hour":        _time.Hour,
   107  	"h":           _time.Hour,
   108  }
   109  
   110  // Duration converts the given number to a time.Duration.
   111  // Unit is one of nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m or hour/h.
   112  func (ns *Namespace) Duration(unit interface{}, number interface{}) (_time.Duration, error) {
   113  	unitStr, err := cast.ToStringE(unit)
   114  	if err != nil {
   115  		return 0, err
   116  	}
   117  	unitDuration, found := durationUnits[unitStr]
   118  	if !found {
   119  		return 0, fmt.Errorf("%q is not a valid duration unit", unit)
   120  	}
   121  	n, err := cast.ToInt64E(number)
   122  	if err != nil {
   123  		return 0, err
   124  	}
   125  	return _time.Duration(n) * unitDuration, nil
   126  }