goiso8601duration

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 7 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:

goos: linux
goarch: amd64
pkg: github.com/xnacly/go-iso8601-duration
cpu: Intel(R) Core(TM) Ultra 9 275HX
BenchmarkDuration/P0D-24                        165412600                 6.97 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/PT15H-24                      155630031                 7.80 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P1W-24                        171056552                 7.08 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P15W-24                       163372800                 7.00 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P1Y15W-24                     145697648                 8.48 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P15Y-24                       160867038                 7.13 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P15Y3M-24                     147443806                 8.57 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P15Y3M41D-24                   99545108                11.50 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/PT15M-24                      152095197                 7.46 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/PT15M10S-24                   100000000                11.59 ns/op           0 B/op          0 allocs/op
BenchmarkDuration/P3Y6M4DT12H30M5S-24            57697164                25.43 ns/op           0 B/op          0 allocs/op
PASS
ok      github.com/xnacly/go-iso8601-duration   20.435s

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	UnexpectedEof             = errors.New("Unexpected EOF 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

func (ISO8601DurationError) Unwrap added in v1.3.0

func (i ISO8601DurationError) Unwrap() error

Jump to

Keyboard shortcuts

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