Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
4322d27
Just refactoring to make the fork easier to work with.
Nov 23, 2015
8792f00
Added ability for formatting a conventional suffix on the day number,…
Nov 24, 2015
fbae161
Generalised FormatWithSuffixes to remove the unsupported case and joi…
Nov 24, 2015
dc16359
Added new test for Date.String(). Started work on DateRange.
Nov 25, 2015
8e2524c
ShiftBy implemented
Nov 26, 2015
a4c508a
Contains implemented.
Nov 26, 2015
4ac7702
Implemented ContainsTime, with StartUTC and EndUTC.
Nov 26, 2015
4dfa4ea
Implemented Merge.
Nov 26, 2015
53ced14
package renamed to timespan
Nov 26, 2015
505aff1
Revised the behaviour of EndUTC. Added StartTimeIn, EndTimeIn, Durati…
Nov 26, 2015
5051d00
DateRange is now mark+days. Brought in TimeSpan, which is also Mark+D…
Nov 27, 2015
821c807
TimeSpan fields are now not exported to allow for future change if re…
Nov 27, 2015
c6bf3e7
Date internal type uses Days now.
Nov 27, 2015
6198946
Date implementation is now a type derived from a primitive type (actu…
Nov 28, 2015
9b0baff
Reverted the structure of Date; zero value is normal automatic expres…
Nov 30, 2015
1856266
Sharply improved performance of Date.ParseISO - achieved by not using…
Nov 30, 2015
02c080d
Augmented the README.
Nov 30, 2015
6dd81cc
Reformatted by go-fmt. Not sure why IntelliJ mis-formats.
Nov 30, 2015
a36e621
Date now has Min and Max. DateRange Merge is now much simpler as a co…
Dec 1, 2015
cf53073
Commented out some non-functioning travis settings
Dec 3, 2015
08f1831
Travis only reporting coverage for top-level package
Dec 3, 2015
c9f0d50
Added new Clock type to support clock-face operations.
Dec 3, 2015
6406c10
Improved documentation and go-fmt.
Dec 4, 2015
eab529d
Clock now has its own package.
Dec 4, 2015
5dda47e
Renamed ParseClock -> Parse
Dec 4, 2015
33f7797
Added Clock.IsMidnight and improved some tests; bug fixed in Mod24.
Dec 4, 2015
2b2c3c3
Changed Clock resolution from int64 to int32, this being a more natur…
Dec 4, 2015
552f750
Added IsLeap and DaysIn functions for general-purpose date handling.
Dec 6, 2015
8550750
LastDayOfMonth added
Dec 6, 2015
be2d89a
Added MustParseXxx methods - mostly to simplify startup and test code.
Dec 19, 2015
6e2eda7
New date.AutoParse function; new tool for viewing dates/clocks as num…
Dec 29, 2015
139383e
Added direct access methods NewOfDays and DaysSinceEpoch
Dec 29, 2015
9cc3fbd
Improved documentation; new MustAutoParse function.
Dec 29, 2015
aa417a9
Comments
Dec 30, 2015
31c200e
Added Undefined constant and revised the documentation
Jan 3, 2016
c8a42df
Added parsing for am/pm times
Jan 3, 2016
8fb35ed
Added formatting methods for am/pm times
Jan 3, 2016
60a8326
Better documentation
Jan 3, 2016
559ebed
Some minor internal refactoring
Jan 4, 2016
d716302
New constants: Midnight, Noon
Jan 4, 2016
a00101d
Renamed constants
Jan 4, 2016
7e0c2e1
Renamed constants
Jan 4, 2016
8978bef
Bug fix - using "Monday" in a format string clashed with "2nd"
Jan 14, 2016
943b432
New view package for fluent formatting of dates.
Jan 14, 2016
00b595c
Revised to removed incorrect dependencies. Improved the API and docum…
Jan 14, 2016
0177733
Added lossy support for marshalling (a.k.a. marshaling) for JSON and …
Jan 15, 2016
2408229
DateRange - added EmptyRange and IsZero; deprecated ZeroRange
Jan 26, 2016
e34666d
DateRange.Merge now excludes zero-valued ranges as a special case.
Jan 26, 2016
f30c14d
New Period type represents ISO-8601 periods such as P2Y3M
Feb 2, 2016
55b6134
Added support for JSON marshalling of Period
Feb 2, 2016
1176065
Moved Period to sub-package to reduce API clutter. Added string forma…
Feb 6, 2016
b651586
Finished the binary encoding/decoding. Obsolete encoders/decoders wer…
Feb 6, 2016
b74feb2
Documentation
Feb 6, 2016
67f9383
Documentation
Feb 6, 2016
8836972
Period now supports time-based and day-based components, i.e. the com…
Feb 6, 2016
8b5c29d
Period now has Add and Scale methods
Feb 6, 2016
058f15c
Split source code across several files
Feb 6, 2016
5beca00
More conversion and interfacing methods
Feb 6, 2016
ce7b491
Documentation
Feb 6, 2016
701aea3
Period has new Normalise and TotalDaysApprox methods
Feb 6, 2016
659d28c
Added TotalMonthsApprox method
Feb 13, 2016
920c604
Added NewOf(Duration) method to allow easier construction from the ti…
Apr 11, 2016
fa25087
Added Between function to calculate the difference between two time.T…
Apr 11, 2016
5f24135
Formatting time now follows the special-case convention that midnight…
Apr 21, 2016
f56ed50
Added ModSubtract method
Dec 6, 2016
c769905
Date now implements Scanner and Valuer interfaces to allow direct sto…
May 20, 2017
52be6ff
SQL serialisation extended to allow string and []byte values.
May 21, 2017
7566b02
Fixed the build scripts
Jun 8, 2017
a6d27bd
Preparation for v1
Aug 21, 2017
16ffe3a
minor
Aug 21, 2017
3861b51
Fixed minor doc issues etc; removed an item that was to be deleted ea…
Aug 21, 2017
6c2251f
switched from glock to dep; removed gomock
Aug 23, 2017
ca6968f
docs
Aug 26, 2017
511bb2b
Added several new methods to VDate: IsYesterday, IsToday, IsTomorrow,…
Aug 31, 2017
6a81950
Reduced the number of lint warnings
Sep 22, 2017
65dd7e6
Reduced the number of lint warnings again
Sep 22, 2017
4db6498
tweaked the build script
Dec 29, 2017
e165556
Bug fixed in Scan method - now handles nil correctly
Jan 16, 2018
bcf2cbc
New IsOdd method added to VDate
Feb 19, 2018
b004bed
Documentation updates
Jul 17, 2018
a2b74d5
Added TimeSpan.Format and MarshalText methods, compatible with RFC5545.
Jul 17, 2018
2f7dc21
Enhanced timespan Format method to give more configuration options.
Jul 17, 2018
28d9e9f
Added timespan.ParseRFC5545InLocation function
Jul 17, 2018
a1faafb
Added functions & methods to timespan: TimeSpanOf, Equal, Format, For…
rickb777 Jul 18, 2018
de3500f
Upgraded to plural v1.2.0. Added more tests/test cases.
rickb777 Jul 18, 2018
faad512
Added more tests/test cases.
rickb777 Jul 18, 2018
b628975
Correction for RFC5545 - always output in zulu time.
rickb777 Jul 18, 2018
891e142
Revised Period to handle hudredth of a second better; added WeeksFloa…
Jul 24, 2018
22a539e
Improved NewOf function, plus a few other minor tweaks
Jul 25, 2018
7269504
Further work done on Between and DaysBetween
Jul 25, 2018
0447a7c
Between method now works in a wide range of use-cases (DaysBetween me…
Jul 27, 2018
33e1bef
Minor simplification & documentation; uncovered some shortcomings in …
Jul 27, 2018
3e38f12
Period: fixed Scale issue - now using Duration to handle reductions. …
Jul 28, 2018
062bfeb
Fixed bug: Period.IsNegative
Jul 28, 2018
041306e
Fixed bug: Period.Normalise edge cases
Jul 29, 2018
eae0545
Clarified VDate.String zero-value case is now blank
Aug 23, 2018
6bcbdd5
this package is now a go module
rickb777 Sep 2, 2018
ee30139
Removed a rogue fmt.Printf
rickb777 Sep 10, 2018
f815151
Added implementation for the following interfaces: encoding.BinaryMar…
avalchev94 Sep 18, 2018
3cbe88b
Merge pull request #1 from avalchev94/master
rickb777 Sep 20, 2018
9f6145f
Improved error reporting in period.Parse. Added more documentation.
Sep 20, 2018
8571bfe
documentation
Sep 20, 2018
9fcad74
comments & test cases
Oct 5, 2018
93168f6
more comments
Nov 15, 2018
5959d0b
Augmented Period with AddTo(time) method. Added Period.IsPositive and…
Nov 27, 2018
75ffca5
Bug fixed in Period.AddTo calculation: a more accurate solution is po…
Nov 27, 2018
5d32ee7
Much improved 'datetool'
rickb777 Mar 20, 2019
338cbdf
correction
rickb777 Mar 20, 2019
6d588f0
datetool now shows day-of-week name
rickb777 Apr 2, 2019
64df880
experimental ValueConverter implementation
rickb777 Apr 24, 2019
6062b86
Increased the bit size from 16 to 32 when parsing Period strings to a…
capnspacehook Apr 25, 2019
bd8f90e
new DateString variant of Date allows DB storage using TEXT or DATE c…
rickb777 Apr 25, 2019
a337401
Merge pull request #2 from capnspacehook/master
rickb777 Apr 25, 2019
a4bb3f7
parsing now uses 64-bit arithmetic for its calculations, allowing the…
rickb777 Apr 27, 2019
9434d2c
DateString now implements binary & text marshalling interfaces, so is…
rickb777 May 13, 2019
ccd9db0
extra test case added to date.Parse; added 'go vet' and 'goreturns'
rickb777 Jun 5, 2019
4da884b
withdrawn shadowing checks
rickb777 Jun 5, 2019
2dd7d2b
added extra documentation and some test cases
rickb777 Jun 16, 2019
cc56534
address build failure
rickb777 Jun 16, 2019
1c9d14b
typos
rickb777 Jun 17, 2019
036c37a
Bug #4 fixed: AutoParse now checks for the string being blank (after …
rickb777 Jul 12, 2019
7995dd9
build settings
rickb777 Sep 18, 2019
e1afd88
script alterations
rickb777 Sep 18, 2019
2248ec4
Period: some improved documentation and a tweak of month calculations
rickb777 Apr 4, 2020
31e2dc8
Period parsing ensure consumption of all components.
magodo Apr 21, 2020
6300e54
Merge pull request #8 from magodo/period_ensure_consumption
rickb777 Apr 22, 2020
be16c32
updated dependencies
May 13, 2020
7c75e70
feat: add period.ParseWithNormalise
ali-ince Jun 16, 2020
a947217
Merge pull request #9 from ali-ince/feat-add-parse-with-normalise
rickb777 Jul 13, 2020
e076f69
restored earlier test to ensure full coverage
rickb777 Jul 13, 2020
921b670
switched test to use Gomega
rickb777 Jul 13, 2020
8f09712
documentation additions
rickb777 Aug 17, 2020
6b66972
updated dependencies; now using go 1.15
rickb777 Aug 17, 2020
19cdf33
period: upgraded tests to Gomega
rickb777 Aug 19, 2020
afa19e5
disabled goveralls to investigate failures
rickb777 Aug 19, 2020
e01682b
travis now using go 1.15
rickb777 Aug 19, 2020
55c00f5
Period.String() now uses internal period64 helper type; some altered …
rickb777 Aug 19, 2020
91ffaa5
Period Parse and ScaleWithOverflowCheck now use internal period64 hel…
rickb777 Aug 19, 2020
ea239e1
Period code restructured into more files
rickb777 Sep 4, 2020
d2bc4af
Period parsing improved; extra tests added
rickb777 Sep 4, 2020
f8d6535
Period.Between bug fixed: when times need reversing and there is a da…
rickb777 Sep 4, 2020
3b91071
Period.Normalise simplified considerably: now always using 64-bit ari…
rickb777 Sep 4, 2020
0262965
Period tests - further improvements
rickb777 Sep 4, 2020
075a087
new Period Simplify method
rickb777 Sep 5, 2020
c7dda92
Period tests
rickb777 Sep 8, 2020
9c56d1a
updated dependencies
rickb777 Oct 7, 2020
0bcc9fd
godoc link changed
rickb777 Oct 8, 2020
28753ad
demostrated problem mentioned in issue 11 https://github.com/rickb777…
rickb777 Oct 13, 2020
21bcac5
fixed int32 overflow problem mentioned in issue 11 https://github.com…
rickb777 Oct 13, 2020
df05203
Add flag methods to Period
tamalsaha Oct 21, 2020
24acb1e
Merge pull request #13 from gomodules/flag
rickb777 Oct 28, 2020
0bd1a9f
updated dependencies
rickb777 Nov 2, 2020
15a0c2a
added SQL support for Period type, i.e. Scanner and Valuer
rickb777 Dec 11, 2020
80b1a03
comments etc
rickb777 Dec 11, 2020
e9e3f8d
sql Scan now disables normalisation, assuming that the retrieved valu…
rickb777 Dec 16, 2020
5225eda
marshaling also disables normalisation, assuming that the retrieved v…
rickb777 Dec 16, 2020
ae06fa1
updated dependencies
rickb777 Dec 17, 2020
5df9e8c
updated dependencies
rickb777 Feb 15, 2021
2e89fc3
upgrade to Go 1.17
rickb777 Sep 11, 2021
59eb296
Date JSON marshalling/unmarshalling tweaked so that the zero value ca…
rickb777 Dec 17, 2021
126ffe0
Updated dependencies. Began work on forked repo for `period`.
rickb777 Feb 2, 2022
c32516f
Bugfix: Date.MarshalJSON incorrectly wrote the zero value as a blank …
rickb777 May 12, 2022
754e690
Documentation improvements & tests tweaked
rickb777 Aug 2, 2022
168141b
Updated dependencies & re-fmt
rickb777 Nov 4, 2022
fba60ed
bumped up some dependencies
rickb777 Jul 5, 2023
a792460
Bugfix: this resolves issue #19 fraction designator parsing bug
Sep 19, 2023
ad3aa70
Dependencies updated
Sep 19, 2023
b6690e4
period.AddTo revised to reduce the impact of subtle behaviours of tim…
Sep 19, 2023
ff580cf
more tests added to period.Between
Sep 19, 2023
02b87e1
another parse test case
Sep 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
*.so

# Folders
_obj
_test
.idea/
_obj/
_test/
reports/
vendor/

# Architecture specific extensions/prefixes
*.[568vq]
Expand All @@ -22,3 +25,4 @@ _testmain.go
*.exe
*.test
*.prof
*.out
9 changes: 3 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
language: go

go:
- tip
- '1.17'

install:
- go get -t -v ./...
- go get github.com/mattn/goveralls

script:
- go test -v -covermode=count -coverprofile=coverage.out ./...
- go tool cover -func=coverage.out
- $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN
- ./build+test.sh amd64
- ./build+test.sh 386

env:
secure: "kcksCWXVeZKmFUWcyi2S/j87iwUmXMxZXxA2DG9ymc11QP43QoPNSG9pBjA/DDjvzt4WdKIFphTrxVfvawii/9j3oXA1aPmAcHGu87i4iOVg4IIZ4bPZLfUo0e7s6XP5FakzegYvPP6HWV5Xr5h+Q6osrjq3czOnPY+rVII6MRrxXMOfsqo8HEER+YIOOD6vj5LV2/quY8d0XHtThqgGvQ1cz4OB3vbd4KFBl48kmfXKefTrRG1NoqoQMMpwUVzU395JIEAg1eWbGkquhWU5v13gRwk3VMVWF75jZna8TSiqWha0P5iQdaED30kNCz3poIaBI1MLdxktJxwUQJZ5AaYIMCxh7ZCiW0FXTYCRu3EoeYusTPMLqy1ghK+gIlA46sNd26cKk5/OngXRrHo/J0aF5NWjydlk5FLHfKm9ih/Y426M9nV2zYNQAcVKgO8zVNb2IkJ3e7aTB2NH4DpkvjSV4D4hlnmW9xxmo14TKF+gXJ9Hw9ssKbigRHoL6S92aQHcpkdjGGnI5YSTy1fZh/nIE3HDmx+hcK4/ZtPHj9KnXopKYxBGyNswN5Eko+q6h3BB/Q7LwALtEexdDbznwsRmcZXJsOU4chvcjAKgIAi6cbeTwq8kG5E/w8TTY2wGeRm2ZFysQu6Jf8hgTZDQTV343RG80STWeUbiD0o7/WY="
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2015 The Go Authors. All rights reserved.
Copyright (c) 2015 The Go Authors & Rick Beton. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
Expand All @@ -24,4 +24,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
# date

[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://godoc.org/github.com/fxtlabs/date)
[![Build Status](https://api.travis-ci.org/fxtlabs/date.svg?branch=master)](https://travis-ci.org/fxtlabs/date)
[![Coverage Status](https://coveralls.io/repos/fxtlabs/date/badge.svg?branch=master&service=github)](https://coveralls.io/github/fxtlabs/date?branch=master)
[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg)](https://pkg.go.dev/github.com/rickb777/date)
[![Build Status](https://api.travis-ci.org/rickb777/date.svg?branch=master)](https://travis-ci.org/rickb777/date/builds)
[![Coverage Status](https://coveralls.io/repos/rickb777/date/badge.svg?branch=master&service=github)](https://coveralls.io/github/rickb777/date?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/rickb777/date)](https://goreportcard.com/report/github.com/rickb777/date)
[![Issues](https://img.shields.io/github/issues/rickb777/date.svg)](https://github.com/rickb777/date/issues)

Package `date` provides functionality for working with dates.

This package introduces a light-weight `Date` type that is storage-efficient
and covenient for calendrical calculations and date parsing and formatting
and convenient for calendrical calculations and date parsing and formatting
(including years outside the [0,9999] interval).

See [package documentation](https://godoc.org/github.com/fxtlabs/date) for
It also provides

* `clock.Clock` which expresses a wall-clock style hours-minutes-seconds with millisecond precision.
* `period.Period` which expresses a period corresponding to the ISO-8601 form (e.g. "PT30S").
* `timespan.DateRange` which expresses a period between two dates.
* `timespan.TimeSpan` which expresses a duration of time between two instants.
* `view.VDate` which wraps `Date` for use in templates etc.

See [package documentation](https://godoc.org/github.com/rickb777/date) for
full documentation and examples.

## Installation

go get -u github.com/fxtlabs/date
go get -u github.com/rickb777/date

or

dep ensure -add github.com/rickb777/date

## Status

This library has been in reliable production use for some time. Versioning follows the well-known semantic version pattern.

## Credits

Expand All @@ -25,3 +43,5 @@ many of the `Date` methods are implemented using the corresponding methods
of the `time.Time` type and much of the documentation is copied directly
from that package.

The original [Good Work](https://github.com/fxtlabs/date) on which this was
based was done by Filippo Tampieri at Fxtlabs.
46 changes: 46 additions & 0 deletions build+test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash -e
cd "$(dirname $0)"
PATH=$HOME/go/bin:$PATH
unset GOPATH
export GOARCH=${1}

function v
{
echo
echo $@
$@
}

if ! type -p goveralls; then
v go install github.com/mattn/goveralls
fi

if ! type -p shadow; then
v go get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
v go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
fi

if ! type -p goreturns; then
v go get github.com/sqs/goreturns
v go install github.com/sqs/goreturns
fi

echo date...
v go test -v -covermode=count -coverprofile=date.out .
v go tool cover -func=date.out
#[ -z "$COVERALLS_TOKEN" ] || goveralls -coverprofile=date.out -service=travis-ci -repotoken $COVERALLS_TOKEN

for d in clock period timespan view; do
echo $d...
v go test -v -covermode=count -coverprofile=$d.out ./$d
v go tool cover -func=$d.out
#[ -z "$COVERALLS_TOKEN" ] || goveralls -coverprofile=$d.out -service=travis-ci -repotoken $COVERALLS_TOKEN
done

v goreturns -l -w *.go */*.go

v go vet ./...

v shadow ./...

v go install ./datetool
182 changes: 182 additions & 0 deletions clock/clock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// Copyright 2015 Rick Beton. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package clock specifies a time of day with resolution to the nearest millisecond.
package clock

import (
"math"
"time"
)

// Clock specifies a time of day. It complements the existing time.Duration, applying
// that to the time since midnight (on some arbitrary day in some arbitrary timezone).
// The resolution is to the nearest millisecond, unlike time.Duration (which has nanosecond
// resolution).
//
// It is not intended that Clock be used to represent periods greater than 24 hours nor
// negative values. However, for such lengths of time, a fixed 24 hours per day
// is assumed and a modulo operation Mod24 is provided to discard whole multiples of 24 hours.
//
// Clock is a type of integer (actually int32), so values can be compared and sorted as
// per other integers. The constants Second, Minute, Hour and Day can be added and subtracted
// with obvious outcomes.
//
// See https://en.wikipedia.org/wiki/ISO_8601#Times
type Clock int32

// Common durations - second, minute, hour and day.
const (
// Second is one second; it has a similar meaning to time.Second.
Second Clock = Clock(time.Second / time.Millisecond)

// Minute is one minute; it has a similar meaning to time.Minute.
Minute Clock = Clock(time.Minute / time.Millisecond)

// Hour is one hour; it has a similar meaning to time.Hour.
Hour Clock = Clock(time.Hour / time.Millisecond)

// Day is a fixed period of 24 hours. This does not take account of daylight savings,
// so is not fully general.
Day Clock = Clock(time.Hour * 24 / time.Millisecond)
)

// Midnight is the zero value of a Clock.
const Midnight Clock = 0

// Noon is at 12pm.
const Noon Clock = Hour * 12

// Undefined is provided because the zero value of a Clock *is* defined (i.e. Midnight).
// So a special value is chosen, which is math.MinInt32.
const Undefined Clock = Clock(math.MinInt32)

// New returns a new Clock with specified hour, minute, second and millisecond.
func New(hour, minute, second, millisec int) Clock {
hx := Clock(hour) * Hour
mx := Clock(minute) * Minute
sx := Clock(second) * Second
return Clock(hx + mx + sx + Clock(millisec))
}

// NewAt returns a new Clock with specified hour, minute, second and millisecond.
func NewAt(t time.Time) Clock {
hour, minute, second := t.Clock()
hx := Clock(hour) * Hour
mx := Clock(minute) * Minute
sx := Clock(second) * Second
ms := Clock(t.Nanosecond() / int(time.Millisecond))
return Clock(hx + mx + sx + ms)
}

// SinceMidnight returns a new Clock based on a duration since some arbitrary midnight.
func SinceMidnight(d time.Duration) Clock {
return Clock(d / time.Millisecond)
}

// DurationSinceMidnight convert a clock to a time.Duration since some arbitrary midnight.
func (c Clock) DurationSinceMidnight() time.Duration {
return time.Duration(c) * time.Millisecond
}

// Add returns a new Clock offset from this clock specified hour, minute, second and millisecond.
// The parameters can be negative.
//
// If required, use Mod24() to correct any overflow or underflow.
func (c Clock) Add(h, m, s, ms int) Clock {
hx := Clock(h) * Hour
mx := Clock(m) * Minute
sx := Clock(s) * Second
return c + hx + mx + sx + Clock(ms)
}

// AddDuration returns a new Clock offset from this clock by a duration.
// The parameters can be negative.
//
// If required, use Mod24() to correct any overflow or underflow.
//
// AddDuration is also useful for adding period.Period values.
func (c Clock) AddDuration(d time.Duration) Clock {
return c + Clock(d/time.Millisecond)
}

// ModSubtract returns the duration between two clock times.
//
// If c2 is before c (i.e. c2 < c), the result is the duration computed from c - c2.
//
// But if c is before c2, it is assumed that c is after midnight and c2 is before midnight. The
// result is the sum of the evening time from c2 to midnight with the morning time from midnight to c.
// This is the same as Mod24(c - c2).
func (c Clock) ModSubtract(c2 Clock) time.Duration {
ms := c - c2
return ms.Mod24().DurationSinceMidnight()
}

// IsInOneDay tests whether a clock time is in the range 0 to 24 hours, inclusive. Inside this
// range, a Clock is generally well-behaved. But outside it, there may be errors due to daylight
// savings. Note that 24:00:00 is included as a special case as per ISO-8601 definition of midnight.
func (c Clock) IsInOneDay() bool {
return Midnight <= c && c <= Day
}

// IsMidnight tests whether a clock time is midnight. This is shorthand for c.Mod24() == 0.
// For large values, this assumes that every day has 24 hours.
func (c Clock) IsMidnight() bool {
return c.Mod24() == Midnight
}

// Mod24 calculates the remainder vs 24 hours using Euclidean division, in which the result
// will be less than 24 hours and is never negative. Note that this imposes the assumption that
// every day has 24 hours (not correct when daylight saving changes in any timezone).
//
// https://en.wikipedia.org/wiki/Modulo_operation
func (c Clock) Mod24() Clock {
if Midnight <= c && c < Day {
return c
}
if c < Midnight {
q := 1 - c/Day
m := c + (q * Day)
if m == Day {
m = Midnight
}
return m
}
q := c / Day
return c - (q * Day)
}

// Days gets the number of whole days represented by the Clock, assuming that each day is a fixed
// 24 hour period. Negative values are treated so that the range -23h59m59s to -1s is fully
// enclosed in a day numbered -1, and so on. This means that the result is zero only for the
// clock range 0s to 23h59m59s, for which IsInOneDay() returns true.
func (c Clock) Days() int {
if c < Midnight {
return int(c/Day) - 1
}
return int(c / Day)
}

// Hours gets the clock-face number of hours (calculated from the modulo time, see Mod24).
func (c Clock) Hours() int {
return int(clockHours(c.Mod24()))
}

// Minutes gets the clock-face number of minutes (calculated from the modulo time, see Mod24).
// For example, for 22:35 this will return 35.
func (c Clock) Minutes() int {
return int(clockMinutes(c.Mod24()))
}

// Seconds gets the clock-face number of seconds (calculated from the modulo time, see Mod24).
// For example, for 10:20:30 this will return 30.
func (c Clock) Seconds() int {
return int(clockSeconds(c.Mod24()))
}

// Millisec gets the clock-face number of milliseconds (calculated from the modulo time, see Mod24).
// For example, for 10:20:30.456 this will return 456.
func (c Clock) Millisec() int {
return int(clockMillisec(c.Mod24()))
}
Loading