time.go (3622B)
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/spf13/cast" 25 ) 26 27 // New returns a new instance of the time-namespaced template functions. 28 func New(timeFormatter htime.TimeFormatter, location *time.Location) *Namespace { 29 return &Namespace{ 30 timeFormatter: timeFormatter, 31 location: location, 32 } 33 } 34 35 // Namespace provides template functions for the "time" namespace. 36 type Namespace struct { 37 timeFormatter htime.TimeFormatter 38 location *time.Location 39 } 40 41 // AsTime converts the textual representation of the datetime string into 42 // a time.Time interface. 43 func (ns *Namespace) AsTime(v any, args ...any) (any, error) { 44 loc := ns.location 45 if len(args) > 0 { 46 locStr, err := cast.ToStringE(args[0]) 47 if err != nil { 48 return nil, err 49 } 50 loc, err = _time.LoadLocation(locStr) 51 if err != nil { 52 return nil, err 53 } 54 } 55 56 return htime.ToTimeInDefaultLocationE(v, loc) 57 58 } 59 60 // Format converts the textual representation of the datetime string in v into 61 // time.Time if needed and formats it with the given layout. 62 func (ns *Namespace) Format(layout string, v any) (string, error) { 63 t, err := htime.ToTimeInDefaultLocationE(v, ns.location) 64 if err != nil { 65 return "", err 66 } 67 68 return ns.timeFormatter.Format(t, layout), nil 69 } 70 71 // Now returns the current local time or `clock` time 72 func (ns *Namespace) Now() _time.Time { 73 return htime.Now() 74 } 75 76 // ParseDuration parses the duration string s. 77 // A duration string is a possibly signed sequence of 78 // decimal numbers, each with optional fraction and a unit suffix, 79 // such as "300ms", "-1.5h" or "2h45m". 80 // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". 81 // See https://golang.org/pkg/time/#ParseDuration 82 func (ns *Namespace) ParseDuration(s any) (_time.Duration, error) { 83 ss, err := cast.ToStringE(s) 84 if err != nil { 85 return 0, err 86 } 87 88 return _time.ParseDuration(ss) 89 } 90 91 var durationUnits = map[string]_time.Duration{ 92 "nanosecond": _time.Nanosecond, 93 "ns": _time.Nanosecond, 94 "microsecond": _time.Microsecond, 95 "us": _time.Microsecond, 96 "µs": _time.Microsecond, 97 "millisecond": _time.Millisecond, 98 "ms": _time.Millisecond, 99 "second": _time.Second, 100 "s": _time.Second, 101 "minute": _time.Minute, 102 "m": _time.Minute, 103 "hour": _time.Hour, 104 "h": _time.Hour, 105 } 106 107 // Duration converts the given number to a time.Duration. 108 // Unit is one of nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m or hour/h. 109 func (ns *Namespace) Duration(unit any, number any) (_time.Duration, error) { 110 unitStr, err := cast.ToStringE(unit) 111 if err != nil { 112 return 0, err 113 } 114 unitDuration, found := durationUnits[unitStr] 115 if !found { 116 return 0, fmt.Errorf("%q is not a valid duration unit", unit) 117 } 118 n, err := cast.ToInt64E(number) 119 if err != nil { 120 return 0, err 121 } 122 return _time.Duration(n) * unitDuration, nil 123 }