duration

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 21, 2021 License: MIT Imports: 8 Imported by: 0

README

Duration Build Coverage Go Report Card Go Reference

Parse ISO8601 duration strings, and use to shift dates/times.

Original credit goes to https://github.com/senseyeio/duration.

Basic Example

package main

import (
	"fmt"
	"time"

	"github.com/Calidity/duration"
)

func main() {
	d, _ := iso8601.ParseISO8601("P1D")
	today := time.Now()
	tomorrow := d.Shift(today)
	fmt.Println(today.Format("Jan _2"))
	fmt.Println(tomorrow.Format("Jan _2"))
}

Why Does This Package Exist

Why can't we just use a time.Duration and time.Add?

A very reasonable question.

The code below repeatedly adds 24 hours to a time.Time. You might expect the time on that date to stay the same, but there are not always 24 hours in a day. When the clocks change in New York, the time will skew by an hour. As you can see from the output, duration.Duration.Shift() can increment the date without shifting the time.

package main

import (
	"fmt"
	"time"

	"github.com/Calidity/duration"
)

func main() {
	loc, _ := time.LoadLocation("America/New_York")
	d, _ := iso8601.ParseISO8601("P1D")
	t1, _ := time.ParseInLocation("Jan 2, 2006 at 3:04pm", "Jan 1, 2006 at 3:04pm", loc)
	t2 := t1
	for i := 0; i < 365; i++ {
		t1 = t1.Add(24 * time.Hour)
		t2 = d.Shift(t2)
		fmt.Printf("time.Add:%d    Duration.Shift:%d\n", t1.Hour(), t2.Hour())
	}
}

// Outputs
// time.Add:15    Duration.Shift:15
// time.Add:15    Duration.Shift:15
// time.Add:15    Duration.Shift:15
// ...
// time.Add:16    Duration.Shift:15
// time.Add:16    Duration.Shift:15
// time.Add:16    Duration.Shift:15
// ...

Months are tricky. Shifting by months uses time.AddDate(), which is great. However, be aware of how differing days in the month are accommodated. Dates will 'roll over' if the month you're shifting to has fewer days. e.g. if you start on Jan 30th and repeat every "P1M", you'll get this:

Jan 30, 2006
Mar 2, 2006
Apr 2, 2006
May 2, 2006
Jun 2, 2006
Jul 2, 2006
Aug 2, 2006
Sep 2, 2006
Oct 2, 2006
Nov 2, 2006
Dec 2, 2006
Jan 2, 2007

Documentation

Overview

Package duration handles ISO8601-formatted durations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Duration

type Duration struct {
	Y int
	M int
	W int
	D int
	// Time Component
	TH int
	TM int
	TS int
}

Duration represents an ISO8601 Duration https://en.wikipedia.org/wiki/ISO_8601#Durations

func ParseISO8601

func ParseISO8601(from string) (Duration, error)

ParseISO8601 parses an ISO8601 duration string.

func (Duration) HasTimePart

func (d Duration) HasTimePart() bool

HasTimePart returns true if the time part of the duration is non-zero.

func (Duration) IsZero

func (d Duration) IsZero() bool

IsZero reports whether d represents the zero duration, P0D.

func (Duration) MarshalJSON

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

MarshalJSON satisfies json.Marshaler.

func (Duration) Shift

func (d Duration) Shift(t time.Time) time.Time

Shift returns a time.Time, shifted by the duration from the given start.

NB: Shift uses time.AddDate for years, months, weeks, and days, and so shares its limitations. In particular, shifting by months is not recommended unless the start date is before the 28th of the month. Otherwise, dates will roll over, e.g. Aug 31 + P1M = Oct 1.

Week and Day values will be combined as W*7 + D.

func (Duration) String

func (d Duration) String() string

String returns an ISO8601-ish representation of the duration.

func (Duration) ToTimeDuration

func (d Duration) ToTimeDuration() time.Duration

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(b []byte) error

UnmarshalJSON satisfies json.Unmarshaler.

Jump to

Keyboard shortcuts

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