durationparser

package
v0.0.0-...-52d0e0a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2020 License: Unlicense Imports: 6 Imported by: 9

README

DetcTime DurationParser

this is a duration parser created to support a wider range of units and with slightly more flexible syntax than the stdlib time.ParseDuration and to attempt to take into account the variability in calender units such as months or years

To handle calender time this duration parser uses a time.Time reference and custom transform functions for certain units instead of a duration sum with fixed units, as such all durations are parsed relative to a certain point in time

The goal being that by using time.Time as a base instead of a duration it should be able to properly take into account the variable length of calender units (most notably months and years, but also days within the regions that still use daylight savings time) so that if its may 4th a duration string such as 2 months returns the duration of time between may 4th and july 4th instead of just assuming all months are the same and returning 60 days

using ParseAt you can specify what time to use, or you can use Parse to parse relative to time.Now or ParseStatic to parse relative to a blank time.Time{}

It also includes some extra customisability like the ability to create custom units or set a max or minimum duration

String formats

it supports typical duration strings like below

  • 10d5h
  • 10 days 5 hours or any combination of
  • 2 days 5h30m
  • 2 weeks 1d 30 hours 5 m

as long as it is within the pattern of number identifier number identifier it'll parse the only expection being if a default unit is set (or a unit is defined with a blank string as an identifier) it can take a number with no trailing identifier at the end

  • 100 assuming the default is set to minutes that will give 1 hour 40 minutes

spaces are completely ignored while parsing so 1 0 h o u r s gets parsed as 10 hours, unless p.KeepSpacesInIdentifier is enabled which in that case it gets parsed as 10 h o u r s

negative numbers -3 minutes are supported

decimal points 1.5h are partly supported, they are fully supported on units using StaticAdder (all units < day), they will be rounded to the nearest integer number with DayAdder MonthAdder and YearAdder (all units >= day) however

Examples

Parse a duration relative to the current time

d, err := durationparser.Parse("10 hours 5 minutes")
// 10h5m

Parse a duration relative to a blank time.Time{}

d, err := durationparser.ParseStatic("10 hours 5 minutes")
// 10h5m

Parse Relative to a custom time

tm, _ := time.Parse(time.RFC3339, "2020-05-04T00:04:35+00:00")

d, err := durationparser.ParseAt("2mo", tm)
// 1464h0m0s, equal to the distance between 2020-05-04 and 2020-7-04

Custom parser

par := &durationparser.Parser{
	Units: []durationparser.Unit{
		durationparser.Second,
		durationparser.Minute,
	},
	Maximum: time.Duration*48,
	Minimum: 0,
}
// creates a parser with Minutes and seconds, a minimum disallowing any negative durations, and a max of 2 days

Define a custom unit using the StaticAdder (a custom unit can be defined using any type implementing UnitAdder though)

pitime := durationparser.Unit{
	Identifiers: []string{"pi", "pis"},
	Unit:        durationparser.StaticAdder(time.Second * 3141),
}

par := &durationparser.Parser{
	Units: []durationparser.Unit{
		pitime,
	},
}

d, err := par.Parse("2 pis")
// 1h44m42s

Documentation

Overview

Package durationparser contains a duration parser created to have a wider range of units than the stdlib time.ParseDuration and to attempt to take into account the variability in calender units such as months or years

To do this it uses a time.Time reference and custom transform functions for certain units instead of a duration sum with fixed units, as such all durations are parsed relative to a point in time, using `ParseAt` you can specify what time to use, or you can use `Parse` to parse relative to time.Now or `ParseStatic` to parse relative to a blank time.Time{}

It also includes some extra customisability like the ability to create custom units or set a max or minimum duration

Index

Constants

View Source
const (
	ErrorUnknownError dpErrorType = iota
	ErrorUndefinedUnit
	ErrorTooHigh
	ErrorTooLow
)

Some various error internal error types. These can be used with the errors.Is function provided by the errors package to help narrow down the error cause and provide a better formatted error message to a user. Note that these only define the errors specific to the parser, errors from other packages (such as a malformed float or int) are not defined or handled by this package, those errors are simply returned as is by the parse function. (see strconv.ErrRange and strconv.ErrSyntax for checking those)

Variables

View Source
var (
	EnglishIdentifiersMiliseconds = []string{"milliseconds", "millisecond", "miliseconds", "milisecond", "ms"}
	EnglishIdentifiersSeconds     = []string{"seconds", "second", "secs", "sec", "s"}
	EnglishIdentifiersMinutes     = []string{"minutes", "minute", "mins", "min", "m"}
	EnglishIdentifiersHours       = []string{"hours", "hour", "h"}
	EnglishIdentifiersDays        = []string{"days", "day", "d"}
	EnglishIdentifiersWeeks       = []string{"weeks", "week", "wks", "wk", "w"}
	EnglishIdentifiersMonths      = []string{"months", "month", "mo"}
	EnglishIdentifiersQuarters    = []string{"quarters", "quarter", "q"}
	EnglishIdentifiersYears       = []string{"years", "year", "y"}
	EnglishIdentifiersDecades     = []string{"decades", "decade", "dec"}
)

Some default English terms for time

View Source
var (
	Millisecond = Unit{
		Unit:        StaticAdder(time.Millisecond),
		Identifiers: EnglishIdentifiersMiliseconds,
	}
	Second = Unit{
		Unit:        StaticAdder(time.Second),
		Identifiers: EnglishIdentifiersSeconds,
	}
	Minute = Unit{
		Unit:        StaticAdder(time.Minute),
		Identifiers: EnglishIdentifiersMinutes,
	}
	Hour = Unit{
		Unit:        StaticAdder(time.Hour),
		Identifiers: EnglishIdentifiersHours,
	}
	Day = Unit{
		Unit:        DayAdder(1),
		Identifiers: EnglishIdentifiersDays,
	}
	Week = Unit{
		Unit:        DayAdder(7),
		Identifiers: EnglishIdentifiersWeeks,
	}
	Month = Unit{
		Unit:        MonthAdder(1),
		Identifiers: EnglishIdentifiersMonths,
	}
	Year = Unit{
		Unit:        YearAdder(1),
		Identifiers: EnglishIdentifiersYears,
	}
	Decade = Unit{
		Unit:        YearAdder(10),
		Identifiers: EnglishIdentifiersDecades,
	}
)

Preset english units

View Source
var Default = &Parser{
	Units: []Unit{
		Millisecond,
		Second,
		Minute,
		Hour,
		Day,
		Week,
		Month,
		Year,
		Decade,
	},
}

Default is a presetup default parser

Functions

func Parse

func Parse(s string) (time.Duration, error)

Parse is an alias to Parse in the default parser, see the documentation on Parser and its methods for more information

func ParseAt

func ParseAt(s string, tm time.Time) (time.Duration, error)

ParseAt is an alias to ParseAt in the default parser, see the documentation on Parser and its methods for more information

func ParseStatic

func ParseStatic(s string) (time.Duration, error)

ParseStatic is an alias to ParseStatic in the default parser, see the documentation on Parser and its methods for more information

Types

type DayAdder

type DayAdder int

DayAdder is a UnitAdder that adds a number of days taking account of the calander (via time.Time.AddDate)

func (DayAdder) Add

func (d DayAdder) Add(t time.Time, nbr int, fp float64) time.Time

Add adds d * nbr days to t

type MonthAdder

type MonthAdder int

MonthAdder is a UnitAdder that adds a number of months taking account of the calander (via time.Time.AddDate)

func (MonthAdder) Add

func (m MonthAdder) Add(t time.Time, nbr int, fp float64) time.Time

Add adds m * nbr months to t

type Parser

type Parser struct {
	// The units names and their assosiated functions to use in parsing a duration
	Units []Unit

	// The Maximum duration, if Max != 0 it will check if the parsed duration exceeds max and will return the value of max and ErrorTooHigh
	// ErrorTooHigh can be safely ignored as the returned duration will be the value of max (check for ErrorTooHigh using errors.Unwrap)
	Maximum time.Duration

	// The minimum duration, functions the same as maximum except flipped to check if the duration is less than minimum and returns ErrorTooLow instead
	Minimum time.Duration

	// the unit to use if no unit is specified
	DefaultUnit string

	// This sets whether or not spaces should be completely ignored (false) or whether they should be kept in unit identifiers
	// when disabled (default) `1 0 h o u r s` gets parsed the same as 10 `hours`
	// when enabled it gets parsed as 10 `h o u r s`
	KeepSpacesInIdentifier bool
}

Parser is a duration parsing tool that uses the calander via time.Time as a reference point instead of a static length sum. the goal being that by using time.Time as a base instead of a duration it should be able to properly take into account the variable length of calender units, so that if its may 4th a duration string such as `2 months` returns the duration of time between may 4th and july 4th instead of just assuming all months are the same and returning 60 days. Parser is safe for concurrent use as long as the units or settings are not modified while in use and no custom unit methods are created with concurrency unsafe code.

func (Parser) Parse

func (p Parser) Parse(s string) (time.Duration, error)

Parse is equivalent to calling p.ParseAt with time.Now() as t

func (Parser) ParseAt

func (p Parser) ParseAt(s string, t time.Time) (time.Duration, error)

ParseAt parses a duration string relative to the time given in t.

func (Parser) ParseStatic

func (p Parser) ParseStatic(s string) (time.Duration, error)

ParseStatic is equivalent to calling p.ParseAt with a blank time.Time{}

type StaticAdder

type StaticAdder time.Duration

StaticAdder is a UnitAdder that adds a fixed unit of duration to t

func (StaticAdder) Add

func (f StaticAdder) Add(t time.Time, nbr int, fp float64) time.Time

Add adds f * fp duration to t and returns the result

type Unit

type Unit struct {
	Unit        UnitAdder
	Identifiers []string
}

Unit defines a units addition rule (via UnitAdder) and its identifiers

type UnitAdder

type UnitAdder interface {
	// t is the time to be added to
	// integer is the number given with the unit (rounded down/tunctuated if any decimal point was given)
	// float is the number given with the unit as a floating point number, including the decimal point if given
	Add(t time.Time, integer int, float float64) time.Time
}

UnitAdder is an interface to allow custom means of adding time to things

type YearAdder

type YearAdder int

YearAdder is a UnitAdder that adds a number of years taking account of the calander (via time.Time.AddDate)

func (YearAdder) Add

func (y YearAdder) Add(t time.Time, nbr int, fp float64) time.Time

Add adds y * nbr years to t

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL