github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/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  	"strings"
    18  	"time"
    19  
    20  	"github.com/spf13/cast"
    21  
    22  	toml "github.com/pelletier/go-toml/v2"
    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  
    79  func NewTimeFormatter(ltr locales.Translator) TimeFormatter {
    80  	if ltr == nil {
    81  		panic("must provide a locales.Translator")
    82  	}
    83  	return TimeFormatter{
    84  		ltr: ltr,
    85  	}
    86  }
    87  
    88  // TimeFormatter is locale aware.
    89  type TimeFormatter struct {
    90  	ltr locales.Translator
    91  }
    92  
    93  func (f TimeFormatter) Format(t time.Time, layout string) string {
    94  	if layout == "" {
    95  		return ""
    96  	}
    97  
    98  	if layout[0] == ':' {
    99  		// It may be one of Hugo's custom layouts.
   100  		switch strings.ToLower(layout[1:]) {
   101  		case "date_full":
   102  			return f.ltr.FmtDateFull(t)
   103  		case "date_long":
   104  			return f.ltr.FmtDateLong(t)
   105  		case "date_medium":
   106  			return f.ltr.FmtDateMedium(t)
   107  		case "date_short":
   108  			return f.ltr.FmtDateShort(t)
   109  		case "time_full":
   110  			return f.ltr.FmtTimeFull(t)
   111  		case "time_long":
   112  			return f.ltr.FmtTimeLong(t)
   113  		case "time_medium":
   114  			return f.ltr.FmtTimeMedium(t)
   115  		case "time_short":
   116  			return f.ltr.FmtTimeShort(t)
   117  		}
   118  	}
   119  
   120  	s := t.Format(layout)
   121  
   122  	monthIdx := t.Month() - 1 // Month() starts at 1.
   123  	dayIdx := t.Weekday()
   124  
   125  	s = strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthWide(t.Month()))
   126  	if !strings.Contains(s, f.ltr.MonthWide(t.Month())) {
   127  		s = strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthAbbreviated(t.Month()))
   128  	}
   129  	s = strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdayWide(t.Weekday()))
   130  	if !strings.Contains(s, f.ltr.WeekdayWide(t.Weekday())) {
   131  		s = strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdayAbbreviated(t.Weekday()))
   132  	}
   133  
   134  	return s
   135  }
   136  
   137  func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
   138  	switch vv := i.(type) {
   139  	case toml.LocalDate:
   140  		return vv.AsTime(location), nil
   141  	case toml.LocalDateTime:
   142  		return vv.AsTime(location), nil
   143  	// issue #8895
   144  	// datetimes parsed by `go-toml` have empty zone name
   145  	// convert back them into string and use `cast`
   146  	case time.Time:
   147  		i = vv.Format(time.RFC3339)
   148  	}
   149  	return cast.ToTimeInDefaultLocationE(i, location)
   150  }