Documentation
¶
Overview ¶
Package xtime provides functionality for working with time.
Duration Formatting (FormatDuration) ¶
The FormatDuration function converts a time.Duration into a string composed of multiple time units (e.g., "1h 5m 30s", "2 days, 3 hours"). This offers more detailed breakdowns than the standard time.Duration.String() method, which typically scales to the largest appropriate single unit (e.g., "1m30.5s").
duration := 2*xtime.Day + 3*time.Hour + 15*time.Minute + 30*time.Second + 500*time.Millisecond
Default formatting (short style, max unit Day, min unit Second, no rounding):
fmt.Println(xtime.FormatDuration(duration)) // Output: 2d 3h 15m 30s
## Custom formatting examples
Long style, max 2 components, rounding enabled:
fmt.Println(xtime.FormatDuration(duration, xtime.WithStyle(xtime.FormatStyleLong), xtime.WithMaxComponents(2), xtime.WithRounding(), )) // Output: 2 days, 3 hours
Compact style:
fmt.Println(xtime.FormatDuration(duration, xtime.WithStyle(xtime.FormatStyleCompact), )) // Output: 2d3h
Short style, rounding enabled, only seconds and smaller displayed:
fmt.Println(xtime.FormatDuration(time.Second+600*time.Millisecond, xtime.WithRounding(), xtime.WithMinUnit(time.Millisecond), )) // Output: 2s (Original: 1s 600ms, rounded up)
Formatting Options (Functional Options Pattern):
- WithMaxUnit(unit time.Duration): Sets the largest unit for decomposition (default: Day).
- WithMinUnit(unit time.Duration): Sets the smallest unit to display (default: Second). Remainder is truncated or rounded.
- WithRounding(): Enables rounding of the MinUnit based on the remainder. The duration is adjusted by adding half of MinUnit before decomposition.
- WithoutRounding(): Disables rounding (default). Remainder is truncated.
- WithMaxComponents(n int): Limits output to at most 'n' components (default: 0 = unlimited).
- WithStyle(style FormatStyle): Sets output style (short, long, long-and).
- WithSeparator(sep string): Custom separator between components (default depends on style).
- WithConjunction(conj string): Custom conjunction (" and " by default) used before the last component in "long-and" style.
Duration Parsing (ParseDuration) ¶
The ParseDuration function converts a human-readable string representation into a time.Duration value. It accepts various formats, including combined units and common abbreviations.
d1, err := xtime.ParseDuration("1h 30m 15s") d2, err := xtime.ParseDuration("1.5hours 10sec") // Combined number/unit and spaces work d3, err := xtime.ParseDuration("10 years, 2 months, 5 days") // Approximate units allowed d4, err := xtime.ParseDuration("3d12h")
Input String Processing:
- Cleaning: Leading/trailing whitespace is trimmed, "and " sequences are removed, and commas are replaced with spaces.
- Tokenization: The cleaned string is split by spaces. Tokens containing both numbers and letters (e.g., "10years", "1h30m", "h1") are further split into number and unit parts (e.g., "10", "years", "1", "h", "30", "m", "h", "1").
- Parsing: - If only one token results and it's a valid number, it's interpreted as seconds. - Otherwise, tokens are processed in pairs (value, unit). The value must be a number (integer or float), and the unit must be one of the recognized unit strings (e.g., "h", "hour", "hours", "d", "day", "days", "mo", "month", "y", "year"). - Parsing fails if the token sequence is invalid (e.g., odd number of tokens, non-number where value is expected, unknown unit).
Error Handling:
- Returns a specific error type (*DurationParseError) containing details about the failure, including the original input, problematic token, and index.
Units and Approximations ¶
The package defines standard fixed-duration units (Week, Day) and also provides approximate average durations for Month (MonthApprox) and Year (YearApprox) based on the Gregorian calendar average (365.2425 days/year).
The YearsFromDuration(d time.Duration) function converts a duration to an approximate number of years using YearApprox. Useful for rough estimations only.
Note on Units Discrepancy: ParseDuration can parse approximate units like "month" (mo) and "year" (y) based on the average durations (MonthApprox, YearApprox). However, FormatDuration does not format durations using these approximate units; it will decompose them into weeks, days, etc., for more precise representation based on the fixed time.Duration value.
Note: For calendar-accurate calculations involving months and years (which vary in length), always operate on time.Time values using functions like time.AddDate and time.Sub, rather than relying solely on time.Duration arithmetic.
Index ¶
- Constants
- func ApproxYearsFromDuration(d time.Duration) float64
- func FormatDuration(d time.Duration, opts ...FormatOption) string
- func ParseDuration(s string) (time.Duration, error)
- type DurationParseError
- type FormatOption
- func WithConjunction(conj string) FormatOption
- func WithMaxComponents(p int) FormatOption
- func WithMaxUnit(unit time.Duration) FormatOption
- func WithMinUnit(unit time.Duration) FormatOption
- func WithRounding() FormatOption
- func WithSeparator(sep string) FormatOption
- func WithStyle(style FormatStyle) FormatOption
- type FormatOptions
- type FormatStyle
Constants ¶
const ( Day time.Duration = 24 * time.Hour Week time.Duration = 7 * Day // YearApprox is the average duration of a year in the Gregorian calendar (365.2425 days). // Use this for approximations only; it does not account for calendar specifics. YearApprox time.Duration = time.Duration(365.2425 * float64(Day)) // MonthApprox is the average duration of a month in the Gregorian calendar (30.436875 days). // Use this for approximations only; it does not account for calendar specifics. MonthApprox time.Duration = time.Duration(float64(YearApprox) / 12) )
Variables ¶
This section is empty.
Functions ¶
func ApproxYearsFromDuration ¶
ApproxYearsFromDuration converts a duration into an approximate number of years. It calculates this based on the average length of a year in the Gregorian calendar (365.2425 days).
WARNING: This function provides an estimation based on duration only. It does not account for specific calendar start/end dates, leap year occurrences within a specific period, or time zones. For calendar-accurate differences involving years and months, use functions operating on time.Time values.
func FormatDuration ¶
func FormatDuration(d time.Duration, opts ...FormatOption) string
FormatDuration formats a duration into a human-readable string composed of multiple time units (e.g., "1h 5m 30s", "2 days, 3 hours").
Use FormatOptions functions (WithMaxUnit, WithMinUnit, WithRounding, WithMaxComponents, WithStyle, WithSeparator, WithConjunction) to customize output.
Example:
FormatDuration(90*time.Minute, WithStyle(FormatStyleLong)) // "1 hour, 30 minutes" FormatDuration(3723*time.Second, WithMinUnit(time.Second), WithMaxComponents(2)) // "1h 2m" FormatDuration(time.Second + 600*time.Millisecond, WithRounding()) // "2s"
func ParseDuration ¶
ParseDuration converts a human-readable duration string into a time.Duration.
It first cleans the input string using the clean() function (removing extra words like "and", replacing commas with spaces, trimming whitespace). Then, it tokenizes the cleaned string using the tokenize() function, which splits the string by spaces and also by transitions between numbers and letters (e.g., "1h30m" becomes ["1", "h", "30", "m"]).
The function handles the following cases:
- Empty or whitespace-only input: Returns an error.
- Single token input: Attempts to parse it as a float64 representing seconds. Returns an error if the token is not a valid number.
- Multiple tokens: Expects an even number of tokens representing pairs of (value, unit). It iterates through these pairs, parses the value as a float64, looks up the unit in the predefined units map, and accumulates the total duration.
It returns an error if:
- The input is empty after cleaning.
- A single token cannot be parsed as a number.
- There is an odd number of tokens (expecting pairs).
- A token expected to be a value cannot be parsed as a float64.
- A token expected to be a unit is not found in the units map.
Types ¶
type DurationParseError ¶
type DurationParseError struct { // The original input string that caused the error. Input string // The specific token that caused the error, if applicable. Token string // The index of the problematic token, if applicable. TokenIndex int // Description of the error. Message string }
DurationParseError provides specific details about a duration parsing failure.
func (*DurationParseError) Error ¶
func (e *DurationParseError) Error() string
type FormatOption ¶
type FormatOption func(*FormatOptions)
FormatOption is a function type for setting format options.
func WithConjunction ¶
func WithConjunction(conj string) FormatOption
WithConjunction sets the conjunction string for "long-and" style.
func WithMaxComponents ¶
func WithMaxComponents(p int) FormatOption
WithMaxComponents sets the max number of components. 0 means unlimited.
func WithMaxUnit ¶
func WithMaxUnit(unit time.Duration) FormatOption
WithMaxUnit sets the largest unit to display.
func WithMinUnit ¶
func WithMinUnit(unit time.Duration) FormatOption
WithMinUnit sets the smallest unit to display.
func WithSeparator ¶
func WithSeparator(sep string) FormatOption
WithSeparator sets the separator string.
func WithStyle ¶
func WithStyle(style FormatStyle) FormatOption
WithStyle sets the output style (short, long, long-and).
type FormatOptions ¶
type FormatOptions struct { // MaxUnit is the largest time unit to display (e.g., time.Hour, // xtime.Day). Components larger than this will be represented in terms of // this unit. // Default: xtime.Day. MaxUnit time.Duration // MinUnit is the smallest time unit to display (e.g., time.Second, // time.Millisecond). Any remaining duration smaller than this will be // truncated or rounded depending on Rounding. // Default: time.Second. MinUnit time.Duration // Rounding enables rounding of the smallest displayed unit based on the // remainder. // If false (default), the remainder is truncated. Rounding bool // MaxComponents limits the maximum number of components displayed (e.g., // 2 // might yield "1h 5m"). // Set to 0 or negative for unlimited components (down to MinUnit). // Default: 0 (unlimited). MaxComponents int // Style determines the format of unit names (compact, short, long, // long-and). // Default: FormatStyleShort. Style FormatStyle // Separator is the string used between components (ignored if only one // component). // Default: ", " for long styles, " " for short style, "" for compact style. Separator string // Conjunction is the string used before the last component in "long-and" // style. // Default: " and ". Conjunction string }
FormatOptions provides configuration for Format.
func DefaultFormatOptions ¶
func DefaultFormatOptions() FormatOptions
DefaultFormatOptions creates options with default values.
type FormatStyle ¶
type FormatStyle string
FormatStyle defines the output style for formatted durations.
const ( // FormatStyleCompact uses abbreviated units without spaces ("1h5m30s"). FormatStyleCompact FormatStyle = "compact" // FormatStyleShort uses abbreviated units ("1h 5m 30s"). FormatStyleShort FormatStyle = "short" // FormatStyleLong uses full unit names ("1 hour, 5 minutes, 30 seconds"). FormatStyleLong FormatStyle = "long" // FormatStyleLongAnd uses full names with "and" before the last component // ("1 hour, 5 minutes and 30 seconds"). FormatStyleLongAnd FormatStyle = "long-and" )