{"id":44756390,"url":"https://github.com/cappuccinotm/trn","last_synced_at":"2026-02-16T00:15:17.958Z","repository":{"id":57645803,"uuid":"441506132","full_name":"cappuccinotm/trn","owner":"cappuccinotm","description":"Time Ranges","archived":false,"fork":false,"pushed_at":"2023-09-06T15:35:11.000Z","size":86,"stargazers_count":39,"open_issues_count":3,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-21T05:59:28.246Z","etag":null,"topics":["go","go-library","time","time-library"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cappuccinotm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2021-12-24T16:04:57.000Z","updated_at":"2024-06-07T22:05:42.000Z","dependencies_parsed_at":"2022-09-05T07:40:19.021Z","dependency_job_id":null,"html_url":"https://github.com/cappuccinotm/trn","commit_stats":null,"previous_names":["cappuccinotm/timerange"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/cappuccinotm/trn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cappuccinotm%2Ftrn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cappuccinotm%2Ftrn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cappuccinotm%2Ftrn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cappuccinotm%2Ftrn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cappuccinotm","download_url":"https://codeload.github.com/cappuccinotm/trn/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cappuccinotm%2Ftrn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29494677,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T00:00:57.352Z","status":"ssl_error","status_checked_at":"2026-02-15T23:56:34.338Z","response_time":118,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","go-library","time","time-library"],"created_at":"2026-02-16T00:15:17.327Z","updated_at":"2026-02-16T00:15:17.948Z","avatar_url":"https://github.com/cappuccinotm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Time Ranges [![Go Reference](https://pkg.go.dev/badge/github.com/cappuccinotm/trn.svg)](https://pkg.go.dev/github.com/cappuccinotm/trn) [![Go](https://github.com/cappuccinotm/trn/actions/workflows/go.yaml/badge.svg)](https://github.com/cappuccinotm/trn/actions/workflows/go.yaml) [![codecov](https://codecov.io/gh/cappuccinotm/trn/branch/master/graph/badge.svg?token=I8SsMkdRqd)](https://codecov.io/gh/cappuccinotm/trn) \nPackage `trn` introduces a `Range` type with useful methods to perform complex\noperations over time ranges.\n\n## Install and update\n`go get -u github.com/cappuccinotm/trn`\n\n## Usage\n```go\nrng := trn.New(time.Now(), 3 * time.Hour, trn.In(time.UTC))\n\nbetweenRng := trn.Between(time.Now(), time.Now().Add(3 * time.Hour), trn.In(time.UTC))\n```\n\nFor more examples see [test file](examples_test.go).\n\n## Todo\n- [ ] Make UTC and opts tests work in UTC location\n\n## Methods\n- `func New(start time.Time, duration time.Duration, opts ...Option) Range`\n  \n  Creates a new `Range` with start at the given time and with the given duration.\n\n- `func Between(start, end time.Time, opts ...Option) (Range, error)`\n\n  Creates a new `Range` within the given time range. `Between` uses the location\n  of the `start` time for the range.\n  Returns ErrStartAfterEnd if the start time is later than the end.\n\n- `func (r Range) Stratify(duration time.Duration, interval time.Duration) ([]Range, error)`\n  \n  Slices the range into smaller ones with fixed `duration` and fixed `interval` \n  between their **starts**.\n  In case if the last interval doesn't fit into the given duration, `Stratify` \n  won't return it.\n  Returns ErrZeroDurationInterval if the provided duration or interval is less or equal to zero.\n\n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![stratify illustration](_img/stratify.svg)\n\n\u003c/details\u003e\n\n- `func (r Range) Split(duration time.Duration, interval time.Duration) ([]Range, error)`\n\n  Slices the range into smaller ones with fixed `duration` and fixed `interval` \n  between the **end** of the one range and **start** of next range.\n  In case if the last interval doesn't fit into the given duration, `Split` \n  won't return it.\n  Returns ErrZeroDurationInterval if the provided duration is less or equal to zero.\n\n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![split illustration](_img/split.svg)\n\n\u003c/details\u003e\n\n- `func (r Range) Truncate(bounds Range) Range`\n  \n  Cuts the start and the end of the range to fit the given `bounds`.\n\n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![truncate illustration](_img/truncate.svg)\n\n\u003c/details\u003e\n\n- `MergeOverlappingRanges(ranges []Range) []Range`\n  \n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![merge illustration](_img/merge_overlapping_ranges.svg)\n\n\u003c/details\u003e\n\n- `func (r Range) Flip(ranges []Range) []Range`\n\n  Flips the given `ranges` within the given period (`r`).\n  \n  The boundaries of the given ranges are considered to be inclusive, which means\n  that the flipped ranges will start or end at the exact nanosecond where\n  the boundary from the input starts or ends.\n\n  Note: for the sake of safety, ranges are being merged before flip to ensure \n  the correct working of method.\n\n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![flip illustration](_img/flip.svg)\n\n\u003c/details\u003e\n\n- `func Intersection(ranges []Range) Range`\n\n  Returns the range, which is common for all the given ranges.\n\n\u003cdetails\u003e\u003csummary\u003eIllustration\u003c/summary\u003e\n\n![intersection illustration](_img/intersection.svg)\n\n\u003c/details\u003e\n\nThere are some other non-algorithmic methods, which you can see in the [reference](https://pkg.go.dev/github.com/cappuccinotm/trn).\n\n## Details\n\n`String` method formats the range in format `[start time, end time]`, where the \ntimes are formatted with the next template:\n```go\nconst defaultRangeFmt = \"2006-01-02 15:04:05.999999999 -0700 MST\"\n```\n\n# Status\nThe code was extracted from existing project and still under development. Until \nv1.x released the API may change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcappuccinotm%2Ftrn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcappuccinotm%2Ftrn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcappuccinotm%2Ftrn/lists"}