goiso8601duration

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2026 License: MIT Imports: 8 Imported by: 0

README

Go ISO8601 Duration

A small, zero alloc and high performance libary for parsing ISO8601 compliant duration format into Go time compatible representation.

go get github.com/xnacly/go-iso8601-duration

Features

  • ISO8601 duration parsing formats: [+-]P[n]Y[n]W[n]M[n]DT[n]H[n]M[n]S via goiso8601duration.From:
  • Interop with time.Time and time.Duration via:
    • goiso8601duration.Duration.Apply(time.Time) time.Time
    • goiso8601duration.Duration.Duration() time.Duration
    • goiso8601duration.FromDuration(time.Duration) goiso8601duration.Duration
  • Serializing goiso8601duration.Duration to the correct format goiso8601duration.Duration.String
  • JSON serialisation support via json.Unmarshaller and json.Marshaller
  • High quality errors with position context.

Example

package main

import (
    "fmt"
    "time"

    "github.com/xnacly/go-iso8601-duration"
)

func Must[T any](t T, err error) T {
	if err != nil {
		panic(err)
	}
	return t
}

func main() {
	rawDuration := "PT1H30M12S"
	duration := Must(goiso8601duration.From(rawDuration))

	// 1h30m12s PT1H30M12S
	fmt.Println(duration.Duration().String(), duration.String())

	// 01:00:00 02:30:12
	fmt.Println(
		time.
			Unix(0, 0).
			Format(time.TimeOnly),
		duration.
			Apply(time.Unix(0, 0)).
			Format(time.TimeOnly),
	)

	type arrival struct {
		In goiso8601duration.Duration `json:"in"`
	}

	asJson := Must(
		json.Marshal(
			arrival{
				In: goiso8601duration.FromDuration(
					12*time.Minute + 43*time.Second,
				),
			},
		),
	)

	// {"in":"PT12M43S"}
	fmt.Println(string(asJson))

	var a arrival
	json.Unmarshal(asJson, &a)

	// {In:PT12M43S}
	fmt.Printf("%+v\n", a)
}

Benchmarks

Reproduce with:

go test -bench=. -benchmem
goos: linux
goarch: amd64
pkg: github.com/xnacly/go-iso8601-duration
cpu: AMD Ryzen 7 3700X 8-Core Processor
BenchmarkDuration/P0D-16                100000000               10.51 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/PT15H-16              80446293                14.58 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P1W-16                100000000               10.33 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P15W-16               93517448                12.75 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P1Y15W-16             70472916                17.19 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P15Y-16               89461000                12.75 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P15Y3M-16             61222558                18.65 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P15Y3M41D-16          46391493                25.45 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/PT15M-16              80630947                14.98 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/PT15M10S-16           55008163                22.14 ns/op            0 B/op          0 allocs/op
BenchmarkDuration/P3Y6M4DT12H30M5S-16   24965916                46.99 ns/op            0 B/op          0 allocs/op
PASS
ok      github.com/xnacly/go-iso8601-duration   12.956s

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	UnexpectedEof             = errors.New("Unexpected EOF in duration format string")
	UnexpectedNonAsciiRune    = errors.New("Unexpected non ascii component in duration format string")
	MissingDesignator         = errors.New("Missing unit designator")
	UnknownDesignator         = errors.New("Unknown designator, expected YMWD or after a T, HMS")
	DuplicateDesignator       = errors.New("Duplicate designator")
	MissingNumber             = errors.New("Missing number specifier before unit designator")
	DesignatorNumberTooLarge  = errors.New("The number for the designator is too large for int64")
	MissingPDesignatorAtStart = errors.New("Missing [P] designator at the start of the duration format string")
)

Functions

This section is empty.

Types

type Duration

type Duration struct {
	// contains filtered or unexported fields
}

func From

func From(s string) (Duration, error)

P[nn]Y[nn]M[nn]DT[nn]H[nn]M[nn]S or P[nn]W, as seen in https://en.wikipedia.org/wiki/ISO_8601#Durations

- P is the duration designator (for period) placed at the start of the duration representation.

  • Y is the year designator that follows the value for the number of calendar years.
  • M is the month designator that follows the value for the number of calendar months.
  • W is the week designator that follows the value for the number of weeks.
  • D is the day designator that follows the value for the number of calendar days.

- T is the time designator that precedes the time components of the representation.

  • H is the hour designator that follows the value for the number of hours.
  • M is the minute designator that follows the value for the number of minutes.
  • S is the second designator that follows the value for the number of seconds.

func FromDuration

func FromDuration(d time.Duration) Duration

func (Duration) Apply

func (i Duration) Apply(t time.Time) time.Time

func (Duration) Duration

func (i Duration) Duration() time.Duration

func (Duration) MarshalJSON

func (i Duration) MarshalJSON() ([]byte, error)

func (Duration) String

func (i Duration) String() string

func (*Duration) UnmarshalJSON

func (i *Duration) UnmarshalJSON(data []byte) error

type ISO8601DurationError

type ISO8601DurationError struct {
	Inner  error
	Column int
}

func (ISO8601DurationError) Error

func (i ISO8601DurationError) Error() string

func (ISO8601DurationError) String

func (i ISO8601DurationError) String() string

Jump to

Keyboard shortcuts

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