github.com/anakojm/hugo-katex@v0.0.0-20231023141351-42d6f5de9c0b/common/htime/time.go (about)

     1  // Copyright 2021 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 htime
    15  
    16  import (
    17  	"log"
    18  	"strings"
    19  	"time"
    20  
    21  	"github.com/bep/clocks"
    22  	"github.com/spf13/cast"
    23  
    24  	"github.com/gohugoio/locales"
    25  )
    26  
    27  var (
    28  	longDayNames = []string{
    29  		"Sunday",
    30  		"Monday",
    31  		"Tuesday",
    32  		"Wednesday",
    33  		"Thursday",
    34  		"Friday",
    35  		"Saturday",
    36  	}
    37  
    38  	shortDayNames = []string{
    39  		"Sun",
    40  		"Mon",
    41  		"Tue",
    42  		"Wed",
    43  		"Thu",
    44  		"Fri",
    45  		"Sat",
    46  	}
    47  
    48  	shortMonthNames = []string{
    49  		"Jan",
    50  		"Feb",
    51  		"Mar",
    52  		"Apr",
    53  		"May",
    54  		"Jun",
    55  		"Jul",
    56  		"Aug",
    57  		"Sep",
    58  		"Oct",
    59  		"Nov",
    60  		"Dec",
    61  	}
    62  
    63  	longMonthNames = []string{
    64  		"January",
    65  		"February",
    66  		"March",
    67  		"April",
    68  		"May",
    69  		"June",
    70  		"July",
    71  		"August",
    72  		"September",
    73  		"October",
    74  		"November",
    75  		"December",
    76  	}
    77  
    78  	Clock = clocks.System()
    79  )
    80  
    81  func NewTimeFormatter(ltr locales.Translator) TimeFormatter {
    82  	if ltr == nil {
    83  		panic("must provide a locales.Translator")
    84  	}
    85  	return TimeFormatter{
    86  		ltr: ltr,
    87  	}
    88  }
    89  
    90  // TimeFormatter is locale aware.
    91  type TimeFormatter struct {
    92  	ltr locales.Translator
    93  }
    94  
    95  func (f TimeFormatter) Format(t time.Time, layout string) string {
    96  	if layout == "" {
    97  		return ""
    98  	}
    99  
   100  	if layout[0] == ':' {
   101  		// It may be one of Hugo's custom layouts.
   102  		switch strings.ToLower(layout[1:]) {
   103  		case "date_full":
   104  			return f.ltr.FmtDateFull(t)
   105  		case "date_long":
   106  			return f.ltr.FmtDateLong(t)
   107  		case "date_medium":
   108  			return f.ltr.FmtDateMedium(t)
   109  		case "date_short":
   110  			return f.ltr.FmtDateShort(t)
   111  		case "time_full":
   112  			return f.ltr.FmtTimeFull(t)
   113  		case "time_long":
   114  			return f.ltr.FmtTimeLong(t)
   115  		case "time_medium":
   116  			return f.ltr.FmtTimeMedium(t)
   117  		case "time_short":
   118  			return f.ltr.FmtTimeShort(t)
   119  		}
   120  	}
   121  
   122  	s := t.Format(layout)
   123  
   124  	monthIdx := t.Month() - 1 // Month() starts at 1.
   125  	dayIdx := t.Weekday()
   126  
   127  	if strings.Contains(layout, "January") {
   128  		s = strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthWide(t.Month()))
   129  	} else if strings.Contains(layout, "Jan") {
   130  		s = strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthAbbreviated(t.Month()))
   131  	}
   132  
   133  	if strings.Contains(layout, "Monday") {
   134  		s = strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdayWide(t.Weekday()))
   135  	} else if strings.Contains(layout, "Mon") {
   136  		s = strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdayAbbreviated(t.Weekday()))
   137  	}
   138  
   139  	return s
   140  }
   141  
   142  func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
   143  	switch vv := i.(type) {
   144  	case AsTimeProvider:
   145  		return vv.AsTime(location), nil
   146  	// issue #8895
   147  	// datetimes parsed by `go-toml` have empty zone name
   148  	// convert back them into string and use `cast`
   149  	// TODO(bep) add tests, make sure we really need this.
   150  	case time.Time:
   151  		i = vv.Format(time.RFC3339)
   152  	}
   153  	return cast.ToTimeInDefaultLocationE(i, location)
   154  }
   155  
   156  // Now returns time.Now() or time value based on the `clock` flag.
   157  // Use this function to fake time inside hugo.
   158  func Now() time.Time {
   159  	return Clock.Now()
   160  }
   161  
   162  func Since(t time.Time) time.Duration {
   163  	return Clock.Since(t)
   164  }
   165  
   166  // AsTimeProvider is implemented by go-toml's LocalDate and LocalDateTime.
   167  type AsTimeProvider interface {
   168  	AsTime(zone *time.Location) time.Time
   169  }
   170  
   171  // StopWatch is a simple helper to measure time during development.
   172  func StopWatch(name string) func() {
   173  	start := time.Now()
   174  	return func() {
   175  		log.Printf("StopWatch %q took %s", name, time.Since(start))
   176  	}
   177  }