func (t *Translator) formatDateTimeComponentDayOfWeekAbbreviated(dayOfWeek time.Weekday) string {
	switch dayOfWeek {
	case time.Sunday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Sun
	case time.Monday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Mon
	case time.Tuesday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Tue
	case time.Wednesday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Wed
	case time.Thursday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Thu
	case time.Friday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Fri
	case time.Saturday:
		return t.rules.DateTime.FormatNames.Days.Abbreviated.Sat
	}
	return ""
}
formatDateTimeComponentDayOfWeekAbbreviated renders an abbreviated text
day-of-week component.
package i18n
import (
	"fmt"
	"strings"
	"time"
)
const (
	DateFormatFull = iota
	DateFormatLong
	DateFormatMedium
	DateFormatShort
	TimeFormatFull
	TimeFormatLong
	TimeFormatMedium
	TimeFormatShort
	DateTimeFormatFull
	DateTimeFormatLong
	DateTimeFormatMedium
	DateTimeFormatShort
)
const (
	datetimeFormatUnitEra       = 'G'
	datetimeFormatUnitYear      = 'y'
	datetimeFormatUnitMonth     = 'M'
	datetimeFormatUnitDayOfWeek = 'E'
	datetimeFormatUnitDay       = 'd'
	datetimeFormatUnitHour12    = 'h'
	datetimeFormatUnitHour24    = 'H'
	datetimeFormatUnitMinute    = 'm'
	datetimeFormatUnitSecond    = 's'
	datetimeFormatUnitPeriod    = 'a'
	datetimeForamtUnitQuarter   = 'Q'
	datetimeFormatUnitTimeZone1 = 'z'
	datetimeFormatUnitTimeZone2 = 'v'
	datetimeFormatTimeSeparator = ':'
	datetimeFormatLiteral       = '\''
)
const (
	datetimeFormatLength1Plus       = 1
	datetimeFormatLength2Plus       = 2
	datetimeFormatLengthAbbreviated = 3
	datetimeFormatLengthWide        = 4
	datetimeFormatLengthNarrow      = 5
)
const (
	datetimePatternComponentUnit = iota
	datetimePatternComponentLiteral
)
var (
	datetimeFormatUnitCutset = []rune{
		datetimeFormatUnitEra,
		datetimeForamtUnitQuarter,
		datetimeFormatUnitTimeZone1,
		datetimeFormatUnitTimeZone2,
	}
)
type datetimePatternComponent struct {
	pattern       string
	componentType int
}
func (t *Translator) FormatDateTime(format int, datetime time.Time) (string, error) {
	pattern := ""
	switch format {
	case DateFormatFull:
		pattern = t.rules.DateTime.Formats.Date.Full
	case DateFormatLong:
		pattern = t.rules.DateTime.Formats.Date.Long
	case DateFormatMedium:
		pattern = t.rules.DateTime.Formats.Date.Medium
	case DateFormatShort:
		pattern = t.rules.DateTime.Formats.Date.Short
	case TimeFormatFull:
		pattern = t.rules.DateTime.Formats.Time.Full
	case TimeFormatLong:
		pattern = t.rules.DateTime.Formats.Time.Long
	case TimeFormatMedium:
		pattern = t.rules.DateTime.Formats.Time.Medium
	case TimeFormatShort:
		pattern = t.rules.DateTime.Formats.Time.Short
	case DateTimeFormatFull:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Full, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Full, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Full, datePattern, timePattern)
	case DateTimeFormatLong:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Long, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Long, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Long, datePattern, timePattern)
	case DateTimeFormatMedium:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Medium, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Medium, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Medium, datePattern, timePattern)
	case DateTimeFormatShort:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Short, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Short, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Short, datePattern, timePattern)
	default:
		return "", translatorError{message: "unknown datetime format" + pattern[0:1]}
	}
	parsed, err := t.parseDateTimeFormat(pattern)
	if err != nil {
		return "", err
	}
	return t.formatDateTime(datetime, parsed)
}
func (t *Translator) formatDateTime(datetime time.Time, pattern []*datetimePatternComponent) (string, error) {
	formatted := ""
	for _, component := range pattern {
		if component.componentType == datetimePatternComponentLiteral {
			formatted += component.pattern
		} else {
			f, err := t.formatDateTimeComponent(datetime, component.pattern)
			if err != nil {
				return "", err
			}
			formatted += f
		}
	}
	return strings.Trim(formatted, " ,"), nil
}
func (t *Translator) formatDateTimeComponent(datetime time.Time, pattern string) (string, error) {
	switch pattern[0:1] {
	case string(datetimeFormatUnitEra):
		return t.formatDateTimeComponentEra(datetime, len(pattern))
	case string(datetimeFormatUnitYear):
		return t.formatDateTimeComponentYear(datetime, len(pattern))
	case string(datetimeFormatUnitMonth):
		return t.formatDateTimeComponentMonth(datetime, len(pattern))
	case string(datetimeFormatUnitDayOfWeek):
		return t.formatDateTimeComponentDayOfWeek(datetime, len(pattern))
	case string(datetimeFormatUnitDay):
		return t.formatDateTimeComponentDay(datetime, len(pattern))
	case string(datetimeFormatUnitHour12):
		return t.formatDateTimeComponentHour12(datetime, len(pattern))
	case string(datetimeFormatUnitHour24):
		return t.formatDateTimeComponentHour24(datetime, len(pattern))
	case string(datetimeFormatUnitMinute):
		return t.formatDateTimeComponentMinute(datetime, len(pattern))
	case string(datetimeFormatUnitSecond):
		return t.formatDateTimeComponentSecond(datetime, len(pattern))
	case string(datetimeFormatUnitPeriod):
		return t.formatDateTimeComponentPeriod(datetime, len(pattern))
	case string(datetimeForamtUnitQuarter):
		return t.formatDateTimeComponentQuarter(datetime, len(pattern))
	case string(datetimeFormatUnitTimeZone1):
		fallthrough
	case string(datetimeFormatUnitTimeZone2):
		return t.formatDateTimeComponentTimeZone(datetime, len(pattern))
	}
	return "", translatorError{message: "unknown datetime format unit: " + pattern[0:1]}
}
func (t *Translator) formatDateTimeComponentEra(datetime time.Time, length int) (string, error) {
	return "", nil
}
func (t *Translator) formatDateTimeComponentYear(datetime time.Time, length int) (string, error) {
	year := datetime.Year()
	switch length {
	case datetimeFormatLength1Plus:
		return t.formatDateTimeComponentYearLengthWide(year), nil
	case datetimeFormatLength2Plus:
		return t.formatDateTimeComponentYearLength2Plus(year), nil
	case datetimeFormatLengthWide:
		return t.formatDateTimeComponentYearLengthWide(year), nil
	}
	return "", translatorError{message: fmt.Sprintf("unsupported year length: %d", length)}
}
func (t *Translator) formatDateTimeComponentYearLength2Plus(year int) string {
	yearShort := year % 100
	if yearShort < 10 {
		return fmt.Sprintf("0%d", yearShort)
	}
	return fmt.Sprintf("%d", yearShort)
}
func (t *Translator) formatDateTimeComponentYearLengthWide(year int) string {
	return fmt.Sprintf("%d", year)
}
func (t *Translator) formatDateTimeComponentMonth(datetime time.Time, length int) (string, error) {
	month := int(datetime.Month())
	switch length {
	case datetimeFormatLength1Plus:
		return t.formatDateTimeComponentMonth1Plus(month), nil
	case datetimeFormatLength2Plus:
		return t.formatDateTimeComponentMonth2Plus(month), nil
	case datetimeFormatLengthAbbreviated:
		return t.formatDateTimeComponentMonthAbbreviated(month), nil
	case datetimeFormatLengthWide:
		return t.formatDateTimeComponentMonthWide(month), nil
	case datetimeFormatLengthNarrow:
		return t.formatDateTimeComponentMonthNarrow(month), nil
	}
	return "", translatorError{message: fmt.Sprintf("unsupported month length: %d", length)}
}
func (t *Translator) formatDateTimeComponentMonth1Plus(month int) string {
	return fmt.Sprintf("%d", month)
}
func (t *Translator) formatDateTimeComponentMonth2Plus(month int) string {
	if month < 10 {
		return fmt.Sprintf("0%d", month)
	}
	return fmt.Sprintf("%d", month)
}
func (t *Translator) formatDateTimeComponentMonthAbbreviated(month int) string {
	switch month {
	case 1:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month1
	case 2:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month2
	case 3:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month3
	case 4:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month4
	case 5:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month5
	case 6:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month6
	case 7:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month7
	case 8:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month8
	case 9:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month9
	case 10:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month10
	case 11:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month11
	case 12:
		return t.rules.DateTime.FormatNames.Months.Abbreviated.Month12
	}
	return ""
}
func (t *Translator) formatDateTimeComponentMonthWide(month int) string {
	switch month {
	case 1:
		return t.rules.DateTime.FormatNames.Months.Wide.Month1
	case 2:
		return t.rules.DateTime.FormatNames.Months.Wide.Month2
	case 3:
		return t.rules.DateTime.FormatNames.Months.Wide.Month3
	case 4:
		return t.rules.DateTime.FormatNames.Months.Wide.Month4
	case 5:
		return t.rules.DateTime.FormatNames.Months.Wide.Month5
	case 6:
		return t.rules.DateTime.FormatNames.Months.Wide.Month6
	case 7:
		return t.rules.DateTime.FormatNames.Months.Wide.Month7
	case 8:
		return t.rules.DateTime.FormatNames.Months.Wide.Month8
	case 9:
		return t.rules.DateTime.FormatNames.Months.Wide.Month9
	case 10:
		return t.rules.DateTime.FormatNames.Months.Wide.Month10
	case 11:
		return t.rules.DateTime.FormatNames.Months.Wide.Month11
	case 12:
		return t.rules.DateTime.FormatNames.Months.Wide.Month12
	}
	return ""
}
func (t *Translator) formatDateTimeComponentMonthNarrow(month int) string {
	switch month {
	case 1:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month1
	case 2:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month2
	case 3:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month3
	case 4:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month4
	case 5:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month5
	case 6:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month6
	case 7:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month7
	case 8:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month8
	case 9:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month9
	case 10:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month10
	case 11:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month11
	case 12:
		return t.rules.DateTime.FormatNames.Months.Narrow.Month12
	}
	return ""
}
func (t *Translator) formatDateTimeComponentDayOfWeek(datetime time.Time, length int) (string, error) {
	switch length {
	case datetimeFormatLength1Plus:
		return t.formatDateTimeComponentDayOfWeekWide(datetime.Weekday()), nil
	case datetimeFormatLength2Plus:
		return t.formatDateTimeComponentDayOfWeekShort(datetime.Weekday()), nil
	case datetimeFormatLengthAbbreviated:
		return t.formatDateTimeComponentDayOfWeekAbbreviated(datetime.Weekday()), nil
	case datetimeFormatLengthWide:
		return t.formatDateTimeComponentDayOfWeekWide(datetime.Weekday()), nil
	case datetimeFormatLengthNarrow:
		return t.formatDateTimeComponentDayOfWeekNarrow(datetime.Weekday()), nil
	}
	return "", translatorError{message: fmt.Sprintf("unsupported year day-of-week: %d", length)}
}