synchro

package module
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Dec 16, 2023 License: MIT Imports: 10 Imported by: 1

README

🕰️ Synchro: Timezone-typesafe date and time framework for Go

test codecov Go Reference

This is inspired by Rust chrono

Features

  • Timezone-typesafe date and time handling
  • Easy conversion between time zones
  • Support for common date and time operations
  • Compatible with the standard time package
  • Full compatible with ISO8601 (GoDoc)
    • ✅ Dates
      • Years
      • Calendar dates
      • Week dates
      • Quarter dates
      • Ordinal dates
    • ✅ Times
    • ✅ Combined date and time representations
    • ✅ Durations
    • ✅ Time intervals
      • Repeating intervals
    • Note: This package can be used as civil time.
      • Civil time is a time-zone-independent representation of time that follows the rules of the proleptic Gregorian calendar with exactly 24-hour days, 60-minute hours, and 60-second minutes.

Installation

To install Synchro, use go get:

go get github.com/Code-Hex/synchro

Synopsis

To use Synchro, import it in your Go code:

package main

import (
    "fmt"

    "github.com/Code-Hex/synchro"
    "github.com/Code-Hex/synchro/tz"
)

func main() {
    // The current UTC time is fixed to `2023-09-02 14:00:00`.
    utcNow := synchro.Now[tz.UTC]()
    fmt.Println(utcNow)

    jstNow := synchro.Now[tz.AsiaTokyo]()
    fmt.Println(jstNow)
    // Output:
    // 2009-11-10 23:00:00 +0000 UTC
    // 2009-11-11 08:00:00 +0900 JST
}

https://go.dev/play/p/Ql3CM7NLfj0

Please refer to the numerous usage examples on GoDoc for reference.

Utilities

We also have a wide range of very useful utilities!!

If you have a feature request, please open an issue. It would be great if you could provide relevant examples or links that could be helpful.

TODO

  • Support database/sql
  • Support i18n
  • Optimization

Contributing

Contributions to Synchro are welcome!

To contribute, please fork the repository and submit a pull request.

License

Synchro is licensed under the MIT License. See LICENSE for more information.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func After

func After[T TimeZone](d time.Duration) <-chan Time[T]

After waits for the duration to elapse and then sends the current time on the returned channel. It is equivalent to NewTimer(d).C. The underlying Timer is not recovered by the garbage collector until the timer fires. If efficiency is a concern, use NewTimer instead and call Timer.Stop if the timer is no longer needed.

This is a simple wrapper function for time.After.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

var c chan int

func handle(int) {}

func main() {
	select {
	case m := <-c:
		handle(m)
	case <-synchro.After[tz.UTC](time.Millisecond):
		fmt.Println("timed out")
	}
}
Output:

timed out

func NowWithContext

func NowWithContext[T TimeZone](ctx context.Context, t Time[T]) context.Context

NowWithContext returns a new context with the provided time with timezone stored in it. This allows you to create a context with a specific time value attached to it.

Types

type Day added in v0.0.9

type Day int

Day sets the day component of the time being built.

type Hour added in v0.0.9

type Hour int

Hour sets the hour component of the time being built.

type Minute added in v0.0.9

type Minute int

Minute sets the minute component of the time being built.

type Month added in v0.0.9

type Month int

Month sets the month component of the time being built.

type Nanosecond added in v0.0.9

type Nanosecond int

Nanosecond sets the nanosecond component of the time being built.

type NullTime added in v0.0.4

type NullTime[T TimeZone] struct {
	Time  Time[T]
	Valid bool // Valid is true if Time is not NULL
}

NullTime represents a Time[T] that may be null. NullTime implements the sql.Scanner interface so it can be used as a scan destination, similar to sql.NullString.

func (*NullTime[T]) Scan added in v0.0.4

func (n *NullTime[T]) Scan(src any) error

Scan implements the sql.Scanner interface.

func (NullTime[T]) Value added in v0.0.4

func (n NullTime[T]) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

type Period added in v0.2.0

type Period[T TimeZone] struct {
	// contains filtered or unexported fields
}

Period allows iteration over a set of dates and times, recurring at regular intervals, over a given period.

Example (PeriodicalSlice)
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p1, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01T00:00:00",
		"2009-01-01T03:00:00",
	)

	got := p1.PeriodicDuration(time.Hour).Slice()
	fmt.Println("len:", len(got))
	for _, current := range got {
		fmt.Println(current)
	}
}
Output:

len: 4
2009-01-01 00:00:00 +0000 UTC
2009-01-01 01:00:00 +0000 UTC
2009-01-01 02:00:00 +0000 UTC
2009-01-01 03:00:00 +0000 UTC

func NewPeriod added in v0.2.0

func NewPeriod[T TimeZone, T1 timeish[T], T2 timeish[T]](from T1, to T2) (Period[T], error)

NewPeriod creates a new Period struct between the 'from' and 'to' values you specified.

If Time[T] or time.Time is specified, it guarantees no error returns. When a string or []byte is passed, ParseISO function is called internally. Therefore, these parameters should be in a format compatible with ParseISO.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	// with synchro.Time params
	p1, _ := synchro.NewPeriod[tz.UTC](
		synchro.New[tz.UTC](2009, 1, 1, 0, 0, 0, 0),
		synchro.New[tz.UTC](2009, 1, 10, 23, 59, 59, 0),
	)
	// with time.Time params
	p2, _ := synchro.NewPeriod[tz.UTC](
		time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC),
		time.Date(2009, 1, 10, 23, 59, 59, 0, time.UTC),
	)
	// with ISO 8601 date and time format string or bytes
	p3, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01",
		[]byte("2009-01-10T23:59:59Z"),
	)
	// Reverse
	p4, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-10T23:59:59",
		"2009-01-01",
	)
	fmt.Printf("p1: %s\n", p1)
	fmt.Printf("p2: %s\n", p2)
	fmt.Printf("p3: %s\n", p3)
	fmt.Printf("p4: %s\n", p4)
}
Output:

p1: from 2009-01-01 00:00:00 +0000 UTC to 2009-01-10 23:59:59 +0000 UTC
p2: from 2009-01-01 00:00:00 +0000 UTC to 2009-01-10 23:59:59 +0000 UTC
p3: from 2009-01-01 00:00:00 +0000 UTC to 2009-01-10 23:59:59 +0000 UTC
p4: from 2009-01-10 23:59:59 +0000 UTC to 2009-01-01 00:00:00 +0000 UTC

func (Period[T]) Contains added in v0.3.0

func (p Period[T]) Contains(t Time[T]) int

Contains checks whether the specified t is included within from and to.

if p.from < t && t < p.to, it returns +1; if p.from == t || t == p.to, it returns 0. Otherwise returns -1;

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p, _ := synchro.NewPeriod[tz.UTC](
		"2008-12-28",
		"2009-01-03",
	)
	t := synchro.New[tz.UTC](2009, 1, 3, 0, 0, 0, 0)

	// p.Contains(t) >= 0 is the same as 2008-12-28 <= t && t <= 2009-01-03
	fmt.Println("p.Contains(t) >= 0:", p.Contains(t) >= 0)
}
Output:

p.Contains(t) >= 0: true

func (Period[T]) From added in v0.3.0

func (p Period[T]) From() Time[T]

From returns end of period.

func (Period[T]) Periodic added in v0.2.0

func (p Period[T]) Periodic(next func(Time[T]) Time[T]) periodical[T]

Periodic returns a channel that emits Time[T] values at regular intervals between the start and end times of the Period[T]. The interval is specified by the next function argument.

If start < end, the process will increase from start to end. In other words, when the current value exceeds end, the iteration is terminated.

If start > end, the process will decrease from start to end. In other words, when the current value falls below end, the iteration is terminated.

func (Period[T]) PeriodicAdvance added in v0.2.0

func (p Period[T]) PeriodicAdvance(u1 Unit, u2 ...Unit) periodical[T]

PeriodicAdvance is a wrapper for the Periodic function. The interval is specified by the provided date and time unit arguments.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p1, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01",
		time.Date(2013, 1, 3, 0, 0, 0, 0, time.UTC),
	)
	for current := range p1.PeriodicAdvance(synchro.Year(1), synchro.Day(1)) {
		fmt.Println(current)
	}
}
Output:

2009-01-01 00:00:00 +0000 UTC
2010-01-02 00:00:00 +0000 UTC
2011-01-03 00:00:00 +0000 UTC
2012-01-04 00:00:00 +0000 UTC

func (Period[T]) PeriodicDate added in v0.2.0

func (p Period[T]) PeriodicDate(years int, months int, days int) periodical[T]

PeriodicDuration is a wrapper for the Periodic function. The interval is specified by the given number of years, months, and days.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p1, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01",
		"2009-01-03",
	)
	for current := range p1.PeriodicDate(0, 0, 1) {
		fmt.Println(current)
	}
}
Output:

2009-01-01 00:00:00 +0000 UTC
2009-01-02 00:00:00 +0000 UTC
2009-01-03 00:00:00 +0000 UTC

func (Period[T]) PeriodicDuration added in v0.2.0

func (p Period[T]) PeriodicDuration(d time.Duration) periodical[T]

PeriodicDuration is a wrapper for the Periodic function. The interval is specified by the time.Duration argument.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p1, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01",
		synchro.New[tz.UTC](2009, 1, 1, 3, 59, 59, 0),
	)
	for current := range p1.PeriodicDuration(time.Hour) {
		fmt.Println(current)
	}
}
Output:

2009-01-01 00:00:00 +0000 UTC
2009-01-01 01:00:00 +0000 UTC
2009-01-01 02:00:00 +0000 UTC
2009-01-01 03:00:00 +0000 UTC

func (Period[T]) PeriodicISODuration added in v0.2.0

func (p Period[T]) PeriodicISODuration(duration string) (periodical[T], error)

PeriodicISODuration is a wrapper for the Periodic function. It accepts a duration in ISO 8601 format as a parameter.

Examples of valid durations include:

PnYnMnDTnHnMnS (e.g., P3Y6M4DT12H30M5S)
PnW (e.g., P4W)
Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	p1, _ := synchro.NewPeriod[tz.UTC](
		"2009-01-01",
		"2009-03-01",
	)
	iter, _ := p1.PeriodicISODuration("P1M")
	for current := range iter {
		fmt.Println(current)
	}
}
Output:

2009-01-01 00:00:00 +0000 UTC
2009-02-01 00:00:00 +0000 UTC
2009-03-01 00:00:00 +0000 UTC

func (Period[T]) String added in v0.2.0

func (p Period[T]) String() string

String implements the fmt.Stringer interface.

func (Period[T]) To added in v0.3.0

func (p Period[T]) To() Time[T]

To returns start of period.

type Quarter

type Quarter[T TimeZone] struct {
	// contains filtered or unexported fields
}

func (Quarter[T]) After

func (q Quarter[T]) After(u Quarter[T]) bool

After reports whether the Quarter instant q is after u.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 4, 1, 0, 0, 0, 0)
	d3 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	q1 := d1.Quarter()
	q2 := d2.Quarter()
	q3 := d3.Quarter()

	fmt.Printf("q2.After(q1) = %v\n", q2.After(q1))
	fmt.Printf("q3.After(q1) = %v\n", q3.After(q1))
	fmt.Printf("q1.After(q2) = %v\n", q1.After(q2))
}
Output:

q2.After(q1) = true
q3.After(q1) = true
q1.After(q2) = false

func (Quarter[T]) Before

func (q Quarter[T]) Before(u Quarter[T]) bool

Before reports whether the Quarter instant q is before u.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 4, 1, 0, 0, 0, 0)
	d3 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	q1 := d1.Quarter()
	q2 := d2.Quarter()
	q3 := d3.Quarter()

	fmt.Printf("q1.Before(q2) = %v\n", q1.Before(q2))
	fmt.Printf("q1.Before(q3) = %v\n", q1.Before(q3))
	fmt.Printf("q2.Before(q1) = %v\n", q2.Before(q1))
}
Output:

q1.Before(q2) = true
q1.Before(q3) = true
q2.Before(q1) = false

func (Quarter[T]) Compare

func (q Quarter[T]) Compare(u Quarter[T]) int

Compare compares the Quarter instant q with u. If q is before u, it returns -1; if q is after u, it returns +1; if they're the same, it returns 0.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 3, 31, 23, 59, 59, 999999999)
	d3 := synchro.New[tz.UTC](2023, 7, 1, 0, 0, 0, 0)
	d4 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	q1 := d1.Quarter()
	q2 := d2.Quarter()
	q3 := d3.Quarter()
	q4 := d4.Quarter()

	fmt.Printf("q1.Compare(q2) = %d\n", q1.Compare(q2))
	fmt.Printf("q1.Compare(q3) = %d\n", q1.Compare(q3))
	fmt.Printf("q4.Compare(q1) = %d\n", q4.Compare(q1))

}
Output:

q1.Compare(q2) = 0
q1.Compare(q3) = -1
q4.Compare(q1) = 1

func (Quarter[T]) End

func (q Quarter[T]) End() Time[T]

End returns end time in the quarter.

func (Quarter[T]) Number

func (q Quarter[T]) Number() int

Number returns the number of quarter.

func (Quarter[T]) Start

func (q Quarter[T]) Start() Time[T]

Start returns start time in the quarter.

func (Quarter[T]) Year

func (q Quarter[T]) Year() int

Year returns the year in which q occurs.

type Second added in v0.0.9

type Second int

Second sets the second component of the time being built.

type Semester

type Semester[T TimeZone] struct {
	// contains filtered or unexported fields
}

func (Semester[T]) After

func (s Semester[T]) After(u Semester[T]) bool

After reports whether the Semester instant s is after u.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 7, 1, 0, 0, 0, 0)
	d3 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	s1 := d1.Semester()
	s2 := d2.Semester()
	s3 := d3.Semester()

	fmt.Printf("s2.After(s1) = %v\n", s2.After(s1))
	fmt.Printf("s3.After(s1) = %v\n", s3.After(s1))
	fmt.Printf("s1.After(s2) = %v\n", s1.After(s2))
}
Output:

s2.After(s1) = true
s3.After(s1) = true
s1.After(s2) = false

func (Semester[T]) Before

func (s Semester[T]) Before(u Semester[T]) bool

Before reports whether the Semester instant s is before u.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 7, 1, 0, 0, 0, 0)
	d3 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	s1 := d1.Semester()
	s2 := d2.Semester()
	s3 := d3.Semester()

	fmt.Printf("s1.Before(s2) = %v\n", s1.Before(s2))
	fmt.Printf("s1.Before(s3) = %v\n", s1.Before(s3))
	fmt.Printf("s2.Before(s1) = %v\n", s2.Before(s1))
}
Output:

s1.Before(s2) = true
s1.Before(s3) = true
s2.Before(s1) = false

func (Semester[T]) Compare

func (s Semester[T]) Compare(u Semester[T]) int

Compare compares the Semester instant s with u. If s is before u, it returns -1; if s is after u, it returns +1; if they're the same, it returns 0.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2023, 1, 1, 0, 0, 0, 0)
	d2 := synchro.New[tz.UTC](2023, 6, 30, 23, 59, 59, 999999999)
	d3 := synchro.New[tz.UTC](2023, 7, 1, 0, 0, 0, 0)
	d4 := synchro.New[tz.UTC](2024, 1, 1, 0, 0, 0, 0)

	s1 := d1.Semester()
	s2 := d2.Semester()
	s3 := d3.Semester()
	s4 := d4.Semester()

	fmt.Printf("s1.Compare(s2) = %d\n", s1.Compare(s2))
	fmt.Printf("s1.Compare(s3) = %d\n", s1.Compare(s3))
	fmt.Printf("s4.Compare(s1) = %d\n", s4.Compare(s1))

}
Output:

s1.Compare(s2) = 0
s1.Compare(s3) = -1
s4.Compare(s1) = 1

func (Semester[T]) End

func (s Semester[T]) End() Time[T]

End returns end time in the semester.

func (Semester[T]) Number

func (s Semester[T]) Number() int

Number returns the number of semester.

func (Semester[T]) Start

func (s Semester[T]) Start() Time[T]

Start returns start time in the semester.

func (Semester[T]) Year

func (s Semester[T]) Year() int

Year returns the year in which s occurs.

type Time

type Time[T TimeZone] struct {
	// contains filtered or unexported fields
}

func ConvertTz

func ConvertTz[U TimeZone, T TimeZone](from Time[T]) Time[U]

ConvertTz can be used to convert a time from one time zone to another.

For example to convert from UTC to Asia/Tokyo. If `2009-11-10 23:00:00 +0000 UTC` as input, the output will be `2009-11-11 08:00:00 +0900 Asia/Tokyo`.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	utc := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	fmt.Printf("Go launched at %s\n", utc)

	jst := synchro.ConvertTz[tz.AsiaTokyo](utc)
	fmt.Printf("Go launched at %s\n", jst)
}
Output:

Go launched at 2009-11-10 23:00:00 +0000 UTC
Go launched at 2009-11-11 08:00:00 +0900 JST

func In

func In[T TimeZone](tm time.Time) Time[T]

In returns timezone-aware time.

If the given time.Time is the zero value, a zero value Time[T] is returned. A zero value Time[T] is not timezone-aware. Always set UTC.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d := time.Date(2023, 9, 2, 14, 0, 0, 0, time.UTC)
	utc := synchro.In[tz.UTC](d)
	fmt.Println(utc)

	jst := synchro.In[tz.AsiaTokyo](d)
	fmt.Println(jst)
}
Output:

2023-09-02 14:00:00 +0000 UTC
2023-09-02 23:00:00 +0900 JST

func New

func New[T TimeZone](year int, month time.Month, day int, hour int, min int, sec int, nsec int) Time[T]

New returns the Time corresponding to

yyyy-mm-dd hh:mm:ss + nsec nanoseconds

in the appropriate zone for that time in the given timezone.

The month, day, hour, min, sec, and nsec values may be outside their usual ranges and will be normalized during the conversion. For example, October 32 converts to November 1.

A daylight savings time transition skips or repeats times. For example, in the United States, March 13, 2011 2:15am never occurred, while November 6, 2011 1:15am occurred twice. In such cases, the choice of time zone, and therefore the time, is not well-defined. Date returns a time that is correct in one of the two zones involved in the transition, but it does not guarantee which.

This is a simple wrapper function for time.Date.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	utc := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	fmt.Printf("Go launched at %s\n", utc)
}
Output:

Go launched at 2009-11-10 23:00:00 +0000 UTC

func Now

func Now[T TimeZone]() Time[T]

Now returns the current time with timezone.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	// The current UTC time is fixed to `2023-09-02 14:00:00`.
	utcNow := synchro.Now[tz.UTC]()
	fmt.Println(utcNow)

	jstNow := synchro.Now[tz.AsiaTokyo]()
	fmt.Println(jstNow)
}
Output:

2023-09-02 14:00:00 +0000 UTC
2023-09-02 23:00:00 +0900 JST

func NowContext

func NowContext[T TimeZone](ctx context.Context) Time[T]

NowContext returns the current time stored in the provided context. If the time is not found in the context, it returns zero value.

NowContext and NowWithContext are useful when you want to store the current time within the context of the executing logic. For example, in scenarios where you consider the entire lifecycle of an HTTP request, from its initiation to the response.

By capturing the timestamp when the request occurs and fixing it as the current time, you can achieve consistent handling of the current time throughout that request. This ensures uniformity in dealing with the current time within the scope of that specific request.

Example
package main

import (
	"context"
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	// This is the timestamp when the request occurred.
	// The current UTC time is fixed to `2023-09-02 14:00:00`.
	timestamp := synchro.Now[tz.UTC]()

	// The context of the request.
	ctx := context.Background()

	// Set the current time within the request context.Context.
	ctx = synchro.NowWithContext[tz.UTC](ctx, timestamp)
	utcNow := synchro.NowContext[tz.UTC](ctx)
	fmt.Println(utcNow)

	// A zero value is returned because the time is not stored in the same timezone.
	jstNow := synchro.NowContext[tz.AsiaTokyo](ctx)
	fmt.Println(jstNow)
}
Output:

2023-09-02 14:00:00 +0000 UTC
0001-01-01 00:00:00 +0000 UTC

func Parse

func Parse[T TimeZone](layout, value string) (Time[T], error)

Parse parses a formatted string and returns the time value it represents. See the documentation for the constant called Layout to see how to represent the format. The second argument must be parseable using the format string (layout) provided as the first argument.

This is a simple wrapper function for time.ParseInLocation.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func init() {
	synchro.SetNow(func() time.Time {
		return time.Date(2023, 9, 2, 14, 0, 0, 0, time.UTC)
	})
}

type EuropeBerlin struct{}

func (EuropeBerlin) Location() *time.Location {
	loc, _ := time.LoadLocation("Europe/Berlin")
	return loc
}

func main() {
	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
	t, _ := synchro.Parse[EuropeBerlin](longForm, "Jul 9, 2012 at 5:02am (CEST)")
	fmt.Println(t)

	// Note: without explicit zone, returns time in given location.
	const shortForm = "2006-Jan-02"
	t, _ = synchro.Parse[EuropeBerlin](shortForm, "2012-Jul-09")
	fmt.Println(t)

	_, err := synchro.Parse[tz.UTC](time.RFC3339, time.RFC3339)
	fmt.Println("error", err) // Returns an error as the layout is not a valid time value

}
Output:

2012-07-09 05:02:00 +0200 CEST
2012-07-09 00:00:00 +0200 CEST
error parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"

func ParseISO added in v0.0.5

func ParseISO[T TimeZone](value string) (Time[T], error)

ParseISO parses an ISO8601-compliant date or datetime string and returns its representation as a Time. If the input string does not conform to the ISO8601 standard or if any other parsing error occurs, an error is returned. Supported formats include:

Basic                        Extended
20070301                     2007-03-01
2012W521                     2012-W52-1
2012Q485                     2012-Q4-85
20070301T1300Z               2007-03-01T13:00Z
20070301T1300Z               2007-03-01T13:00Z
20070301T1300+0100           2007-03-01T13:00+01:00
20070301T1300-0600           2007-03-01T13:00-06:00
20070301T130045Z             2007-03-01T13:00:45Z
20070301T130045+0100         2007-03-01T13:00:45+01:00
... and other combinations

func Strptime added in v0.5.0

func Strptime[T TimeZone](source string, format string) (Time[T], error)

Strptime parses time string with the default location. The location is also used to parse the time zone name (%Z).

The format string should follow the format of strptime(3) in man pages. The following list shows the supported format specifiers:

  • %a: abbreviated weekday name
  • %A: full weekday name
  • %b: abbreviated month name
  • %B: full month name
  • %c: preferred date and time representation
  • %C: century number (00-99)
  • %d: day of the month (01-31)
  • %D: same as %m/%d/%y
  • %e: day of the month (1-31)
  • %F: same as %Y-%m-%d
  • %g: last two digits of the year (00-99)
  • %G: year as a 4-digit number
  • %h: same as %b
  • %H: hour (00-23)
  • %I: hour (01-12)
  • %j: day of the year (001-366)
  • %m: month (01-12)
  • %M: minute (00-59)
  • %n: newline character
  • %p: either "am" or "pm" according to the given time value
  • %r: time in a.m. and p.m. notation
  • %R: time in 24 hour notation
  • %S: second (00-60)
  • %t: tab character
  • %T: current time, equal to %H:%M:%S
  • %u: weekday as a number (1-7)
  • %U: week number of the current year, starting with the first Sunday as the first day of the first week
  • %V: week number of the current year, starting with the first week that has at least 4 days in the new year
  • %w: day of the week as a decimal, Sunday being 0
  • %W: week number of the current year, starting with the first Monday as the first day of the first week
  • %x: preferred date representation without the time
  • %X: preferred time representation without the date
  • %y: year without a century (00-99)
  • %Y: year with century
  • %z: time zone offset, such as "-0700"
  • %Z: time zone name, such as "UTC" or "GMT"

This is a wrapper for the github.com/itchyny/timefmt-go library.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	t, _ := synchro.Strptime[tz.AsiaTokyo]("2023-09-02 14:09:56", "%Y-%m-%d %H:%M:%S")
	fmt.Println(t)

	_, err := synchro.Strptime[tz.UTC]("invalid", "%Y")
	fmt.Println("error", err) // Returns an error as the layout is not a valid time value
}
Output:

2023-09-02 14:09:56 +0900 JST
error failed to parse "invalid" with "%Y": cannot parse %Y

func Unix

func Unix[T TimeZone](sec int64, nsec int64) Time[T]

Unix returns the local Time corresponding to the given Unix time, sec seconds and nsec nanoseconds since January 1, 1970 UTC. It is valid to pass nsec outside the range [0, 999999999]. Not all sec values have a corresponding time value. One such value is 1<<63-1 (the largest int64 value).

This is a simple wrapper function for time.Unix.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	unixTime := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	fmt.Println(unixTime.Unix())
	t := synchro.Unix[tz.UTC](unixTime.Unix(), 0)
	fmt.Println(t)

}
Output:

1257894000
2009-11-10 23:00:00 +0000 UTC

func UnixMicro

func UnixMicro[T TimeZone](usec int64) Time[T]

UnixMicro returns the local Time corresponding to the given Unix time, usec microseconds since January 1, 1970 UTC.

This is a simple wrapper function for time.UnixMicro.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	umt := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	fmt.Println(umt.UnixMicro())
	t := synchro.UnixMicro[tz.UTC](umt.UnixMicro())
	fmt.Println(t)

}
Output:

1257894000000000
2009-11-10 23:00:00 +0000 UTC

func UnixMilli

func UnixMilli[T TimeZone](msec int64) Time[T]

UnixMilli returns the local Time corresponding to the given Unix time, msec milliseconds since January 1, 1970 UTC.

This is a simple wrapper function for time.UnixMilli.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	umt := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	fmt.Println(umt.UnixMilli())
	t := synchro.UnixMilli[tz.UTC](umt.UnixMilli())
	fmt.Println(t)

}
Output:

1257894000000
2009-11-10 23:00:00 +0000 UTC

func (Time[T]) Add

func (t Time[T]) Add(d time.Duration) Time[T]

Add returns the time t+d.

This is a simple wrapper method for (time.Time{}).Add.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	start := synchro.New[tz.UTC](2009, 1, 1, 12, 0, 0, 0)
	afterTenSeconds := start.Add(time.Second * 10)
	afterTenMinutes := start.Add(time.Minute * 10)
	afterTenHours := start.Add(time.Hour * 10)
	afterTenDays := start.Add(time.Hour * 24 * 10)

	fmt.Printf("start = %v\n", start)
	fmt.Printf("start.Add(time.Second * 10) = %v\n", afterTenSeconds)
	fmt.Printf("start.Add(time.Minute * 10) = %v\n", afterTenMinutes)
	fmt.Printf("start.Add(time.Hour * 10) = %v\n", afterTenHours)
	fmt.Printf("start.Add(time.Hour * 24 * 10) = %v\n", afterTenDays)

}
Output:

start = 2009-01-01 12:00:00 +0000 UTC
start.Add(time.Second * 10) = 2009-01-01 12:00:10 +0000 UTC
start.Add(time.Minute * 10) = 2009-01-01 12:10:00 +0000 UTC
start.Add(time.Hour * 10) = 2009-01-01 22:00:00 +0000 UTC
start.Add(time.Hour * 24 * 10) = 2009-01-11 12:00:00 +0000 UTC

func (Time[T]) AddDate

func (t Time[T]) AddDate(years int, months int, days int) Time[T]

AddDate returns the time corresponding to adding the given number of years, months, and days to t.

This is a simple wrapper method for (time.Time{}).AddDate.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	start := synchro.New[tz.UTC](2009, 1, 1, 0, 0, 0, 0)
	oneDayLater := start.AddDate(0, 0, 1)
	oneMonthLater := start.AddDate(0, 1, 0)
	oneYearLater := start.AddDate(1, 0, 0)

	fmt.Printf("oneDayLater: start.AddDate(0, 0, 1) = %v\n", oneDayLater)
	fmt.Printf("oneMonthLater: start.AddDate(0, 1, 0) = %v\n", oneMonthLater)
	fmt.Printf("oneYearLater: start.AddDate(1, 0, 0) = %v\n", oneYearLater)

}
Output:

oneDayLater: start.AddDate(0, 0, 1) = 2009-01-02 00:00:00 +0000 UTC
oneMonthLater: start.AddDate(0, 1, 0) = 2009-02-01 00:00:00 +0000 UTC
oneYearLater: start.AddDate(1, 0, 0) = 2010-01-01 00:00:00 +0000 UTC

func (Time[T]) Advance added in v0.0.8

func (t Time[T]) Advance(u1 Unit, u2 ...Unit) Time[T]

Advance adjusts the time based on the provided unit values, moving it forward in time. u1 is a required unit, while u2... can be provided as additional optional units. This method returns a new Time[T] and does not modify the original. The time is adjusted in the order the units are provided.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

// shorthand way
type Y = synchro.Year
type M = synchro.Month
type D = synchro.Day
type HH = synchro.Hour
type MM = synchro.Minute
type SS = synchro.Second
type NS = synchro.Nanosecond

func main() {
	utc := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	c1 := utc.Advance(synchro.Year(1))
	c11 := utc.Advance(Y(1), Y(1)) // +2 years

	c2 := utc.Advance(Y(1), M(1))
	c3 := utc.Advance(Y(1), M(1), D(1))
	c4 := c3.Advance(HH(1))
	c5 := c3.Advance(HH(1), MM(1))
	c6 := c3.Advance(HH(1), MM(1), SS(1))
	c7 := c3.Advance(HH(1), MM(1), SS(1), NS(123456789))

	fmt.Printf("Go launched at %s\n", utc)
	fmt.Println(c1)
	fmt.Println(c11)
	fmt.Println()
	fmt.Println(c2)
	fmt.Println(c3)
	fmt.Println(c4)
	fmt.Println(c5)
	fmt.Println(c6)
	fmt.Println(c7)
}
Output:

Go launched at 2009-11-10 23:00:00 +0000 UTC
2010-11-10 23:00:00 +0000 UTC
2011-11-10 23:00:00 +0000 UTC

2010-12-10 23:00:00 +0000 UTC
2010-12-11 23:00:00 +0000 UTC
2010-12-12 00:00:00 +0000 UTC
2010-12-12 00:01:00 +0000 UTC
2010-12-12 00:01:01 +0000 UTC
2010-12-12 00:01:01.123456789 +0000 UTC

func (Time[T]) After

func (t Time[T]) After(u Time[T]) bool

After reports whether the time instant t is after u.

If you want to compare time.Time as a parameter, please use with the Time method.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	year2000 := synchro.New[tz.UTC](2000, 1, 1, 0, 0, 0, 0)
	year3000 := synchro.New[tz.UTC](3000, 1, 1, 0, 0, 0, 0)

	isYear3000AfterYear2000 := year3000.After(year2000) // True
	isYear2000AfterYear3000 := year2000.After(year3000) // False

	fmt.Printf("year3000.After(year2000) = %v\n", isYear3000AfterYear2000)
	fmt.Printf("year2000.After(year3000) = %v\n", isYear2000AfterYear3000)

}
Output:

year3000.After(year2000) = true
year2000.After(year3000) = false

func (Time[T]) AppendFormat

func (t Time[T]) AppendFormat(b []byte, layout string) []byte

AppendFormat is like Format but appends the textual representation to b and returns the extended buffer.

This is a simple wrapper method for (time.Time{}).AppendFormat.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	t := synchro.New[tz.UTC](2017, time.November, 4, 11, 0, 0, 0)
	text := []byte("Time: ")

	text = t.AppendFormat(text, time.Kitchen)
	fmt.Println(string(text))

}
Output:

Time: 11:00AM

func (Time[T]) Before

func (t Time[T]) Before(u Time[T]) bool

Before reports whether the time instant t is before u.

If you want to compare time.Time as a parameter, please use with the Time method.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	year2000 := synchro.New[tz.UTC](2000, 1, 1, 0, 0, 0, 0)
	year3000 := synchro.New[tz.UTC](3000, 1, 1, 0, 0, 0, 0)

	isYear2000BeforeYear3000 := year2000.Before(year3000) // True
	isYear3000BeforeYear2000 := year3000.Before(year2000) // False

	fmt.Printf("year2000.Before(year3000) = %v\n", isYear2000BeforeYear3000)
	fmt.Printf("year3000.Before(year2000) = %v\n", isYear3000BeforeYear2000)

}
Output:

year2000.Before(year3000) = true
year3000.Before(year2000) = false

func (Time[T]) Change added in v0.0.8

func (t Time[T]) Change(u1 Unit, u2 ...Unit) Time[T]

Change modifies the time based on the provided unit values. u1 is a required unit, while u2... can be provided as additional optional units. This method returns a new Time[T] and does not modify the original.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

// shorthand way
type Y = synchro.Year
type M = synchro.Month
type D = synchro.Day
type HH = synchro.Hour
type MM = synchro.Minute
type SS = synchro.Second
type NS = synchro.Nanosecond

func main() {
	utc := synchro.New[tz.UTC](2009, time.November, 10, 23, 0, 0, 0)
	c1 := utc.Change(synchro.Year(2010))
	c2 := utc.Change(synchro.Year(2010), synchro.Month(time.December))
	c3 := utc.Change(Y(2010), M(time.December), D(1))
	c4 := c3.Change(synchro.Hour(1))
	c5 := c3.Change(HH(1), MM(1))
	c6 := c3.Change(HH(1), MM(1), SS(1))
	c7 := c3.Change(HH(1), MM(1), SS(1), NS(123456789))
	fmt.Printf("Go launched at %s\n", utc)
	fmt.Println(c1)
	fmt.Println(c2)
	fmt.Println(c3)
	fmt.Println(c4)
	fmt.Println(c5)
	fmt.Println(c6)
	fmt.Println(c7)
}
Output:

Go launched at 2009-11-10 23:00:00 +0000 UTC
2010-11-10 23:00:00 +0000 UTC
2010-12-10 23:00:00 +0000 UTC
2010-12-01 23:00:00 +0000 UTC
2010-12-01 01:00:00 +0000 UTC
2010-12-01 01:01:00 +0000 UTC
2010-12-01 01:01:01 +0000 UTC
2010-12-01 01:01:01.123456789 +0000 UTC

func (Time[T]) Clock

func (t Time[T]) Clock() (hour, min, sec int)

Clock returns the hour, minute, and second within the day specified by t.

This is a simple wrapper method for (time.Time{}).Clock.

func (Time[T]) Compare

func (t Time[T]) Compare(u Time[T]) int

Compare compares the time instant t with u. If t is before u, it returns -1; if t is after u, it returns +1; if they're the same, it returns 0.

If you want to compare time.Time as a parameter, please use with the Time method.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	base := synchro.New[tz.UTC](2000, 1, 1, 1, 0, 0, 0)
	before := synchro.New[tz.UTC](2000, 1, 1, 0, 0, 0, 0)
	after := synchro.New[tz.UTC](3000, 1, 1, 2, 0, 0, 0)

	isSame := base.Compare(base)
	isAfter := base.Compare(after)
	isBefore := base.Compare(before)

	fmt.Printf("base.Compare(base) = %d\n", isSame)
	fmt.Printf("base.Compare(after) = %d\n", isAfter)
	fmt.Printf("base.Compare(before) = %d\n", isBefore)

}
Output:

base.Compare(base) = 0
base.Compare(after) = -1
base.Compare(before) = 1

func (Time[T]) Date

func (t Time[T]) Date() (year int, month time.Month, day int)

Date returns the year, month, and day in which t occurs.

This is a simple wrapper method for (time.Time{}).Date.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d := synchro.New[tz.UTC](2000, 2, 1, 12, 30, 0, 0)
	year, month, day := d.Date()

	fmt.Printf("year = %v\n", year)
	fmt.Printf("month = %v\n", month)
	fmt.Printf("day = %v\n", day)

}
Output:

year = 2000
month = February
day = 1

func (Time[T]) Day

func (t Time[T]) Day() int

Day returns the day of the month specified by t.

This is a simple wrapper method for (time.Time{}).Day.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d := synchro.New[tz.UTC](2000, 2, 1, 12, 30, 0, 0)
	day := d.Day()

	fmt.Printf("day = %v\n", day)

}
Output:

day = 1

func (Time[T]) DiffInCalendarDays added in v0.0.5

func (t Time[T]) DiffInCalendarDays(u Time[T]) int

DiffInCalendarDays calculates the difference in calendar days between t and u. (t-u) Calendar days are calculated by considering only the dates, excluding the times, and then determining the difference in days.

func (Time[T]) EndOfMonth

func (t Time[T]) EndOfMonth() Time[T]

EndOfMonth returns Time for end of the month.

func (Time[T]) EndOfQuarter

func (t Time[T]) EndOfQuarter() Time[T]

EndOfQuarter returns a Time for end of the quarter.

func (Time[T]) EndOfSemester

func (t Time[T]) EndOfSemester() Time[T]

EndOfSemester returns a Time for end of the semester.

func (Time[T]) EndOfWeek

func (t Time[T]) EndOfWeek() Time[T]

EndOfWeek returns Time for end of the week.

func (Time[T]) EndOfYear

func (t Time[T]) EndOfYear() Time[T]

EndOfYear returns Time for end of the year.

func (Time[T]) Equal

func (t Time[T]) Equal(u Time[T]) bool

Equal reports whether t and u represent the same time instant.

If you want to compare time.Time as a parameter, please use with the Time method.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	d1 := synchro.New[tz.UTC](2000, 2, 1, 12, 30, 0, 0)
	d2, _ := synchro.Parse[tz.UTC]("2006 Jan 02 15:04:05 (MST)", "2000 Feb 01 12:30:00 (JST)")

	datesEqualUsingEqualOperator := d1 == d2
	datesEqualUsingFunction := d1.Equal(d2)

	fmt.Printf("d1 = %q\n", d1)
	fmt.Printf("d2 = %q\n", d2)
	fmt.Printf("datesEqualUsingEqualOperator = %v\n", datesEqualUsingEqualOperator)
	fmt.Printf("datesEqualUsingFunction = %v\n", datesEqualUsingFunction)

}
Output:

d1 = "2000-02-01 12:30:00 +0000 UTC"
d2 = "2000-02-01 12:30:00 +0000 UTC"
datesEqualUsingEqualOperator = true
datesEqualUsingFunction = true

func (Time[T]) Format

func (t Time[T]) Format(layout string) string

Format returns a textual representation of the time value formatted according to the layout defined by the argument.

This is a simple wrapper method for (time.Time{}).Format.

func (Time[T]) GoString

func (t Time[T]) GoString() string

GoString implements fmt.GoStringer and formats t to be printed in Go source code.

This is a simple wrapper method for (time.Time{}).GoString.

func (*Time[T]) GobDecode

func (t *Time[T]) GobDecode(data []byte) error

GobDecode implements the gob.GobDecoder interface.

This is a simple wrapper method for (time.Time{}).GobDecode.

func (Time[T]) GobEncode

func (t Time[T]) GobEncode() ([]byte, error)

GobEncode implements the gob.GobEncoder interface.

This is a simple wrapper method for (time.Time{}).GobEncode.

func (Time[T]) Hour

func (t Time[T]) Hour() int

Hour returns the hour within the day specified by t, in the range [0, 23].

This is a simple wrapper method for (time.Time{}).Hour.

func (Time[T]) ISOWeek

func (t Time[T]) ISOWeek() (year, week int)

ISOWeek returns the ISO 8601 year and week number in which t occurs.

This is a simple wrapper method for (time.Time{}).ISOWeek.

func (Time[T]) IsBetween

func (t Time[T]) IsBetween(from Time[T], to Time[T]) bool

IsBetween returns true if from < t && t < to.

func (Time[T]) IsDST

func (t Time[T]) IsDST() bool

IsDST reports whether the time in the configured location is in Daylight Savings Time.

This is a simple wrapper method for (time.Time{}).IsDST.

func (Time[T]) IsLeapYear

func (t Time[T]) IsLeapYear() bool

IsLeapYear returns true if t is leap year.

func (Time[T]) IsZero

func (t Time[T]) IsZero() bool

IsZero reports whether t represents the zero time instant, January 1, year 1, 00:00:00 UTC.

This is a simple wrapper method for (time.Time{}).IsZero.

func (Time[T]) Local

func (t Time[T]) Local() Time[tz.Local]

Local returns t with the location set to local time.

func (Time[T]) Location

func (t Time[T]) Location() *time.Location

Location returns the time zone information associated with t.

This is a simple wrapper method for (time.Time{}).Location.

func (Time[T]) MarshalBinary

func (t Time[T]) MarshalBinary() ([]byte, error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

This is a simple wrapper method for (time.Time{}).MarshalBinary.

func (Time[T]) MarshalJSON

func (t Time[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface. The time is a quoted string in the RFC 3339 format with sub-second precision. If the timestamp cannot be represented as valid RFC 3339 (e.g., the year is out of range), then an error is reported.

This is a simple wrapper method for (time.Time{}).MarshalJSON.

func (Time[T]) MarshalText

func (t Time[T]) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface. The time is formatted in RFC 3339 format with sub-second precision. If the timestamp cannot be represented as valid RFC 3339 (e.g., the year is out of range), then an error is reported.

This is a simple wrapper method for (time.Time{}).MarshalText.

func (Time[T]) Minute

func (t Time[T]) Minute() int

Minute returns the minute offset within the hour specified by t, in the range [0, 59].

This is a simple wrapper method for (time.Time{}).Minute.

func (Time[T]) Month

func (t Time[T]) Month() time.Month

Month returns the month of the year specified by t.

This is a simple wrapper method for (time.Time{}).Month.

func (Time[T]) Nanosecond

func (t Time[T]) Nanosecond() int

Nanosecond returns the nanosecond offset within the second specified by t, in the range [0, 999999999].

This is a simple wrapper method for (time.Time{}).Nanosecond.

func (Time[T]) Quarter

func (t Time[T]) Quarter() Quarter[T]

Quarter gets current quarter.

func (Time[T]) Round

func (t Time[T]) Round(d time.Duration) Time[T]

Round returns the result of rounding t to the nearest multiple of d (since the zero time). The rounding behavior for halfway values is to round up. If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged.

This is a simple wrapper method for (time.Time{}).Round.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	t := synchro.New[tz.UTC](0, 0, 0, 12, 15, 30, 918273645)
	round := []time.Duration{
		time.Nanosecond,
		time.Microsecond,
		time.Millisecond,
		time.Second,
		2 * time.Second,
		time.Minute,
		10 * time.Minute,
		time.Hour,
	}

	for _, d := range round {
		fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
	}
}
Output:

t.Round(   1ns) = 12:15:30.918273645
t.Round(   1µs) = 12:15:30.918274
t.Round(   1ms) = 12:15:30.918
t.Round(    1s) = 12:15:31
t.Round(    2s) = 12:15:30
t.Round(  1m0s) = 12:16:00
t.Round( 10m0s) = 12:20:00
t.Round(1h0m0s) = 12:00:00

func (*Time[T]) Scan added in v0.0.4

func (t *Time[T]) Scan(src any) error

Scan implements the sql.Scanner interface.

func (Time[T]) Second

func (t Time[T]) Second() int

Second returns the second offset within the minute specified by t, in the range [0, 59].

This is a simple wrapper method for (time.Time{}).Second.

func (Time[T]) Semester

func (t Time[T]) Semester() Semester[T]

Semester gets current semester.

func (Time[T]) StartOfMonth

func (t Time[T]) StartOfMonth() Time[T]

StartOfMonth returns Time for start of the month.

func (Time[T]) StartOfQuarter

func (t Time[T]) StartOfQuarter() Time[T]

StartOfQuarter returns a Time for start of the quarter.

func (Time[T]) StartOfSemester

func (t Time[T]) StartOfSemester() Time[T]

StartOfSemester returns a Time for start of the semester.

func (Time[T]) StartOfWeek

func (t Time[T]) StartOfWeek() Time[T]

StartOfWeek returns Time for start of the week.

func (Time[T]) StartOfYear

func (t Time[T]) StartOfYear() Time[T]

StartOfYear returns Time for start of the year.

func (Time[T]) StdTime

func (t Time[T]) StdTime() time.Time

StdTime returns the time.Time.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	want := time.Date(2023, 9, 2, 14, 0, 0, 0, time.UTC)
	got1 := synchro.In[tz.UTC](want).StdTime()
	got2 := synchro.In[tz.AsiaTokyo](want).StdTime()
	fmt.Println(want.Equal(got1))
	fmt.Println(want.Equal(got2))
}
Output:

true
true

func (Time[T]) Strftime added in v0.5.0

func (t Time[T]) Strftime(format string) string

Strftime formats the time according to the given format string.

This method is a wrapper for the github.com/itchyny/timefmt-go library.

Example:

  • %Y-%m-%d %H:%M:%S => 2023-09-02 14:09:56
  • %a, %d %b %Y %T %z => Sat, 02 Sep 2023 14:09:56 +0900

The format string should follow the format of strftime(3) in man pages. The following list shows the supported format specifiers:

  • %a: Abbreviated weekday name (Sun)
  • %A: Full weekday name (Sunday)
  • %b: Abbreviated month name (Jan)
  • %B: Full month name (January)
  • %c: Date and time representation
  • %C: Year divided by 100 (00-99)
  • %d: Day of the month (01-31)
  • %D: Short MM/DD/YY date, equivalent to %m/%d/%y
  • %e: Day of the month, with a space preceding single digits ( 1-31)
  • %F: Equivalent to %Y-%m-%d (the ISO 8601 date format)
  • %g: Week-based year, last two digits (00-99)
  • %G: Week-based year
  • %h: Abbreviated month name (Jan)
  • %H: Hour in 24h format (00-23)
  • %I: Hour in 12h format (01-12)
  • %j: Day of the year (001-366)
  • %m: Month as a decimal number (01-12)
  • %M: Minute (00-59)
  • %n: New-line character
  • %p: AM or PM designation
  • %P: am or pm designation
  • %r: 12-hour clock time
  • %R: 24-hour HH:MM time, equivalent to %H:%M
  • %S: Second (00-59)
  • %t: Horizontal-tab character
  • %T: 24-hour clock time, equivalent to %H:%M:%S
  • %u: ISO 8601 weekday as number with Monday as 1 (1-7)
  • %U: Week number with the first Sunday as the first day of week (00-53)
  • %V: ISO 8601 week number (01-53)
  • %w: Weekday as a decimal number with Sunday as 0 (0-6)
  • %W: Week number with the first Monday as the first day of week (00-53)
  • %x: Date representation
  • %X: Time representation
  • %y: Year, last two digits (00-99)
  • %Y: Year
  • %z: ISO 8601 offset from UTC in timezone (+HHMM)
  • %Z: Timezone name or abbreviation
  • %+: Extended date and time representation
  • %::z: Colon-separated offset from UTC in timezone (e.g. +05:00)
  • %:::z: Like %::z, but with optional seconds
Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	t := synchro.New[tz.AsiaTokyo](2023, 9, 2, 14, 9, 56, 0)
	fmt.Println(t.Strftime("%Y-%m-%d %H:%M:%S"))
	fmt.Println(t.Strftime("%a, %d %b %Y %T %z"))
}
Output:

2023-09-02 14:09:56
Sat, 02 Sep 2023 14:09:56 +0900

func (Time[T]) String

func (t Time[T]) String() string

String returns the time formatted using the format string

"2006-01-02 15:04:05.999999999 -0700 MST"

If the time has a monotonic clock reading, the returned string includes a final field "m=±<value>", where value is the monotonic clock reading formatted as a decimal number of seconds.

This is a simple wrapper method for (time.Time{}).String.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	timeWithNanoseconds := synchro.New[tz.UTC](2000, 2, 1, 12, 13, 14, 15)
	withNanoseconds := timeWithNanoseconds.String()

	timeWithoutNanoseconds := synchro.New[tz.UTC](2000, 2, 1, 12, 13, 14, 0)
	withoutNanoseconds := timeWithoutNanoseconds.String()

	fmt.Printf("withNanoseconds = %v\n", string(withNanoseconds))
	fmt.Printf("withoutNanoseconds = %v\n", string(withoutNanoseconds))

}
Output:

withNanoseconds = 2000-02-01 12:13:14.000000015 +0000 UTC
withoutNanoseconds = 2000-02-01 12:13:14 +0000 UTC

func (Time[T]) Sub

func (t Time[T]) Sub(u Time[T]) time.Duration

Sub returns the duration t-u. If the result exceeds the maximum (or minimum) value that can be stored in a Duration, the maximum (or minimum) duration will be returned. To compute t-d for a duration d, use t.Add(-d).

This is a simple wrapper method for (time.Time{}).Sub.

Example
package main

import (
	"fmt"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	start := synchro.New[tz.UTC](2000, 1, 1, 0, 0, 0, 0)
	end := synchro.New[tz.UTC](2000, 1, 1, 12, 0, 0, 0)

	difference := end.Sub(start)
	fmt.Printf("difference = %v\n", difference)

}
Output:

difference = 12h0m0s

func (Time[T]) Truncate

func (t Time[T]) Truncate(d time.Duration) Time[T]

Truncate returns the result of rounding t down to a multiple of d (since the zero time). If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged.

This is a simple wrapper method for (time.Time{}).Truncate.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func init() {
	synchro.SetNow(func() time.Time {
		return time.Date(2023, 9, 2, 14, 0, 0, 0, time.UTC)
	})
}

func main() {
	t, _ := synchro.Parse[tz.UTC]("2006 Jan 02 15:04:05", "2012 Dec 07 12:15:30.918273645")
	trunc := []time.Duration{
		time.Nanosecond,
		time.Microsecond,
		time.Millisecond,
		time.Second,
		2 * time.Second,
		time.Minute,
		10 * time.Minute,
	}

	for _, d := range trunc {
		fmt.Printf("t.Truncate(%5s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))
	}
	// To round to the last midnight in the local timezone, create a new Date.
	midnight := synchro.New[tz.UTC](t.Year(), t.Month(), t.Day(), 0, 0, 0, 0)
	_ = midnight

}
Output:

t.Truncate(  1ns) = 12:15:30.918273645
t.Truncate(  1µs) = 12:15:30.918273
t.Truncate(  1ms) = 12:15:30.918
t.Truncate(   1s) = 12:15:30
t.Truncate(   2s) = 12:15:30
t.Truncate( 1m0s) = 12:15:00
t.Truncate(10m0s) = 12:10:00

func (Time[T]) Unix

func (t Time[T]) Unix() int64

Unix returns t as a Unix time, the number of seconds elapsed since January 1, 1970 UTC. The result does not depend on the location associated with t. Unix-like operating systems often record time as a 32-bit count of seconds, but since the method here returns a 64-bit value it is valid for billions of years into the past or future.

This is a simple wrapper method for (time.Time{}).Unix.

Example
package main

import (
	"fmt"
	"time"

	"github.com/Code-Hex/synchro"
	"github.com/Code-Hex/synchro/tz"
)

func main() {
	// 1 billion seconds of Unix, three ways.
	fmt.Println(synchro.Unix[tz.UTC](1e9, 0))     // 1e9 seconds
	fmt.Println(synchro.Unix[tz.UTC](0, 1e18))    // 1e18 nanoseconds
	fmt.Println(synchro.Unix[tz.UTC](2e9, -1e18)) // 2e9 seconds - 1e18 nanoseconds

	t := synchro.New[tz.UTC](2001, time.September, 9, 1, 46, 40, 0)
	fmt.Println(t.Unix())     // seconds since 1970
	fmt.Println(t.UnixNano()) // nanoseconds since 1970

}
Output:

2001-09-09 01:46:40 +0000 UTC
2001-09-09 01:46:40 +0000 UTC
2001-09-09 01:46:40 +0000 UTC
1000000000
1000000000000000000

func (Time[T]) UnixMicro

func (t Time[T]) UnixMicro() int64

UnixMicro returns t as a Unix time, the number of microseconds elapsed since January 1, 1970 UTC. The result is undefined if the Unix time in microseconds cannot be represented by an int64 (a date before year -290307 or after year 294246). The result does not depend on the location associated with t.

This is a simple wrapper method for (time.Time{}).UnixMicro.

func (Time[T]) UnixMilli

func (t Time[T]) UnixMilli() int64

UnixMilli returns t as a Unix time, the number of milliseconds elapsed since January 1, 1970 UTC. The result is undefined if the Unix time in milliseconds cannot be represented by an int64 (a date more than 292 million years before or after 1970). The result does not depend on the location associated with t.

This is a simple wrapper method for (time.Time{}).UnixMilli.

func (Time[T]) UnixNano

func (t Time[T]) UnixNano() int64

UnixNano returns t as a Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC. The result is undefined if the Unix time in nanoseconds cannot be represented by an int64 (a date before the year 1678 or after 2262). Note that this means the result of calling UnixNano on the zero Time is undefined. The result does not depend on the location associated with t.

This is a simple wrapper method for (time.Time{}).UnixNano.

func (*Time[T]) UnmarshalBinary

func (t *Time[T]) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.

This is a simple wrapper method for (time.Time{}).UnmarshalBinary.

func (*Time[T]) UnmarshalJSON

func (t *Time[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface. The time must be a quoted string in the RFC 3339 format.

This is a simple wrapper method for (time.Time{}).UnmarshalJSON.

func (*Time[T]) UnmarshalText

func (t *Time[T]) UnmarshalText(data []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The time must be in the RFC 3339 format.

This is a simple wrapper method for (time.Time{}).MarshalText.

func (Time[T]) Value added in v0.0.4

func (t Time[T]) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

func (Time[T]) Weekday

func (t Time[T]) Weekday() time.Weekday

Weekday returns the day of the week specified by t.

This is a simple wrapper method for (time.Time{}).Weekday.

func (Time[T]) Year

func (t Time[T]) Year() int

Year returns the year in which t occurs.

This is a simple wrapper method for (time.Time{}).Year.

func (Time[T]) YearDay

func (t Time[T]) YearDay() int

YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years, and [1,366] in leap years.

This is a simple wrapper method for (time.Time{}).YearDay.

func (Time[T]) Zone

func (t Time[T]) Zone() (name string, offset int)

Zone computes the time zone in effect at time t, returning the abbreviated name of the zone (such as "CET") and its offset in seconds east of UTC.

This is a simple wrapper method for (time.Time{}).Zone.

func (Time[T]) ZoneBounds

func (t Time[T]) ZoneBounds() (start, end Time[T])

ZoneBounds returns the bounds of the time zone in effect at time t. The zone begins at start and the next zone begins at end. If the zone begins at the beginning of time, start will be returned as a zero Time. If the zone goes on forever, end will be returned as a zero Time. The Location of the returned times will be the same as t.

This is a simple wrapper method for (time.Time{}).ZoneBounds.

type TimeZone

type TimeZone interface {
	Location() *time.Location
}

TimeZone represents the timezone.

type Unit added in v0.4.0

type Unit interface {
	// contains filtered or unexported methods
}

Unit is a component of the time being built.

type Year added in v0.0.9

type Year int

Year sets the year component of the time being built.

Directories

Path Synopsis
internal
scripts
Package tz provides timezone related types.
Package tz provides timezone related types.

Jump to

Keyboard shortcuts

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