From 6bd97bdb64718f9f0b89a8e9c22407909d3e17ad Mon Sep 17 00:00:00 2001 From: darrenldl Date: Tue, 30 Jan 2024 13:12:52 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=202fae1?= =?UTF-8?q?c9965936911f0305cff2475e122c993d29f=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- odoc.support/odoc.css | 467 ++++++++++++++++-- odoc.support/odoc_search.js | 66 +++ .../Timedesc_json/Time_zone/index.html | 2 +- timedesc-json/Timedesc_json/index.html | 2 +- timedesc-json/index.html | 2 +- timedesc-sexp/Timedesc_sexp/Date/index.html | 2 +- timedesc-sexp/Timedesc_sexp/Span/index.html | 2 +- timedesc-sexp/Timedesc_sexp/Time/index.html | 2 +- .../Timedesc_sexp/Time_zone/Db/index.html | 2 +- .../Timedesc_sexp/Time_zone/index.html | 2 +- .../Timedesc_sexp/Time_zone_info/index.html | 2 +- .../Timedesc_sexp/Timestamp/index.html | 2 +- .../Timedesc_sexp/Zoneless/index.html | 2 +- timedesc-sexp/Timedesc_sexp/index.html | 2 +- timedesc-sexp/index.html | 2 +- timedesc-tzdb/Timedesc_tzdb/index.html | 2 +- timedesc-tzdb/index.html | 2 +- timedesc-tzlocal-js/index.html | 2 +- timedesc-tzlocal/Timedesc_tzlocal/index.html | 2 +- timedesc-tzlocal/index.html | 2 +- timedesc/Timedesc/Date/ISO_ord/index.html | 2 +- .../Timedesc/Date/ISO_week_date/index.html | 2 +- timedesc/Timedesc/Date/Ymd/index.html | 2 +- timedesc/Timedesc/Date/index.html | 2 +- .../Timedesc/ISO_ord_date_time/index.html | 2 +- timedesc/Timedesc/ISO_week/index.html | 2 +- .../Timedesc/ISO_week_date_time/index.html | 2 +- timedesc/Timedesc/Interval/index.html | 2 +- timedesc/Timedesc/Span/For_human/index.html | 2 +- timedesc/Timedesc/Span/index.html | 2 +- timedesc/Timedesc/Time/index.html | 2 +- .../Timedesc/Time_zone/Compressed/index.html | 2 +- .../Time_zone/Db/Compressed/index.html | 2 +- timedesc/Timedesc/Time_zone/Db/index.html | 2 +- timedesc/Timedesc/Time_zone/Raw/index.html | 2 +- timedesc/Timedesc/Time_zone/index.html | 2 +- timedesc/Timedesc/Time_zone_info/index.html | 2 +- timedesc/Timedesc/Timestamp/index.html | 2 +- timedesc/Timedesc/Utils/index.html | 2 +- timedesc/Timedesc/Ym/index.html | 2 +- timedesc/Timedesc/Zoneless/index.html | 2 +- timedesc/Timedesc/index.html | 6 +- timedesc/index.html | 2 +- timere-parse/Timere_parse/index.html | 2 +- timere-parse/index.html | 2 +- timere/Timere/Points/index.html | 2 +- timere/Timere/Utils/index.html | 2 +- timere/Timere/index.html | 4 +- timere/index.html | 2 +- 49 files changed, 546 insertions(+), 87 deletions(-) create mode 100644 odoc.support/odoc_search.js diff --git a/odoc.support/odoc.css b/odoc.support/odoc.css index 7230f826..c23517ba 100644 --- a/odoc.support/odoc.css +++ b/odoc.support/odoc.css @@ -1,7 +1,7 @@ @charset "UTF-8"; /* Copyright (c) 2016 The odoc contributors. All rights reserved. Distributed under the ISC license, see terms at the end of the file. - odoc 2.3.0 */ + odoc 2.4.1 */ /* Fonts */ /* noticia-text-regular - latin */ @@ -95,7 +95,10 @@ :root, .light:root { - --main-background: #FFFFFF; + + scroll-padding-top: calc(var(--search-bar-height) + var(--search-padding-top) + 1em); + + --main-background: #FFFFFF; --color: #333333; --link-color: #2C94BD; @@ -116,6 +119,7 @@ --toc-color: #1F2D3D; --toc-before-color: #777; --toc-background: #f6f8fa; + --toc-background-emph: #ecf0f5; --toc-list-border: #ccc; --spec-summary-border-color: #5c9cf5; @@ -124,6 +128,12 @@ --spec-summary-hover-background: #ebeff2; --spec-details-after-background: rgba(0, 4, 15, 0.05); --spec-details-after-shadow: rgba(204, 204, 204, 0.53); + + --search-results-border: #bbb; + --search-results-shadow: #bbb; + + --search-snake: #82aaff; + } .dark:root { @@ -151,6 +161,7 @@ --li-code-color: #999; --toc-color: #777; --toc-background: #252525; + --toc-background-emph: #2a2a2a; --hljs-link: #999; --hljs-keyword: #cda869; @@ -161,6 +172,10 @@ --hljs-variable: #cf6a4c; --spec-label-color: lightgreen; + + --search-results-border: #505050; + --search-results-shadow: #404040; + } @media (prefers-color-scheme: dark) { @@ -195,6 +210,7 @@ --toc-color: #777; --toc-before-color: #777; --toc-background: #252525; + --toc-background-emph: #2a2a2a; --toc-list-border: #ccc; --spec-summary-hover-background: #ebeff2; --spec-details-after-background: rgba(0, 4, 15, 0.05); @@ -209,6 +225,10 @@ --hljs-variable: #cf6a4c; --spec-label-color: lightgreen; + + --search-results-border: #505050; + --search-results-shadow: #404040; + } } @@ -246,26 +266,50 @@ body { } body { - margin-left: calc(10vw + 20ex); - margin-right: 4ex; - margin-top: 20px; - margin-bottom: 50px; + margin-left: auto; + margin-right: auto; + padding: 0 4ex; } body.odoc { - max-width: 100ex; + max-width: 132ex; + display: grid; + grid-template-columns: min-content 1fr; + column-gap: 4ex; + row-gap: 2ex; } body.odoc-src { margin-right: calc(10vw + 20ex); } +.odoc-content { + grid-row: 4; + grid-column: 2; +} + +.odoc-preamble > *:first-child { + /* This make the first thing in the preamble align with the sidebar */ + padding-top: 0; + margin-top: 0; +} + header { margin-bottom: 30px; } +header.odoc-preamble { + grid-column: 2; + grid-row: 3; +} + nav { - font-family: "Fira Sans", Helvetica, Arial, sans-serif; + font-family: "Fira Sans", sans-serif; +} + +nav.odoc-nav { + grid-column: 2; + grid-row: 2; } /* Basic markup elements */ @@ -396,7 +440,7 @@ a.anchor { a.source_link { float: right; color: var(--source-color); - font-family: "Fira Sans", Helvetica, Arial, sans-serif; + font-family: "Fira Sans", sans-serif; font-size: initial; } @@ -405,13 +449,17 @@ a.source_link { we restart the sequence there like h2 */ h1, h2, h3, h4, h5, h6, .h7, .h8, .h9, .h10 { - font-family: "Fira Sans", Helvetica, Arial, sans-serif; + font-family: "Fira Sans", sans-serif; font-weight: 400; padding-top: 0.1em; line-height: 1.2; overflow-wrap: break-word; } +.odoc-preamble h1 { + margin-top: 10px; +} + h1 { font-weight: 500; font-size: 2.441em; @@ -459,7 +507,7 @@ h4 { font-size: 1.12em; } -/* Comment delimiters, hidden but accessible to screen readers and +/* Comment delimiters, hidden but accessible to screen readers and selected for copy/pasting */ /* Taken from bootstrap */ @@ -479,7 +527,7 @@ h4 { /* Preformatted and code */ tt, code, pre { - font-family: "Fira Mono", courier; + font-family: "Fira Mono", monospace; font-weight: 400; } @@ -549,10 +597,10 @@ div.odoc-spec,.odoc-include { .spec.type .variant, .spec.type .record { margin-left: 2ch; +} + +.spec.type li.variant, .spec.type li.record { list-style: none; - display: flex; - flex-wrap: wrap; - row-gap: 4px; } .spec.type .record > code, .spec.type .variant > code { @@ -569,9 +617,8 @@ div.odoc-spec,.odoc-include { padding: 0.25em 0.5em; margin-left: 10%; border-radius: 3px; - flex-grow:1; background: var(--main-background); - box-shadow: 2px 2px 4px lightgrey; + box-shadow: 1px 1px 2px lightgrey; } div.def { @@ -739,19 +786,32 @@ td.def-doc *:first-child { line-height: 1.2; } +/* When a search bar is present, we need the sticky sidebar to be a bit lower, + so `top` is higher */ + +.odoc-search + * + .odoc-toc { + --toc-top: calc(var(--search-bar-height) + var(--search-padding-top) + 20px); + max-height: calc(100vh - 2 * var(--toc-top)); + top: var(--toc-top) +} + .odoc-toc { - position: fixed; - top: 0px; - bottom: 0px; - left: 0px; - max-width: 30ex; - min-width: 26ex; - width: 20%; + --toc-top: 20px; + width: 28ex; background: var(--toc-background); overflow: auto; color: var(--toc-color); padding-left: 2ex; padding-right: 2ex; + grid-row-start: 3; + grid-row-end: 5; + grid-column: 1; + height: fit-content; + border: solid 1px var(--border); + border-radius: 5px; + position:sticky; + max-height: calc(100vh - 2 * var(--toc-top)); + top: var(--toc-top) } .odoc-toc ul li a { @@ -759,15 +819,287 @@ td.def-doc *:first-child { font-size: 0.95em; color: var(--color); font-weight: 400; - line-height: 1.6em; + line-height: 1.2em; display: block; } -.odoc-toc ul li a:hover { +.odoc-sidebar ul li a:hover { box-shadow: none; text-decoration: underline; } +:root { + --search-bar-height: 25px; + --search-padding-top: 1rem; +} + +.odoc-search { + position: sticky; + top: 0; + background: var(--main-background); + /* This amounts to fit-content when the search is not active, but when you + have the search results displayed, you do not want the height of the search + container to change. */ + height: calc(var(--search-bar-height) + var(--search-padding-top)); + width: 100%; + padding-top: var(--search-padding-top); + z-index: 1; + grid-row: 1; + grid-column-start: 1; + grid-column-end: 3; +} + + +.odoc-search .search-inner { + width: 100%; + position: relative; + left: 0; + display: grid; + /* The second column is for the search snake, which has 0 width */ + grid-template-columns: 1fr 0fr; + grid-row-gap: 1rem; + /* The second row is for the search results. It has a width, but only */ + grid-template-rows: min-content 0px; + background: transparent; +} + +.odoc-search .search-bar { + position: relative; + z-index: 2; + font-size: 1em; + transition: font-size 0.3s; + box-shadow: 0px 0px 0.2rem 0.3em var(--main-background); + height: var(--search-bar-height); +} + +.odoc-search:focus-within .search-bar { + font-size: 1.1em; +} + +.odoc-search:not(:focus-within) .search-result { + display: none; +} + +.odoc-search .search-result:empty { + display: none; +} + +.odoc-search .search-result { + grid-row: 2; + background: var(--toc-background); + position: absolute; + left: 0; + right: 0; + border: solid; + border-color: var(--search-results-border); + border-width: 1px; + border-radius: 6px; + box-shadow: 0 3px 10px 2px var(--search-results-shadow), 0 0 3px 4px var(--main-background), 0px -1rem 0px 0px var(--main-background); + /* Works better on smallish screens with this */ + max-height: calc(min(40rem, 50vh)); + overflow-y: auto; +} + +.search-bar { + /* inputs are of fixed size by default, even if you display:block them */ + width: 100%; +} + + +.odoc-search .search-no-result { + color: var(--color); + border-bottom: var(--search-results-border) solid 1px; + background-color: inherit; + outline: 0; + padding: 10px; + padding-right: 0.5rem; +} + +.search-bar-container { + display: flex; + align-items: stretch; + border-bottom: 1rem solid var(--main-background); +} + +.search-snake { + grid-row: 1; + grid-column: 2; + display: flex; + align-items: center; + width: 0; + z-index: 2; + position: relative; + left: 0; + margin-top: 4px; + margin-bottom: 4px; + /* Otherwise the search snake flickers for very fast searches. */ + transition: opacity 0.2s; + opacity: 0; +} + +.search-snake.search-busy { + opacity: 1; +} + +.search-snake:before { + content: " "; + display: block; + aspect-ratio: 1 / 1; + height: 100%; + margin-right: 4px; + border-radius: 50%; + border: 3px solid #aaa; + border-color: var(--search-snake) transparent var(--search-snake) transparent; + animation: search-snake 1.2s linear infinite; + position: absolute; + right: 0; +} + +@keyframes search-snake { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +:root { + --kind-font-size-factor: 0.8; +} + +.odoc-search .search-entry { + color: var(--color); + display: grid; + /* Possible kinds are the following : + "doc" "type" "mod" "exn" "class" "meth" "cons" "sig" "cons" "field" "val" + and "ext". + As the longest is 5 characters (and the font monospace), we give 5 + character size to the column. However the font used for kind is a little + smaller, so we adjust by this factor. + */ + grid-template-columns: [kinds] calc(var(--kind-font-size-factor) * 5ch) [titles] 1fr; + column-gap: 0.5rem; + border-bottom: var(--search-results-border) solid 1px; + background-color: inherit; + outline: 0; + padding: 0.4rem 0.4rem 0.7rem 0.7rem; +} +.odoc-search .search-entry p { + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.odoc-search .search-entry:focus-visible { + box-shadow: none; + background-color: var(--target-background); +} + +.odoc-search .search-entry:hover { + box-shadow: none; + background-color: var(--toc-background-emph); +} + +.odoc-search .search-entry .entry-kind { + grid-row: 1/2; + grid-column: 1/2; + line-height: 1.4rem; + font-size: calc(var(--kind-font-size-factor) * 1em); + font-weight: bold; + text-align: right; + position: relative; + bottom: 0; +} + +.odoc-search .search-entry pre { + border: none; + margin: 0; +} + +.odoc-search .search-entry pre code { + font-size: 1em; + background-color: var(--li-code-background); + color: var(--li-code-color); + border-radius: 3px; + padding: 0 0.3ex; +} + +.odoc-search .search-entry .entry-title { + width: 100%; + display: block; + grid-column: 2/2; + grid-row: 1/2; + align-self: end; + line-height: 1.4rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.odoc-search .entry-name { + font-weight: bold; +} + +.odoc-search .prefix-name { + font-weight: bold; +} + +.odoc-search .search-entry .prefix-name { + opacity: 0.7; +} + +.odoc-search .entry-rhs { + white-space: nowrap; +} + +.odoc-search .search-entry .entry-content { + flex-grow: 1; + flex-shrink: 1; + min-width: 0; +} + +.odoc-search .search-entry .entry-comment { + max-height: 1.5em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.95em; + grid-row: 2/2; + grid-column: 2/2; +} + +.odoc-search .search-entry .entry-comment ul { + white-space: nowrap; + display: inline; +} + +.odoc-search .search-entry .entry-comment li { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment ul>li::before { + content: '•'; +} + +.odoc-search .search-entry .entry-comment div { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment p { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment code { + display: inline; + white-space: nowrap; +} + /* First level titles */ .odoc-toc>ul>li>a { @@ -776,6 +1108,7 @@ td.def-doc *:first-child { .odoc-toc li ul { margin: 0px; + padding-top: 0.25em; } .odoc-toc ul { @@ -783,8 +1116,9 @@ td.def-doc *:first-child { } .odoc-toc ul li { - margin: 0; + padding: 0.25em 0; } + .odoc-toc>ul>li { margin-bottom: 0.3em; } @@ -801,7 +1135,8 @@ td.def-doc *:first-child { margin: 1em; } -.odoc-table td, .odoc-table th { +.odoc-table td, +.odoc-table th { padding-left: 0.5em; padding-right: 0.5em; border: 1px solid black; @@ -816,7 +1151,13 @@ td.def-doc *:first-child { @media only screen and (max-width: 110ex) { body { margin: 2em; + padding: 0; + } + + body.odoc { + display: block; } + .odoc-toc { position: static; width: auto; @@ -836,6 +1177,7 @@ td.def-doc *:first-child { color: black; background: white; } + body nav:first-child { visibility: hidden; } @@ -955,23 +1297,74 @@ td.def-doc *:first-child { text-decoration: underline; } -.VAL, .TYPE, .LET, .REC, .IN, .OPEN, .NONREC, .MODULE, .METHOD, .LETOP, .INHERIT, .INCLUDE, .FUNCTOR, .EXTERNAL, .CONSTRAINT, .ASSERT, .AND, .END, .CLASS, .STRUCT, .SIG { - color: #859900;; -} - -.WITH, .WHILE, .WHEN, .VIRTUAL, .TRY, .TO, .THEN, .PRIVATE, .OF, .NEW, .MUTABLE, .MATCH, .LAZY, .IF, .FUNCTION, .FUN, .FOR, .EXCEPTION, .ELSE, .TO, .DOWNTO, .DO, .DONE, .BEGIN, .AS { +.VAL, +.TYPE, +.LET, +.REC, +.IN, +.OPEN, +.NONREC, +.MODULE, +.METHOD, +.LETOP, +.INHERIT, +.INCLUDE, +.FUNCTOR, +.EXTERNAL, +.CONSTRAINT, +.ASSERT, +.AND, +.END, +.CLASS, +.STRUCT, +.SIG { + color: #859900; + ; +} + +.WITH, +.WHILE, +.WHEN, +.VIRTUAL, +.TRY, +.TO, +.THEN, +.PRIVATE, +.OF, +.NEW, +.MUTABLE, +.MATCH, +.LAZY, +.IF, +.FUNCTION, +.FUN, +.FOR, +.EXCEPTION, +.ELSE, +.TO, +.DOWNTO, +.DO, +.DONE, +.BEGIN, +.AS { color: #cb4b16; } -.TRUE, .FALSE { +.TRUE, +.FALSE { color: #b58900; } -.failwith, .INT, .SEMISEMI, .LIDENT { +.failwith, +.INT, +.SEMISEMI, +.LIDENT { color: #2aa198; } -.STRING, .CHAR, .UIDENT { +.STRING, +.CHAR, +.UIDENT { color: #b58900; } @@ -997,4 +1390,4 @@ td.def-doc *:first-child { WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ---------------------------------------------------------------------------*/ + ---------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/odoc.support/odoc_search.js b/odoc.support/odoc_search.js new file mode 100644 index 00000000..0dc659d2 --- /dev/null +++ b/odoc.support/odoc_search.js @@ -0,0 +1,66 @@ +/* The browsers interpretation of the CORS origin policy prevents to run + webworkers from javascript files fetched from the file:// protocol. This hack + is to workaround this restriction. */ +function createWebWorker() { + var searchs = search_urls.map((search_url) => { + let parts = document.location.href.split("/"); + parts[parts.length - 1] = search_url; + return '"' + parts.join("/") + '"'; + }); + blobContents = ["importScripts(" + searchs.join(",") + ");"]; + var blob = new Blob(blobContents, { type: "application/javascript" }); + var blobUrl = URL.createObjectURL(blob); + + var worker = new Worker(blobUrl); + URL.revokeObjectURL(blobUrl); + + return worker; +} + +var worker; +var waiting = 0; + +function wait() { + waiting = waiting + 1; + document.querySelector(".search-snake").classList.add("search-busy"); +} + +function stop_waiting() { + if (waiting > 0) waiting = waiting - 1; + else waiting = 0; + if (waiting == 0) { + document.querySelector(".search-snake").classList.remove("search-busy"); + } +} + +document.querySelector(".search-bar").addEventListener("focus", (ev) => { + if (typeof worker == "undefined") { + worker = createWebWorker(); + worker.onmessage = (e) => { + stop_waiting(); + let results = e.data; + let search_results = document.querySelector(".search-result"); + search_results.innerHTML = ""; + let f = (entry) => { + let search_result = document.createElement("a"); + search_result.classList.add("search-entry"); + search_result.href = base_url + entry.url; + search_result.innerHTML = entry.html; + search_results.appendChild(search_result); + }; + results.forEach(f); + let search_request = document.querySelector(".search-bar").value; + if (results.length == 0 && search_request != "") { + let no_result = document.createElement("div"); + no_result.classList.add("search-no-result"); + no_result.innerText = "No result..."; + search_results.appendChild(no_result); + } + }; + } +}); + +document.querySelector(".search-bar").addEventListener("input", (ev) => { + wait(); + worker.postMessage(ev.target.value); +}); diff --git a/timedesc-json/Timedesc_json/Time_zone/index.html b/timedesc-json/Timedesc_json/Time_zone/index.html index c293e7fc..0230b363 100644 --- a/timedesc-json/Timedesc_json/Time_zone/index.html +++ b/timedesc-json/Timedesc_json/Time_zone/index.html @@ -1,2 +1,2 @@ -Time_zone (timedesc-json.Timedesc_json.Time_zone)

Module Timedesc_json.Time_zone

val to_json : Timedesc.Time_zone.t -> Yojson.Basic.t
val of_json : Yojson.Basic.t -> Timedesc.Time_zone.t option
val of_string : string -> Timedesc.Time_zone.t option
+Time_zone (timedesc-json.Timedesc_json.Time_zone)

Module Timedesc_json.Time_zone

val to_json : Timedesc.Time_zone.t -> Yojson.Basic.t
val of_json : Yojson.Basic.t -> Timedesc.Time_zone.t option
val of_string : string -> Timedesc.Time_zone.t option
diff --git a/timedesc-json/Timedesc_json/index.html b/timedesc-json/Timedesc_json/index.html index 4faa21e6..dfb16629 100644 --- a/timedesc-json/Timedesc_json/index.html +++ b/timedesc-json/Timedesc_json/index.html @@ -1,2 +1,2 @@ -Timedesc_json (timedesc-json.Timedesc_json)

Module Timedesc_json

module Time_zone : sig ... end
+Timedesc_json (timedesc-json.Timedesc_json)

Module Timedesc_json

module Time_zone : sig ... end
diff --git a/timedesc-json/index.html b/timedesc-json/index.html index b05b5022..3b622637 100644 --- a/timedesc-json/index.html +++ b/timedesc-json/index.html @@ -1,2 +1,2 @@ -index (timedesc-json.index)

timedesc-json index

Library timedesc-json

The entry point of this library is the module: Timedesc_json.

+index (timedesc-json.index)

timedesc-json index

Library timedesc-json

The entry point of this library is the module: Timedesc_json.

diff --git a/timedesc-sexp/Timedesc_sexp/Date/index.html b/timedesc-sexp/Timedesc_sexp/Date/index.html index 3be60908..17239281 100644 --- a/timedesc-sexp/Timedesc_sexp/Date/index.html +++ b/timedesc-sexp/Timedesc_sexp/Date/index.html @@ -1,2 +1,2 @@ -Date (timedesc-sexp.Timedesc_sexp.Date)

Module Timedesc_sexp.Date

val to_sexp : Timedesc.Date.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Date.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Date.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Date.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Date.t -> unit
+Date (timedesc-sexp.Timedesc_sexp.Date)

Module Timedesc_sexp.Date

val to_sexp : Timedesc.Date.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Date.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Date.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Date.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Date.t -> unit
diff --git a/timedesc-sexp/Timedesc_sexp/Span/index.html b/timedesc-sexp/Timedesc_sexp/Span/index.html index 4fa2e179..4d265a0a 100644 --- a/timedesc-sexp/Timedesc_sexp/Span/index.html +++ b/timedesc-sexp/Timedesc_sexp/Span/index.html @@ -1,2 +1,2 @@ -Span (timedesc-sexp.Timedesc_sexp.Span)

Module Timedesc_sexp.Span

val to_sexp : Timedesc.Span.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Span.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Span.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Span.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Span.t -> unit
+Span (timedesc-sexp.Timedesc_sexp.Span)

Module Timedesc_sexp.Span

val to_sexp : Timedesc.Span.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Span.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Span.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Span.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Span.t -> unit
diff --git a/timedesc-sexp/Timedesc_sexp/Time/index.html b/timedesc-sexp/Timedesc_sexp/Time/index.html index 56bf7ad2..8dc8b72d 100644 --- a/timedesc-sexp/Timedesc_sexp/Time/index.html +++ b/timedesc-sexp/Timedesc_sexp/Time/index.html @@ -1,2 +1,2 @@ -Time (timedesc-sexp.Timedesc_sexp.Time)

Module Timedesc_sexp.Time

val to_sexp : Timedesc.Time.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Time.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Time.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Time.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Time.t -> unit
+Time (timedesc-sexp.Timedesc_sexp.Time)

Module Timedesc_sexp.Time

val to_sexp : Timedesc.Time.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.Time.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Time.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.Time.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.Time.t -> unit
diff --git a/timedesc-sexp/Timedesc_sexp/Time_zone/Db/index.html b/timedesc-sexp/Timedesc_sexp/Time_zone/Db/index.html index 5fbd9bf0..cda0eba5 100644 --- a/timedesc-sexp/Timedesc_sexp/Time_zone/Db/index.html +++ b/timedesc-sexp/Timedesc_sexp/Time_zone/Db/index.html @@ -1,2 +1,2 @@ -Db (timedesc-sexp.Timedesc_sexp.Time_zone.Db)

Module Time_zone.Db

val of_sexp : Sexplib.Sexp.t -> Timedesc.Time_zone.Db.db option
val to_sexp : Timedesc.Time_zone.Db.db -> Sexplib.Sexp.t
val of_string : string -> Timedesc.Time_zone.Db.db option
+Db (timedesc-sexp.Timedesc_sexp.Time_zone.Db)

Module Time_zone.Db

val of_sexp : Sexplib.Sexp.t -> Timedesc.Time_zone.Db.db option
val to_sexp : Timedesc.Time_zone.Db.db -> Sexplib.Sexp.t
val of_string : string -> Timedesc.Time_zone.Db.db option
diff --git a/timedesc-sexp/Timedesc_sexp/Time_zone/index.html b/timedesc-sexp/Timedesc_sexp/Time_zone/index.html index 692d5f2d..2aaed3a7 100644 --- a/timedesc-sexp/Timedesc_sexp/Time_zone/index.html +++ b/timedesc-sexp/Timedesc_sexp/Time_zone/index.html @@ -1,2 +1,2 @@ -Time_zone (timedesc-sexp.Timedesc_sexp.Time_zone)

Module Timedesc_sexp.Time_zone

val to_sexp : Timedesc.Time_zone.t -> Sexplib.Sexp.t
val of_sexp : Sexplib.Sexp.t -> Timedesc.Time_zone.t option
val of_string : string -> Timedesc.Time_zone.t option
module Db : sig ... end
+Time_zone (timedesc-sexp.Timedesc_sexp.Time_zone)

Module Timedesc_sexp.Time_zone

val to_sexp : Timedesc.Time_zone.t -> Sexplib.Sexp.t
val of_sexp : Sexplib.Sexp.t -> Timedesc.Time_zone.t option
val of_string : string -> Timedesc.Time_zone.t option
module Db : sig ... end
diff --git a/timedesc-sexp/Timedesc_sexp/Time_zone_info/index.html b/timedesc-sexp/Timedesc_sexp/Time_zone_info/index.html index df73d9a3..749e5498 100644 --- a/timedesc-sexp/Timedesc_sexp/Time_zone_info/index.html +++ b/timedesc-sexp/Timedesc_sexp/Time_zone_info/index.html @@ -1,4 +1,4 @@ -Time_zone_info (timedesc-sexp.Timedesc_sexp.Time_zone_info)

Module Timedesc_sexp.Time_zone_info

val of_sexp : +Time_zone_info (timedesc-sexp.Timedesc_sexp.Time_zone_info)

Module Timedesc_sexp.Time_zone_info

val of_sexp : Sexplib.Sexp.t -> (Timedesc.Time_zone_info.t, string) Stdlib.result
val to_sexp : Timedesc.Time_zone_info.t -> Sexplib.Sexp.t
diff --git a/timedesc-sexp/Timedesc_sexp/Timestamp/index.html b/timedesc-sexp/Timedesc_sexp/Timestamp/index.html index 2cfd8b7e..fdb98ad6 100644 --- a/timedesc-sexp/Timedesc_sexp/Timestamp/index.html +++ b/timedesc-sexp/Timedesc_sexp/Timestamp/index.html @@ -1,2 +1,2 @@ -Timestamp (timedesc-sexp.Timedesc_sexp.Timestamp)

Module Timedesc_sexp.Timestamp

val of_sexp : Sexplib.Sexp.t -> (Timedesc.Timestamp.t, string) Stdlib.result
val to_sexp : Timedesc.Timestamp.t -> Sexplib.Sexp.t
+Timestamp (timedesc-sexp.Timedesc_sexp.Timestamp)

Module Timedesc_sexp.Timestamp

val of_sexp : Sexplib.Sexp.t -> (Timedesc.Timestamp.t, string) Stdlib.result
val to_sexp : Timedesc.Timestamp.t -> Sexplib.Sexp.t
diff --git a/timedesc-sexp/Timedesc_sexp/Zoneless/index.html b/timedesc-sexp/Timedesc_sexp/Zoneless/index.html index 4e3e9e9b..e74680d4 100644 --- a/timedesc-sexp/Timedesc_sexp/Zoneless/index.html +++ b/timedesc-sexp/Timedesc_sexp/Zoneless/index.html @@ -1,4 +1,4 @@ -Zoneless (timedesc-sexp.Timedesc_sexp.Zoneless)

Module Timedesc_sexp.Zoneless

val to_sexp : Timedesc.Zoneless.zoneless -> Sexplib.Sexp.t
val of_sexp : +Zoneless (timedesc-sexp.Timedesc_sexp.Zoneless)

Module Timedesc_sexp.Zoneless

val to_sexp : Timedesc.Zoneless.zoneless -> Sexplib.Sexp.t
val of_sexp : Sexplib.Sexp.t -> (Timedesc.Zoneless.zoneless, string) Stdlib.result
diff --git a/timedesc-sexp/Timedesc_sexp/index.html b/timedesc-sexp/Timedesc_sexp/index.html index 059e4825..f0a71e60 100644 --- a/timedesc-sexp/Timedesc_sexp/index.html +++ b/timedesc-sexp/Timedesc_sexp/index.html @@ -1,2 +1,2 @@ -Timedesc_sexp (timedesc-sexp.Timedesc_sexp)

Module Timedesc_sexp

val to_sexp : Timedesc.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.t -> unit
module Span : sig ... end
module Timestamp : sig ... end
module Date : sig ... end
module Time : sig ... end
module Time_zone : sig ... end
module Zoneless : sig ... end
module Time_zone_info : sig ... end
+Timedesc_sexp (timedesc-sexp.Timedesc_sexp)

Module Timedesc_sexp

val to_sexp : Timedesc.t -> Sexplib.Sexp.t
val to_sexp_string : Timedesc.t -> string
val of_sexp : Sexplib.Sexp.t -> (Timedesc.t, string) Stdlib.result
val of_sexp_string : string -> (Timedesc.t, string) Stdlib.result
val pp_sexp : Stdlib.Format.formatter -> Timedesc.t -> unit
module Span : sig ... end
module Timestamp : sig ... end
module Date : sig ... end
module Time : sig ... end
module Time_zone : sig ... end
module Zoneless : sig ... end
module Time_zone_info : sig ... end
diff --git a/timedesc-sexp/index.html b/timedesc-sexp/index.html index 1715a848..54f324f4 100644 --- a/timedesc-sexp/index.html +++ b/timedesc-sexp/index.html @@ -1,2 +1,2 @@ -index (timedesc-sexp.index)

timedesc-sexp index

Library timedesc-sexp

The entry point of this library is the module: Timedesc_sexp.

+index (timedesc-sexp.index)

timedesc-sexp index

Library timedesc-sexp

The entry point of this library is the module: Timedesc_sexp.

diff --git a/timedesc-tzdb/Timedesc_tzdb/index.html b/timedesc-tzdb/Timedesc_tzdb/index.html index aac2ec01..f9515e34 100644 --- a/timedesc-tzdb/Timedesc_tzdb/index.html +++ b/timedesc-tzdb/Timedesc_tzdb/index.html @@ -1,5 +1,5 @@ -Timedesc_tzdb (timedesc-tzdb.Timedesc_tzdb)

Module Timedesc_tzdb

module M : Stdlib.Map.S with type key = string
type entry = {
  1. is_dst : bool;
  2. offset : int;
}
type table = +Timedesc_tzdb (timedesc-tzdb.Timedesc_tzdb)

Module Timedesc_tzdb

module M : Stdlib.Map.S with type key = string
type entry = {
  1. is_dst : bool;
  2. offset : int;
}
type table = (int64, Stdlib.Bigarray.int64_elt, Stdlib.Bigarray.c_layout) Stdlib.Bigarray.Array1.t * entry array
val db : table M.t option
val compressed : string option
diff --git a/timedesc-tzdb/index.html b/timedesc-tzdb/index.html index e225aba5..87f9b38d 100644 --- a/timedesc-tzdb/index.html +++ b/timedesc-tzdb/index.html @@ -1,2 +1,2 @@ -index (timedesc-tzdb.index)

timedesc-tzdb index

Library timedesc-tzdb

The entry point of this library is the module: Timedesc_tzdb.

+index (timedesc-tzdb.index)

timedesc-tzdb index

Library timedesc-tzdb

The entry point of this library is the module: Timedesc_tzdb.

diff --git a/timedesc-tzlocal-js/index.html b/timedesc-tzlocal-js/index.html index d464504a..c80bc35f 100644 --- a/timedesc-tzlocal-js/index.html +++ b/timedesc-tzlocal-js/index.html @@ -1,2 +1,2 @@ -index (timedesc-tzlocal-js.index)

timedesc-tzlocal-js index

+index (timedesc-tzlocal-js.index)

timedesc-tzlocal-js index

diff --git a/timedesc-tzlocal/Timedesc_tzlocal/index.html b/timedesc-tzlocal/Timedesc_tzlocal/index.html index 6e341eb5..886779b9 100644 --- a/timedesc-tzlocal/Timedesc_tzlocal/index.html +++ b/timedesc-tzlocal/Timedesc_tzlocal/index.html @@ -1,2 +1,2 @@ -Timedesc_tzlocal (timedesc-tzlocal.Timedesc_tzlocal)

Module Timedesc_tzlocal

val local : unit -> string list
+Timedesc_tzlocal (timedesc-tzlocal.Timedesc_tzlocal)

Module Timedesc_tzlocal

val local : unit -> string list
diff --git a/timedesc-tzlocal/index.html b/timedesc-tzlocal/index.html index 7c0aa2d6..806044fd 100644 --- a/timedesc-tzlocal/index.html +++ b/timedesc-tzlocal/index.html @@ -1,2 +1,2 @@ -index (timedesc-tzlocal.index)

timedesc-tzlocal index

Library timedesc-tzlocal

The entry point of this library is the module: Timedesc_tzlocal.

+index (timedesc-tzlocal.index)

timedesc-tzlocal index

Library timedesc-tzlocal

The entry point of this library is the module: Timedesc_tzlocal.

diff --git a/timedesc/Timedesc/Date/ISO_ord/index.html b/timedesc/Timedesc/Date/ISO_ord/index.html index 1f551ea5..8adc85a0 100644 --- a/timedesc/Timedesc/Date/ISO_ord/index.html +++ b/timedesc/Timedesc/Date/ISO_ord/index.html @@ -1,2 +1,2 @@ -ISO_ord (timedesc.Timedesc.Date.ISO_ord)

Module Date.ISO_ord

type view = private {
  1. year : int;
  2. day_of_year : int;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_day_of_year of int
]
exception Error_exn of error
val make : year:int -> day_of_year:int -> (t, error) Stdlib.result

Constructs a date in the ISO ordinal calendar.

Returns Error `Invalid_year if year < 0 || 9999 < year.

Returns Error `Invalid_day_of_year if day_of_year < 1 || day count of year < day_of_year.

val make_exn : year:int -> day_of_year:int -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
+ISO_ord (timedesc.Timedesc.Date.ISO_ord)

Module Date.ISO_ord

type view = private {
  1. year : int;
  2. day_of_year : int;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_day_of_year of int
]
exception Error_exn of error
val make : year:int -> day_of_year:int -> (t, error) Stdlib.result

Constructs a date in the ISO ordinal calendar.

Returns Error `Invalid_year if year < 0 || 9999 < year.

Returns Error `Invalid_day_of_year if day_of_year < 1 || day count of year < day_of_year.

val make_exn : year:int -> day_of_year:int -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
diff --git a/timedesc/Timedesc/Date/ISO_week_date/index.html b/timedesc/Timedesc/Date/ISO_week_date/index.html index 61f999fd..f6af3ef3 100644 --- a/timedesc/Timedesc/Date/ISO_week_date/index.html +++ b/timedesc/Timedesc/Date/ISO_week_date/index.html @@ -1,2 +1,2 @@ -ISO_week_date (timedesc.Timedesc.Date.ISO_week_date)

Module Date.ISO_week_date

type view = private {
  1. year : int;
  2. week : int;
  3. weekday : weekday;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
]
exception Error_exn of error
val make : year:int -> week:int -> weekday:weekday -> (t, error) Stdlib.result

Constructs a date in the ISO week calendar.

Returns Error `Invalid_iso_year if year < 0 || 9999 < year.

Returns Error `Invalid_iso_week if week < 1 || week count of year < week.

val make_exn : year:int -> week:int -> weekday:weekday -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
+ISO_week_date (timedesc.Timedesc.Date.ISO_week_date)

Module Date.ISO_week_date

type view = private {
  1. year : int;
  2. week : int;
  3. weekday : weekday;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
]
exception Error_exn of error
val make : year:int -> week:int -> weekday:weekday -> (t, error) Stdlib.result

Constructs a date in the ISO week calendar.

Returns Error `Invalid_iso_year if year < 0 || 9999 < year.

Returns Error `Invalid_iso_week if week < 1 || week count of year < week.

val make_exn : year:int -> week:int -> weekday:weekday -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
diff --git a/timedesc/Timedesc/Date/Ymd/index.html b/timedesc/Timedesc/Date/Ymd/index.html index 68837e61..1cda4513 100644 --- a/timedesc/Timedesc/Date/Ymd/index.html +++ b/timedesc/Timedesc/Date/Ymd/index.html @@ -1,2 +1,2 @@ -Ymd (timedesc.Timedesc.Date.Ymd)

Module Date.Ymd

type view = private {
  1. year : int;
  2. month : int;
  3. day : int;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
  4. | `Invalid_day of int
]
exception Error_exn of error
val make : year:int -> month:int -> day:int -> (t, error) Stdlib.result

Constructs a date in the Gregorian calendar.

Returns Error `Invalid_year if year < 0 || 9999 < year.

Returns Error `Invalid_month if month < 1 || 12 < month.

Returns Error `Invalid_day if day < 1 || day count of month < day.

val make_exn : year:int -> month:int -> day:int -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
+Ymd (timedesc.Timedesc.Date.Ymd)

Module Date.Ymd

type view = private {
  1. year : int;
  2. month : int;
  3. day : int;
}
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
  4. | `Invalid_day of int
]
exception Error_exn of error
val make : year:int -> month:int -> day:int -> (t, error) Stdlib.result

Constructs a date in the Gregorian calendar.

Returns Error `Invalid_year if year < 0 || 9999 < year.

Returns Error `Invalid_month if month < 1 || 12 < month.

Returns Error `Invalid_day if day < 1 || day count of month < day.

val make_exn : year:int -> month:int -> day:int -> t
val view : t -> view

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
diff --git a/timedesc/Timedesc/Date/index.html b/timedesc/Timedesc/Date/index.html index d2e0e043..16f013d8 100644 --- a/timedesc/Timedesc/Date/index.html +++ b/timedesc/Timedesc/Date/index.html @@ -1,2 +1,2 @@ -Date (timedesc.Timedesc.Date)

Module Timedesc.Date

type t

Accessors

val ym : t -> Ym.t
val year : t -> int
val month : t -> int
val day : t -> int
val iso_week : t -> ISO_week.t
val iso_year : t -> int
val weekday : t -> weekday
val day_of_year : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : days:int -> t -> t
val sub : days:int -> t -> t
val diff_days : t -> t -> int

Pretty printing

val pp_rfc3339 : Stdlib.Format.formatter -> t -> unit
val to_rfc3339 : t -> string
val pp_rfc9110 : Stdlib.Format.formatter -> t -> unit
val to_rfc9110 : t -> string
val pp_http : Stdlib.Format.formatter -> t -> unit

Alias to pp_rfc9110

val to_http : t -> string

Alias to to_rfc9110

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t

Gregorian calendar

module Ymd : sig ... end
val of_ym : Ym.t -> day:int -> (t, Ymd.error) Stdlib.result
val of_ym_exn : Ym.t -> day:int -> t

ISO week date calendar

module ISO_week_date : sig ... end
val of_iso_week : ISO_week.t -> weekday:weekday -> t

ISO ord date calendar

module ISO_ord : sig ... end
+Date (timedesc.Timedesc.Date)

Module Timedesc.Date

type t

Accessors

val ym : t -> Ym.t
val year : t -> int
val month : t -> int
val day : t -> int
val iso_week : t -> ISO_week.t
val iso_year : t -> int
val weekday : t -> weekday
val day_of_year : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : days:int -> t -> t
val sub : days:int -> t -> t
val diff_days : t -> t -> int

Pretty printing

val pp_rfc3339 : Stdlib.Format.formatter -> t -> unit
val to_rfc3339 : t -> string
val pp_rfc9110 : Stdlib.Format.formatter -> t -> unit
val to_rfc9110 : t -> string
val pp_http : Stdlib.Format.formatter -> t -> unit

Alias to pp_rfc9110

val to_http : t -> string

Alias to to_rfc9110

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t

Gregorian calendar

module Ymd : sig ... end
val of_ym : Ym.t -> day:int -> (t, Ymd.error) Stdlib.result
val of_ym_exn : Ym.t -> day:int -> t

ISO week date calendar

module ISO_week_date : sig ... end
val of_iso_week : ISO_week.t -> weekday:weekday -> t

ISO ord date calendar

module ISO_ord : sig ... end
diff --git a/timedesc/Timedesc/ISO_ord_date_time/index.html b/timedesc/Timedesc/ISO_ord_date_time/index.html index 1d23d6cc..502c33ab 100644 --- a/timedesc/Timedesc/ISO_ord_date_time/index.html +++ b/timedesc/Timedesc/ISO_ord_date_time/index.html @@ -1,5 +1,5 @@ -ISO_ord_date_time (timedesc.Timedesc.ISO_ord_date_time)

Module Timedesc.ISO_ord_date_time

type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_day_of_year of int
  4. | `Invalid_hour of int
  5. | `Invalid_minute of int
  6. | `Invalid_second of int
  7. | `Invalid_s_frac of float
  8. | `Invalid_ns of int
  9. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string
val make : +ISO_ord_date_time (timedesc.Timedesc.ISO_ord_date_time)

Module Timedesc.ISO_ord_date_time

type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_day_of_year of int
  4. | `Invalid_hour of int
  5. | `Invalid_minute of int
  6. | `Invalid_second of int
  7. | `Invalid_s_frac of float
  8. | `Invalid_ns of int
  9. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string
val make : ?tz:Time_zone.t -> ?ns:int -> ?s_frac:float -> diff --git a/timedesc/Timedesc/ISO_week/index.html b/timedesc/Timedesc/ISO_week/index.html index c9ca5128..bf7b16d1 100644 --- a/timedesc/Timedesc/ISO_week/index.html +++ b/timedesc/Timedesc/ISO_week/index.html @@ -1,2 +1,2 @@ -ISO_week (timedesc.Timedesc.ISO_week)

Module Timedesc.ISO_week

type t
type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
]

Constructors

val make : year:int -> week:int -> (t, error) Stdlib.result
val make_exn : year:int -> week:int -> t

Accessors

val year_week : t -> int * int
val year : t -> int
val week : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : weeks:int -> t -> t
val sub : weeks:int -> t -> t
val diff_weeks : t -> t -> int

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
+ISO_week (timedesc.Timedesc.ISO_week)

Module Timedesc.ISO_week

type t
type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
]

Constructors

val make : year:int -> week:int -> (t, error) Stdlib.result
val make_exn : year:int -> week:int -> t

Accessors

val year_week : t -> int * int
val year : t -> int
val week : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : weeks:int -> t -> t
val sub : weeks:int -> t -> t
val diff_weeks : t -> t -> int

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
diff --git a/timedesc/Timedesc/ISO_week_date_time/index.html b/timedesc/Timedesc/ISO_week_date_time/index.html index d25e80f1..7b68c09f 100644 --- a/timedesc/Timedesc/ISO_week_date_time/index.html +++ b/timedesc/Timedesc/ISO_week_date_time/index.html @@ -1,5 +1,5 @@ -ISO_week_date_time (timedesc.Timedesc.ISO_week_date_time)

Module Timedesc.ISO_week_date_time

type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
  4. | `Invalid_hour of int
  5. | `Invalid_minute of int
  6. | `Invalid_second of int
  7. | `Invalid_s_frac of float
  8. | `Invalid_ns of int
  9. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string
val make : +ISO_week_date_time (timedesc.Timedesc.ISO_week_date_time)

Module Timedesc.ISO_week_date_time

type error = [
  1. | `Does_not_exist
  2. | `Invalid_iso_year of int
  3. | `Invalid_iso_week of int
  4. | `Invalid_hour of int
  5. | `Invalid_minute of int
  6. | `Invalid_second of int
  7. | `Invalid_s_frac of float
  8. | `Invalid_ns of int
  9. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string
val make : ?tz:Time_zone.t -> ?ns:int -> ?s_frac:float -> diff --git a/timedesc/Timedesc/Interval/index.html b/timedesc/Timedesc/Interval/index.html index 7d2bc924..ed24d578 100644 --- a/timedesc/Timedesc/Interval/index.html +++ b/timedesc/Timedesc/Interval/index.html @@ -1,5 +1,5 @@ -Interval (timedesc.Timedesc.Interval)

Module Timedesc.Interval

type t = timestamp * timestamp

Left-closed, right-open interval, i.e. interval is * of the form [x, y), which includes x and excludes y

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Pretty printing

val pp : +Interval (timedesc.Timedesc.Interval)

Module Timedesc.Interval

type t = timestamp * timestamp

Left-closed, right-open interval, i.e. interval is * of the form [x, y), which includes x and excludes y

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Pretty printing

val pp : ?display_using_tz:Time_zone.t -> ?format:string -> unit -> diff --git a/timedesc/Timedesc/Span/For_human/index.html b/timedesc/Timedesc/Span/For_human/index.html index 771431ff..5c824de7 100644 --- a/timedesc/Timedesc/Span/For_human/index.html +++ b/timedesc/Timedesc/Span/For_human/index.html @@ -1,5 +1,5 @@ -For_human (timedesc.Timedesc.Span.For_human)

Module Span.For_human

type sign = [
  1. | `Pos
  2. | `Neg
]
type view = private {
  1. sign : sign;
  2. days : int;
  3. hours : int;
  4. minutes : int;
  5. seconds : int;
  6. ns : int;
}
type error = [
  1. | `Invalid_days of int
  2. | `Invalid_hours of int
  3. | `Invalid_minutes of int
  4. | `Invalid_seconds of int
  5. | `Invalid_ns of int
]
type error_f = [
  1. | `Invalid_days_f of float
  2. | `Invalid_hours_f of float
  3. | `Invalid_minutes_f of float
  4. | `Invalid_seconds_f of float
  5. | `Invalid_ns of int
]
exception Error_exn of error
exception Error_f_exn of error_f

Constructors

val make : +For_human (timedesc.Timedesc.Span.For_human)

Module Span.For_human

type sign = [
  1. | `Pos
  2. | `Neg
]
type view = private {
  1. sign : sign;
  2. days : int;
  3. hours : int;
  4. minutes : int;
  5. seconds : int;
  6. ns : int;
}
type error = [
  1. | `Invalid_days of int
  2. | `Invalid_hours of int
  3. | `Invalid_minutes of int
  4. | `Invalid_seconds of int
  5. | `Invalid_ns of int
]
type error_f = [
  1. | `Invalid_days_f of float
  2. | `Invalid_hours_f of float
  3. | `Invalid_minutes_f of float
  4. | `Invalid_seconds_f of float
  5. | `Invalid_ns of int
]
exception Error_exn of error
exception Error_f_exn of error_f

Constructors

val make : ?sign:sign -> ?days:int -> ?hours:int -> diff --git a/timedesc/Timedesc/Span/index.html b/timedesc/Timedesc/Span/index.html index a7252b13..65ef9232 100644 --- a/timedesc/Timedesc/Span/index.html +++ b/timedesc/Timedesc/Span/index.html @@ -1,2 +1,2 @@ -Span (timedesc.Timedesc.Span)

Module Timedesc.Span

type t

Signed/directional span of time with nanosecond precision

exception Out_of_range

Constants

val ns_count_in_s : int
val ns_count_in_s_float : float
val zero : t

Constructors

val make : ?s:int64 -> ?ns:int -> unit -> t

s defaults to 0L, ns defaults to 0.

ns may be negative, and is normalized during construction.

Interpretation of provided input is still s + ns, i.e. if you wish to represent "negative (1 second and 500 nanosecond)", then the call could look like make ~s:(-1L) ~ns:(-500).

  • raises Out_of_range

    if the value cannot be represented even after normalization

val make_small : ?s:int -> ?ns:int -> unit -> t

Wrapper around make

Conversion

val to_s_ns : t -> int64 * int

Yields pair (s, ns) where

  • s is the signed second of the span
  • ns is the unsigned nanosecond offset

The actual span represented is defined as s * 10^9 + ns in nanosecond regardless of the sign of s.

ns is always >= 0 and < 1_000_000_000.

val to_float_s : t -> float

Returns span in seconds, fraction represents subsecond span.

Representation is the same as result from Unix.gettimeofday.

val of_float_s : float -> t

Convert from span in seconds, fraction represents subsecond span

Representation is the same as result from Unix.gettimeofday.

Accessors

val get_s : t -> int64

Yields signed second of span, same as fst (to_s_ns _)

val get_ns_offset : t -> int

Yields the unsigned nanosecond offset, same as snd (to_s_ns _)

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : t -> t -> t
val sub : t -> t -> t
val succ : t -> t
val pred : t -> t
val neg : t -> t
val abs : t -> t
val max : t -> t -> t
val min : t -> t -> t
val ceil : t -> t

Rounds up to nearest second

val floor : t -> t

Rounds down to nearest second

val round : t -> t

Rounds to nearest second

For round x

  • if x.ns >= 500_000_000, then round x = ceil x
  • otherwise round x = floor x
val (<) : t -> t -> bool
val (<=) : t -> t -> bool
val (>) : t -> t -> bool
val (>=) : t -> t -> bool
val (=) : t -> t -> bool
val (<>) : t -> t -> bool
val (-) : t -> t -> t
val (+) : t -> t -> t

Pretty printing

val to_string : t -> string
val pp : Stdlib.Format.formatter -> t -> unit

Human friendly APIs

module For_human : sig ... end
+Span (timedesc.Timedesc.Span)

Module Timedesc.Span

type t

Signed/directional span of time with nanosecond precision

exception Out_of_range

Constants

val ns_count_in_s : int
val ns_count_in_s_float : float
val zero : t

Constructors

val make : ?s:int64 -> ?ns:int -> unit -> t

s defaults to 0L, ns defaults to 0.

ns may be negative, and is normalized during construction.

Interpretation of provided input is still s + ns, i.e. if you wish to represent "negative (1 second and 500 nanosecond)", then the call could look like make ~s:(-1L) ~ns:(-500).

  • raises Out_of_range

    if the value cannot be represented even after normalization

val make_small : ?s:int -> ?ns:int -> unit -> t

Wrapper around make

Conversion

val to_s_ns : t -> int64 * int

Yields pair (s, ns) where

  • s is the signed second of the span
  • ns is the unsigned nanosecond offset

The actual span represented is defined as s * 10^9 + ns in nanosecond regardless of the sign of s.

ns is always >= 0 and < 1_000_000_000.

val to_float_s : t -> float

Returns span in seconds, fraction represents subsecond span.

Representation is the same as result from Unix.gettimeofday.

val of_float_s : float -> t

Convert from span in seconds, fraction represents subsecond span

Representation is the same as result from Unix.gettimeofday.

Accessors

val get_s : t -> int64

Yields signed second of span, same as fst (to_s_ns _)

val get_ns_offset : t -> int

Yields the unsigned nanosecond offset, same as snd (to_s_ns _)

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : t -> t -> t
val sub : t -> t -> t
val succ : t -> t
val pred : t -> t
val neg : t -> t
val abs : t -> t
val max : t -> t -> t
val min : t -> t -> t
val ceil : t -> t

Rounds up to nearest second

val floor : t -> t

Rounds down to nearest second

val round : t -> t

Rounds to nearest second

For round x

  • if x.ns >= 500_000_000, then round x = ceil x
  • otherwise round x = floor x
val (<) : t -> t -> bool
val (<=) : t -> t -> bool
val (>) : t -> t -> bool
val (>=) : t -> t -> bool
val (=) : t -> t -> bool
val (<>) : t -> t -> bool
val (-) : t -> t -> t
val (+) : t -> t -> t

Pretty printing

val to_string : t -> string
val pp : Stdlib.Format.formatter -> t -> unit

Human friendly APIs

module For_human : sig ... end
diff --git a/timedesc/Timedesc/Time/index.html b/timedesc/Timedesc/Time/index.html index e4bd090b..c50bca90 100644 --- a/timedesc/Timedesc/Time/index.html +++ b/timedesc/Timedesc/Time/index.html @@ -1,5 +1,5 @@ -Time (timedesc.Timedesc.Time)

Module Timedesc.Time

type t

Representation of time of day

type view = private {
  1. hour : int;
  2. minute : int;
  3. second : int;
  4. ns : int;
}
type error = [
  1. | `Invalid_hour of int
  2. | `Invalid_minute of int
  3. | `Invalid_second of int
  4. | `Invalid_s_frac of float
  5. | `Invalid_ns of int
]
exception Error_exn of error

Constructors

val make : +Time (timedesc.Timedesc.Time)

Module Timedesc.Time

type t

Representation of time of day

type view = private {
  1. hour : int;
  2. minute : int;
  3. second : int;
  4. ns : int;
}
type error = [
  1. | `Invalid_hour of int
  2. | `Invalid_minute of int
  3. | `Invalid_second of int
  4. | `Invalid_s_frac of float
  5. | `Invalid_ns of int
]
exception Error_exn of error

Constructors

val make : ?ns:int -> ?s_frac:float -> hour:int -> diff --git a/timedesc/Timedesc/Time_zone/Compressed/index.html b/timedesc/Timedesc/Time_zone/Compressed/index.html index 57827a51..cd42a29b 100644 --- a/timedesc/Timedesc/Time_zone/Compressed/index.html +++ b/timedesc/Timedesc/Time_zone/Compressed/index.html @@ -1,2 +1,2 @@ -Compressed (timedesc.Timedesc.Time_zone.Compressed)

Module Time_zone.Compressed

val to_string : t -> string
val of_string : string -> t option
val of_string_exn : string -> t
+Compressed (timedesc.Timedesc.Time_zone.Compressed)

Module Time_zone.Compressed

val to_string : t -> string
val of_string : string -> t option
val of_string_exn : string -> t
diff --git a/timedesc/Timedesc/Time_zone/Db/Compressed/index.html b/timedesc/Timedesc/Time_zone/Db/Compressed/index.html index 502f1c62..33891a22 100644 --- a/timedesc/Timedesc/Time_zone/Db/Compressed/index.html +++ b/timedesc/Timedesc/Time_zone/Db/Compressed/index.html @@ -1,2 +1,2 @@ -Compressed (timedesc.Timedesc.Time_zone.Db.Compressed)

Module Db.Compressed

val to_string : db -> string
val half_compressed_of_string : string -> string Timedesc_tzdb.M.t option
val half_compressed_of_string_exn : string -> string Timedesc_tzdb.M.t
val of_string : string -> db option
val of_string_exn : string -> db
+Compressed (timedesc.Timedesc.Time_zone.Db.Compressed)

Module Db.Compressed

val to_string : db -> string
val half_compressed_of_string : string -> string Timedesc_tzdb.M.t option
val half_compressed_of_string_exn : string -> string Timedesc_tzdb.M.t
val of_string : string -> db option
val of_string_exn : string -> db
diff --git a/timedesc/Timedesc/Time_zone/Db/index.html b/timedesc/Timedesc/Time_zone/Db/index.html index e0e0b664..296da956 100644 --- a/timedesc/Timedesc/Time_zone/Db/index.html +++ b/timedesc/Timedesc/Time_zone/Db/index.html @@ -1,2 +1,2 @@ -Db (timedesc.Timedesc.Time_zone.Db)

Module Time_zone.Db

type db = Timedesc_tzdb.table Timedesc_tzdb.M.t
val empty : db
val add : t -> db -> db
val find_opt : string -> db -> t option
val remove : string -> db -> db
val of_seq : t Stdlib.Seq.t -> db
val add_seq : db -> t Stdlib.Seq.t -> db
val names : db -> string list
module Compressed : sig ... end
+Db (timedesc.Timedesc.Time_zone.Db)

Module Time_zone.Db

type db = Timedesc_tzdb.table Timedesc_tzdb.M.t
val empty : db
val add : t -> db -> db
val find_opt : string -> db -> t option
val remove : string -> db -> db
val of_seq : t Stdlib.Seq.t -> db
val add_seq : db -> t Stdlib.Seq.t -> db
val names : db -> string list
module Compressed : sig ... end
diff --git a/timedesc/Timedesc/Time_zone/Raw/index.html b/timedesc/Timedesc/Time_zone/Raw/index.html index 389bdde2..a884b081 100644 --- a/timedesc/Timedesc/Time_zone/Raw/index.html +++ b/timedesc/Timedesc/Time_zone/Raw/index.html @@ -1,2 +1,2 @@ -Raw (timedesc.Timedesc.Time_zone.Raw)

Module Time_zone.Raw

val of_table : name:string -> Timedesc_tzdb.table -> t option
val of_table_exn : name:string -> Timedesc_tzdb.table -> t
val of_transitions : name:string -> (int64 * entry) list -> t option
val to_transitions : t -> ((int64 * int64) * entry) list
val to_transition_seq : t -> ((int64 * int64) * entry) Stdlib.Seq.t
+Raw (timedesc.Timedesc.Time_zone.Raw)

Module Time_zone.Raw

val of_table : name:string -> Timedesc_tzdb.table -> t option
val of_table_exn : name:string -> Timedesc_tzdb.table -> t
val of_transitions : name:string -> (int64 * entry) list -> t option
val to_transitions : t -> ((int64 * int64) * entry) list
val to_transition_seq : t -> ((int64 * int64) * entry) Stdlib.Seq.t
diff --git a/timedesc/Timedesc/Time_zone/index.html b/timedesc/Timedesc/Time_zone/index.html index 0607a5d4..641af21e 100644 --- a/timedesc/Timedesc/Time_zone/index.html +++ b/timedesc/Timedesc/Time_zone/index.html @@ -1,2 +1,2 @@ -Time_zone (timedesc.Timedesc.Time_zone)

Module Timedesc.Time_zone

type t
val make : string -> t option

Makes a time zone from name.

Naming follows the convention used in /usr/share/zoneinfo/posix/ distributed on Linux, e.g. "Australia/Sydney".

See available_time_zones for checking usable time zone names at runtime.

Alternatively, if you are using timedesc.tzdb.full (the default implementation for timedesc.tzdb), then you can also see available-time-zones.txt for available time zones.

make handles names with "UTC" prefix specially, following holds regardless of DB backend chosen

  • UTC is alway interpreted as utc
  • UTC+/-offset is always interpreted as call to make_offset_only with the provided signed offset
    • e.g. "UTC+1:30" is equivalent to make_offset_only (Span.For_human.make_exn ~hours:1 ~minutes:30 ())
    • offset may be single/double digit hour, optionally followed by colon and single/double digit minute
val make_exn : string -> t
  • raises Invalid_argument

    if make fails

val name : t -> string
val utc : t
val local : unit -> t option
val local_exn : unit -> t
  • raises Invalid_argument

    when local returns None

val equal : t -> t -> bool
val recorded_offsets : t -> int list

Returns the recorded offsets of a time zone in ascending order

val available_time_zones : string list
val make_offset_only : Span.t -> t option

This is mainly used for when you only have an offset to work with, and you don't need to do any accurate search over time zones.

One use of this is to create a time zone for to_string functions.

Returns None when offset exceeds 24 hours in size.

val make_offset_only_exn : Span.t -> t
val to_fixed_offset_from_utc : t -> Span.t option

Importing and exporting

type entry = {
  1. is_dst : bool;
  2. offset : int;
}
module Raw : sig ... end
module Compressed : sig ... end
module Db : sig ... end
+Time_zone (timedesc.Timedesc.Time_zone)

Module Timedesc.Time_zone

type t
val make : string -> t option

Makes a time zone from name.

Naming follows the convention used in /usr/share/zoneinfo/posix/ distributed on Linux, e.g. "Australia/Sydney".

See available_time_zones for checking usable time zone names at runtime.

Alternatively, if you are using timedesc.tzdb.full (the default implementation for timedesc.tzdb), then you can also see available-time-zones.txt for available time zones.

make handles names with "UTC" prefix specially, following holds regardless of DB backend chosen

  • UTC is alway interpreted as utc
  • UTC+/-offset is always interpreted as call to make_offset_only with the provided signed offset
    • e.g. "UTC+1:30" is equivalent to make_offset_only (Span.For_human.make_exn ~hours:1 ~minutes:30 ())
    • offset may be single/double digit hour, optionally followed by colon and single/double digit minute
val make_exn : string -> t
  • raises Invalid_argument

    if make fails

val name : t -> string
val utc : t
val local : unit -> t option
val local_exn : unit -> t
  • raises Invalid_argument

    when local returns None

val equal : t -> t -> bool
val recorded_offsets : t -> int list

Returns the recorded offsets of a time zone in ascending order

val available_time_zones : string list
val make_offset_only : Span.t -> t option

This is mainly used for when you only have an offset to work with, and you don't need to do any accurate search over time zones.

One use of this is to create a time zone for to_string functions.

Returns None when offset exceeds 24 hours in size.

val make_offset_only_exn : Span.t -> t
val to_fixed_offset_from_utc : t -> Span.t option

Importing and exporting

type entry = {
  1. is_dst : bool;
  2. offset : int;
}
module Raw : sig ... end
module Compressed : sig ... end
module Db : sig ... end
diff --git a/timedesc/Timedesc/Time_zone_info/index.html b/timedesc/Timedesc/Time_zone_info/index.html index 5e7fdf63..9ba3de65 100644 --- a/timedesc/Timedesc/Time_zone_info/index.html +++ b/timedesc/Timedesc/Time_zone_info/index.html @@ -1,5 +1,5 @@ -Time_zone_info (timedesc.Timedesc.Time_zone_info)

Module Timedesc.Time_zone_info

type t

A possibly valid pairing of time zone and offset. Whether the pairing actually makes sense still depends on the attached date time (or similar data).

type error = [
  1. | `Missing_both_tz_and_offset_from_utc
  2. | `Invalid_offset of Span.t
  3. | `Unrecorded_offset of Span.t
]
val make : +Time_zone_info (timedesc.Timedesc.Time_zone_info)

Module Timedesc.Time_zone_info

type t

A possibly valid pairing of time zone and offset. Whether the pairing actually makes sense still depends on the attached date time (or similar data).

type error = [
  1. | `Missing_both_tz_and_offset_from_utc
  2. | `Invalid_offset of Span.t
  3. | `Unrecorded_offset of Span.t
]
val make : ?tz:Time_zone.t -> ?offset_from_utc:Span.t -> unit -> diff --git a/timedesc/Timedesc/Timestamp/index.html b/timedesc/Timedesc/Timestamp/index.html index ec080e17..1c81c22d 100644 --- a/timedesc/Timedesc/Timestamp/index.html +++ b/timedesc/Timedesc/Timestamp/index.html @@ -1,5 +1,5 @@ -Timestamp (timedesc.Timedesc.Timestamp)

Module Timedesc.Timestamp

Timestamp specific functions

type t = timestamp

Constants

val min_val : t
val max_val : t

Now

val now : unit -> t

Re-export from Span

Conversion

val to_s_ns : t -> int64 * int
val to_float_s : t -> float

Returns span in seconds, fraction represents subsecond span.

Representation is the same as result from Unix.gettimeofday.

val of_float_s : float -> t

Convert from span in seconds, fraction represents subsecond span

Representation is the same as result from Unix.gettimeofday.

Accessors

val get_s : t -> int64
val get_ns_offset : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : t -> t -> t
val sub : t -> t -> t
val succ : t -> t
val pred : t -> t
val neg : t -> t
val abs : t -> t
val max : t -> t -> t
val min : t -> t -> t
val ceil : t -> t
val floor : t -> t
val round : t -> t
val (<) : t -> t -> bool
val (<=) : t -> t -> bool
val (>) : t -> t -> bool
val (>=) : t -> t -> bool
val (=) : t -> t -> bool
val (<>) : t -> t -> bool
val (-) : t -> t -> t
val (+) : t -> t -> t

Pretty printing

val pp : +Timestamp (timedesc.Timedesc.Timestamp)

Module Timedesc.Timestamp

Timestamp specific functions

type t = timestamp

Constants

val min_val : t
val max_val : t

Now

val now : unit -> t

Re-export from Span

Conversion

val to_s_ns : t -> int64 * int
val to_float_s : t -> float

Returns span in seconds, fraction represents subsecond span.

Representation is the same as result from Unix.gettimeofday.

val of_float_s : float -> t

Convert from span in seconds, fraction represents subsecond span

Representation is the same as result from Unix.gettimeofday.

Accessors

val get_s : t -> int64
val get_ns_offset : t -> int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : t -> t -> t
val sub : t -> t -> t
val succ : t -> t
val pred : t -> t
val neg : t -> t
val abs : t -> t
val max : t -> t -> t
val min : t -> t -> t
val ceil : t -> t
val floor : t -> t
val round : t -> t
val (<) : t -> t -> bool
val (<=) : t -> t -> bool
val (>) : t -> t -> bool
val (>=) : t -> t -> bool
val (=) : t -> t -> bool
val (<>) : t -> t -> bool
val (-) : t -> t -> t
val (+) : t -> t -> t

Pretty printing

val pp : ?display_using_tz:Time_zone.t -> ?format:string -> unit -> diff --git a/timedesc/Timedesc/Utils/index.html b/timedesc/Timedesc/Utils/index.html index 995f0b9d..7bf2584f 100644 --- a/timedesc/Timedesc/Utils/index.html +++ b/timedesc/Timedesc/Utils/index.html @@ -1,2 +1,2 @@ -Utils (timedesc.Timedesc.Utils)

Module Timedesc.Utils

val ptime_span_of_span : Span.t -> Ptime.span option
val ptime_of_timestamp : timestamp -> Ptime.t option
val span_of_ptime_span : Ptime.span -> Span.t

Warning: Subnanosecond information is lost in this conversion

val timestamp_of_ptime : Ptime.t -> timestamp

Warning: Subnanosecond information is lost in this conversion

val day_count_of_year : year:int -> int
val day_count_of_month : year:int -> month:int -> int
val week_count_of_iso_year : year:int -> int

Month utils

type month = [
  1. | `Jan
  2. | `Feb
  3. | `Mar
  4. | `Apr
  5. | `May
  6. | `Jun
  7. | `Jul
  8. | `Aug
  9. | `Sep
  10. | `Oct
  11. | `Nov
  12. | `Dec
]
val human_int_of_month : month -> int

This yields the usual human readable numbering of 1 to 12 inclusive

val index_of_month : month -> int

This yields the index based numbering of 0 to 11 inclusive

val month_of_human_int : int -> month option
val month_of_index : int -> month option
val weekday_of_tm_int : int -> weekday option
val tm_int_of_weekday : weekday -> int
val weekday_of_iso_int : int -> weekday option
val iso_int_of_weekday : weekday -> int
val get_local_tz_for_arg : unit -> Time_zone.t
val abbr_string_of_weekday : weekday -> string

Warning: Following functions are direct applications of the relevant formulas with little to no error checking.

You are advised to read the source code of the following functions in date_time_utils.ml if you intend to use them to ensure they behave as you expect.

val is_leap_year : year:int -> bool
val jd_of_ymd : year:int -> month:int -> day:int -> int
val jd_of_ydoy : year:int -> day_of_year:int -> int
val jd_of_date : Date.t -> int
val jd_of_unix_epoch : int
val jd_span_of_unix_epoch : Span.t
val jd_of_iso_week_date : year:int -> week:int -> weekday:weekday -> int
val ymd_of_jd : int -> int * int * int
val weekday_of_jd : int -> weekday
val iso_week_date_of_jd : int -> int * int * weekday
val doy_of_ymd : year:int -> month:int -> day:int -> int
+Utils (timedesc.Timedesc.Utils)

Module Timedesc.Utils

val ptime_span_of_span : Span.t -> Ptime.span option
val ptime_of_timestamp : timestamp -> Ptime.t option
val span_of_ptime_span : Ptime.span -> Span.t

Warning: Subnanosecond information is lost in this conversion

val timestamp_of_ptime : Ptime.t -> timestamp

Warning: Subnanosecond information is lost in this conversion

val day_count_of_year : year:int -> int
val day_count_of_month : year:int -> month:int -> int
val week_count_of_iso_year : year:int -> int

Month utils

type month = [
  1. | `Jan
  2. | `Feb
  3. | `Mar
  4. | `Apr
  5. | `May
  6. | `Jun
  7. | `Jul
  8. | `Aug
  9. | `Sep
  10. | `Oct
  11. | `Nov
  12. | `Dec
]
val human_int_of_month : month -> int

This yields the usual human readable numbering of 1 to 12 inclusive

val index_of_month : month -> int

This yields the index based numbering of 0 to 11 inclusive

val month_of_human_int : int -> month option
val month_of_index : int -> month option
val weekday_of_tm_int : int -> weekday option
val tm_int_of_weekday : weekday -> int
val weekday_of_iso_int : int -> weekday option
val iso_int_of_weekday : weekday -> int
val get_local_tz_for_arg : unit -> Time_zone.t
val abbr_string_of_weekday : weekday -> string

Warning: Following functions are direct applications of the relevant formulas with little to no error checking.

You are advised to read the source code of the following functions in date_time_utils.ml if you intend to use them to ensure they behave as you expect.

val is_leap_year : year:int -> bool
val jd_of_ymd : year:int -> month:int -> day:int -> int
val jd_of_ydoy : year:int -> day_of_year:int -> int
val jd_of_date : Date.t -> int
val jd_of_unix_epoch : int
val jd_span_of_unix_epoch : Span.t
val jd_of_iso_week_date : year:int -> week:int -> weekday:weekday -> int
val ymd_of_jd : int -> int * int * int
val weekday_of_jd : int -> weekday
val iso_week_date_of_jd : int -> int * int * weekday
val doy_of_ymd : year:int -> month:int -> day:int -> int
diff --git a/timedesc/Timedesc/Ym/index.html b/timedesc/Timedesc/Ym/index.html index 7a16181e..166378eb 100644 --- a/timedesc/Timedesc/Ym/index.html +++ b/timedesc/Timedesc/Ym/index.html @@ -1,2 +1,2 @@ -Ym (timedesc.Timedesc.Ym)

Module Timedesc.Ym

type t
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
]
exception Error_exn of error

Constructors

val make : year:int -> month:int -> (t, error) Stdlib.result
val make_exn : year:int -> month:int -> t

Accessors

val year : t -> int
val month : t -> int
val year_month : t -> int * int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : ?years:int -> ?months:int -> t -> t
val sub : ?years:int -> ?months:int -> t -> t
val diff_months : t -> t -> int

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
+Ym (timedesc.Timedesc.Ym)

Module Timedesc.Ym

type t
type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
]
exception Error_exn of error

Constructors

val make : year:int -> month:int -> (t, error) Stdlib.result
val make_exn : year:int -> month:int -> t

Accessors

val year : t -> int
val month : t -> int
val year_month : t -> int * int

Comparison

val equal : t -> t -> bool
val lt : t -> t -> bool
val le : t -> t -> bool
val gt : t -> t -> bool
val ge : t -> t -> bool
val compare : t -> t -> int

Arithmetic

val add : ?years:int -> ?months:int -> t -> t
val sub : ?years:int -> ?months:int -> t -> t
val diff_months : t -> t -> int

Pretty printing

val pp_iso8601 : Stdlib.Format.formatter -> t -> unit
val to_iso8601 : t -> string

Parsing

val of_iso8601 : string -> (t, string) Stdlib.result
val of_iso8601_exn : string -> t
diff --git a/timedesc/Timedesc/Zoneless/index.html b/timedesc/Timedesc/Zoneless/index.html index 9dcff6b2..1d7583a1 100644 --- a/timedesc/Timedesc/Zoneless/index.html +++ b/timedesc/Timedesc/Zoneless/index.html @@ -1,5 +1,5 @@ -Zoneless (timedesc.Timedesc.Zoneless)

Module Timedesc.Zoneless

type zoneless
type error_when_zoned = [
  1. | `Does_not_exist
  2. | `Invalid_tz_info of string option * Span.t
]
exception Error_when_zoned_exn of error_when_zoned

Constructors

val of_date_and_time : Date.t -> Time.t -> zoneless

Accessors

val date : zoneless -> Date.t
val time : zoneless -> Time.t

Comparison

val equal : zoneless -> zoneless -> bool

Conversion

val to_timestamp_local : zoneless -> timestamp

This yields a "local timestamp" - we pretend we are in the UTC time zone, and calculate seconds since unix epoch

val to_zoned : +Zoneless (timedesc.Timedesc.Zoneless)

Module Timedesc.Zoneless

type zoneless
type error_when_zoned = [
  1. | `Does_not_exist
  2. | `Invalid_tz_info of string option * Span.t
]
exception Error_when_zoned_exn of error_when_zoned

Constructors

val of_date_and_time : Date.t -> Time.t -> zoneless

Accessors

val date : zoneless -> Date.t
val time : zoneless -> Time.t

Comparison

val equal : zoneless -> zoneless -> bool

Conversion

val to_timestamp_local : zoneless -> timestamp

This yields a "local timestamp" - we pretend we are in the UTC time zone, and calculate seconds since unix epoch

val to_zoned : ?tz:Time_zone.t -> zoneless -> (t, error_when_zoned) Stdlib.result

tz defaults to result of Utils.get_local_tz_for_arg

val to_zoned_exn : ?tz:Time_zone.t -> zoneless -> t
val to_zoned_unambiguous : diff --git a/timedesc/Timedesc/index.html b/timedesc/Timedesc/index.html index 488c37c4..14eea839 100644 --- a/timedesc/Timedesc/index.html +++ b/timedesc/Timedesc/index.html @@ -1,5 +1,5 @@ -Timedesc (timedesc.Timedesc)

Module Timedesc

Time description and manipulations

Timedesc provides utilities to describe points of time, and properly handle calendar and time zone information.

Tutorial

Getting started

Suppose we want to get the time right now, we can simply do Timedesc.now (). But what if we want to get the time right now in a different time zone? Say New York? Then we can simply do:

Timedesc.now ~tz_of_date_time:(Timedesc.Time_zone.make_exn "America/New_York") ().

And if we want to construct a date time from scratch, we can use constructors such as make, with similar time zone specification:

Timedesc.make ~tz:(Timedesc.Time_zone.make_exn "Australia/Sydney") ~year:2021 ~month:5 ~day:30 ~hour:14 ~minute:10 ~second:0 ().

Since we deal with timestamps quite frequently, lets have a look at how Timedesc also makes working with them easier. Suppose we receive a timestamp similar to the result returned by Unix.gettimeofday, i.e. seconds since unix epoch in float, we can digest it in myriad ways. If we just want to construct a date time out of it, then we can use of_timestamp_float_s. If we want to get it into the representation used in Timedesc, say to perform arithmetic operations over it etc, then we can use Timestamp.of_float_s. But in either case, we can always swap back and forth via to_timestamp and of_timestamp.

In general it is better to use timestamp as much as possible, unless you require a precision higher than nanosecond. This is because floating point is a lossy representation - if you convert a date time to floating point and back, you may not get the same date time back (i.e. it may not round trip). Also, performing arithmetic operations over floating points can introduce more and more errors, and it is advisable to use the arithmetic functions provided in Span or Timestamp.

To access the values of date time, we can use the constructors such as year, month, day, hour.

Time zone

By now, one nicety should be obvious: you don't have to worry about what is the time zone offset at when and where - Timedesc takes care of that for you properly! All you have to do is to make a time zone following the *nix naming convention. However, even though we follow the same naming convention, we don't actually rely on the OS time zone database, and our code will run fine on any platform.

To see what time zones Timedesc supports during run time, we can refer to Time_zone.available_time_zones. Alternatively, for a text file containing all the supported time zones by default, refer to available-time-zones.txt in the repository.

If you are aware of DST: Yes, Timedesc takes care of that for you properly as well - Timedesc does not allow you to construct a date time that does not exist for the particular time zone, and any ambiguity is made explicit as return type via local_date_time_result.

This does mean Timedesc does not "resolve" the result into one of the possibilities arbitrarily, and you need to resolve the ambiguity yourself. If such a coercion is desirable, however, then you can use either min_of_local_date_time_result or max_of_local_date_time_result.

Span/duration

Timedesc offers both machine-friendly and human-friendly ways of dealing with spans.

For the machine-friendly side, functions in the top level of Span provide efficient constructions and arithmetic operations.

For the human-friendly side, Span.For_human provides functions which work at a level closer to human language. For instance, we say things like "2 hours and 15 minutes" quite frequently, to represent this as Span.t, we can do:

Timedesc.Span.For_human.make_exn ~hours:2 ~minutes:15 ()

And in the case of fractional descriptions, such as "1.5 hours", we can do:

Timedesc.Span.For_human.make_frac_exn ~hours:1.5 ()

Finally, to access the human friendly "view", we can use Span.For_human.view.

Using both Ptime and Timedesc

Ptime is a (very) commonly used package in projects due to being very portable, and robust. However, it lacks certain features which Timedesc provides, such as first class support for time zones, support for different date systems. As such one may wish to use both Ptime and Timedesc, especially if Ptime is already being used for a particular project.

To facilitate such use of both Ptime and Timedesc, utilities for converting to and from Ptime types are available as:

Note that Timedesc only supports nanosecond precision, while Ptime supports picosecond precision. If subnanosecond precision is a concern for you, then the above functions are not suitable.

Advanced usage

Unambiguous date time

Occasionally, we receive date times which carry both the time zone and the exact offset from UTC. Naturally we can discard the time zone since the offset alone suffices in deducing the precise timestamp. However, we can actually ask Timedesc to digest both via make_unambiguous, which checks the offset against the time zone record to make sure it is actually a possible offset.

Other calendar systems

Other than Gregorian calendar, Timedesc also supports ISO week date and ISO ordinal date.

To construct date time in the alternative systems, we can use constructors such as ISO_week_date_time.make and ISO_ord_date_time.make.

Then to access the representation in the alternative date systems, we can use accessors such as iso_week, and day_of_year.

Using date by itself

Sometimes we are only interested in the date component rather than both date and time. We can use Date module in this case.

To construct a Gregorian calendar date, we can use Date.Ymd.make. To construct ISO week date and ISO ordinal date, we can use Date.ISO_week_date.make and Date.ISO_ord.make respectively.

We have similar set of accessors for accessing values of Date.t, such as Date.year, Date.iso_week, Date.day_of_year.

To obtain a "view" (in a manner similar to the human-friendly "view" from Span.For_human), we can use Date.ISO_week_date.view and Date.ISO_ord.view.

Further reading

Misconceptions

  • Time zone offsets are always in hours
  • What we typically consider a time zone, e.g. "Europe/Paris", always has a constant offset
  • With a time zone and a specific date time, we can always obtain a unique "unix timestamp" (time since unix epoch)
  • We can always calculate time zone offset at some date time, and apply it universally for any other date time in the same time zone
  • Many more on various online resources...

Time zone, time zone offset, and date time

It is tempting to think that a time zone maps cleanly to a constant offset, and indeed we may define time zone as such, e.g. UTC+1, UTC-10, but this is far from what we mean in everyday context.

Very often, what we consider to be time zone actually represents a table which records what offset to use in which period, which we index/refer to by geographical names like "Europe/Paris", "Australia/Sydney". These tables are defined by governmental bodies, and attributes of the table, such as offset of any particular period, start and end of any particular period, may not show any observable pattern.

Thus it is not uncommon to see date time errors arising from attempts of applying some formulas universally, which might work well for a lot of cases in contemporary time periods, but fail for some combinations.

We make explicit of above explanation by considering "Europe/Paris" as an example, which observes a common form of transition called Daylight Saving Time (DST).

When DST starts (usually in March), the clocks "jump forward" by 1 hour, usually jumping from 2am to 3am, leading 2am to 3am (exclusive) to become non-existent.

Indeed we can observe the lack of continuity of Europe/Paris timeline below (UTC timeline is always continuous):

                         Mar
+Timedesc (timedesc.Timedesc)

Module Timedesc

Time description and manipulations

Timedesc provides utilities to describe points of time, and properly handle calendar and time zone information.

Tutorial

Getting started

Suppose we want to get the time right now, we can simply do Timedesc.now (). But what if we want to get the time right now in a different time zone? Say New York? Then we can simply do:

Timedesc.now ~tz_of_date_time:(Timedesc.Time_zone.make_exn "America/New_York") ().

And if we want to construct a date time from scratch, we can use constructors such as make, with similar time zone specification:

Timedesc.make ~tz:(Timedesc.Time_zone.make_exn "Australia/Sydney") ~year:2021 ~month:5 ~day:30 ~hour:14 ~minute:10 ~second:0 ().

Since we deal with timestamps quite frequently, lets have a look at how Timedesc also makes working with them easier. Suppose we receive a timestamp similar to the result returned by Unix.gettimeofday, i.e. seconds since unix epoch in float, we can digest it in myriad ways. If we just want to construct a date time out of it, then we can use of_timestamp_float_s. If we want to get it into the representation used in Timedesc, say to perform arithmetic operations over it etc, then we can use Timestamp.of_float_s. But in either case, we can always swap back and forth via to_timestamp and of_timestamp.

In general it is better to use timestamp as much as possible, unless you require a precision higher than nanosecond. This is because floating point is a lossy representation - if you convert a date time to floating point and back, you may not get the same date time back (i.e. it may not round trip). Also, performing arithmetic operations over floating points can introduce more and more errors, and it is advisable to use the arithmetic functions provided in Span or Timestamp.

To access the values of date time, we can use the constructors such as year, month, day, hour.

Time zone

By now, one nicety should be obvious: you don't have to worry about what is the time zone offset at when and where - Timedesc takes care of that for you properly! All you have to do is to make a time zone following the *nix naming convention. However, even though we follow the same naming convention, we don't actually rely on the OS time zone database, and our code will run fine on any platform.

To see what time zones Timedesc supports during run time, we can refer to Time_zone.available_time_zones. Alternatively, for a text file containing all the supported time zones by default, refer to available-time-zones.txt in the repository.

If you are aware of DST: Yes, Timedesc takes care of that for you properly as well - Timedesc does not allow you to construct a date time that does not exist for the particular time zone, and any ambiguity is made explicit as return type via local_date_time_result.

This does mean Timedesc does not "resolve" the result into one of the possibilities arbitrarily, and you need to resolve the ambiguity yourself. If such a coercion is desirable, however, then you can use either min_of_local_date_time_result or max_of_local_date_time_result.

Span/duration

Timedesc offers both machine-friendly and human-friendly ways of dealing with spans.

For the machine-friendly side, functions in the top level of Span provide efficient constructions and arithmetic operations.

For the human-friendly side, Span.For_human provides functions which work at a level closer to human language. For instance, we say things like "2 hours and 15 minutes" quite frequently, to represent this as Span.t, we can do:

Timedesc.Span.For_human.make_exn ~hours:2 ~minutes:15 ()

And in the case of fractional descriptions, such as "1.5 hours", we can do:

Timedesc.Span.For_human.make_frac_exn ~hours:1.5 ()

Finally, to access the human friendly "view", we can use Span.For_human.view.

Using both Ptime and Timedesc

Ptime is a (very) commonly used package in projects due to being very portable, and robust. However, it lacks certain features which Timedesc provides, such as first class support for time zones, support for different date systems. As such one may wish to use both Ptime and Timedesc, especially if Ptime is already being used for a particular project.

To facilitate such use of both Ptime and Timedesc, utilities for converting to and from Ptime types are available as:

Note that Timedesc only supports nanosecond precision, while Ptime supports picosecond precision. If subnanosecond precision is a concern for you, then the above functions are not suitable.

Advanced usage

Unambiguous date time

Occasionally, we receive date times which carry both the time zone and the exact offset from UTC. Naturally we can discard the time zone since the offset alone suffices in deducing the precise timestamp. However, we can actually ask Timedesc to digest both via make_unambiguous, which checks the offset against the time zone record to make sure it is actually a possible offset.

Other calendar systems

Other than Gregorian calendar, Timedesc also supports ISO week date and ISO ordinal date.

To construct date time in the alternative systems, we can use constructors such as ISO_week_date_time.make and ISO_ord_date_time.make.

Then to access the representation in the alternative date systems, we can use accessors such as iso_week, and day_of_year.

Using date by itself

Sometimes we are only interested in the date component rather than both date and time. We can use Date module in this case.

To construct a Gregorian calendar date, we can use Date.Ymd.make. To construct ISO week date and ISO ordinal date, we can use Date.ISO_week_date.make and Date.ISO_ord.make respectively.

We have similar set of accessors for accessing values of Date.t, such as Date.year, Date.iso_week, Date.day_of_year.

To obtain a "view" (in a manner similar to the human-friendly "view" from Span.For_human), we can use Date.ISO_week_date.view and Date.ISO_ord.view.

Further reading

Misconceptions

  • Time zone offsets are always in hours
  • What we typically consider a time zone, e.g. "Europe/Paris", always has a constant offset
  • With a time zone and a specific date time, we can always obtain a unique "unix timestamp" (time since unix epoch)
  • We can always calculate time zone offset at some date time, and apply it universally for any other date time in the same time zone
  • Many more on various online resources...

Time zone, time zone offset, and date time

It is tempting to think that a time zone maps cleanly to a constant offset, and indeed we may define time zone as such, e.g. UTC+1, UTC-10, but this is far from what we mean in everyday context.

Very often, what we consider to be time zone actually represents a table which records what offset to use in which period, which we index/refer to by geographical names like "Europe/Paris", "Australia/Sydney". These tables are defined by governmental bodies, and attributes of the table, such as offset of any particular period, start and end of any particular period, may not show any observable pattern.

Thus it is not uncommon to see date time errors arising from attempts of applying some formulas universally, which might work well for a lot of cases in contemporary time periods, but fail for some combinations.

We make explicit of above explanation by considering "Europe/Paris" as an example, which observes a common form of transition called Daylight Saving Time (DST).

When DST starts (usually in March), the clocks "jump forward" by 1 hour, usually jumping from 2am to 3am, leading 2am to 3am (exclusive) to become non-existent.

Indeed we can observe the lack of continuity of Europe/Paris timeline below (UTC timeline is always continuous):

                         Mar
 UTC          -------------|-------------
                          1am
 
@@ -20,11 +20,11 @@
 
 Europe/Paris -------------|------------- ... -------------|-------------
                        2am 3am                         3am 2am
-                      (+1) (+2)                       (+2) (+1)

This start and end of the DST on and off periods, along with the corresponding offsets, form the basis of the table we mentioned above.

Timedesc date time API behaviour highlights

We highlight some critical cases in practice, and how Timedesc behaves and how it may differ from other libraries.

Take year 2021 for example, DST starts on 2021 Mar 28 for Paris, causing clocks to jump from 2am to 3am. Pick any intermediate point, say 2:30am, we yield an undefined date time. In this case, Timedesc refuses the construction of such t in make etc, while some libraries coerce the result into 3:30am.

And DST ends on 2021 Oct 31, causing clocks to jump from 3am to 2am. Say we pick 2:30am again, we are actually pointing at two time points (there are two 2:30am) unless we make an explicit selection between the first or second occurance. Whenever ambiguity of this form is a possiblity for the result of a function, say to_timestamp, Timedesc uses local_date_time_result variant type, of which `Single _ indicates lack of ambiguity for the particular result, and `Ambiguous _ indicates the result is ambiguous.

Some other libraries coerce the ambiguous result into one of the two possible choices (which exact one may not be guaranteed). If user wishes to do similar coercions, they may use min_of_local_date_time_result or max_of_local_date_time_result.

For constructions, make yields a possibly ambiguous construction, while make_unambiguous yields an unambiguous construction. In general, if you are provided with the exact offset to UTC, then make_unambiguous is the better choice.

Basic exceptions

exception Invalid_format_string of string

Printing exception

exception ISO8601_parse_exn of string
exception RFC9110_parse_exn of string

Basic types

type weekday = [
  1. | `Sun
  2. | `Mon
  3. | `Tue
  4. | `Wed
  5. | `Thu
  6. | `Fri
  7. | `Sat
]
type 'a local_date_time_result = [
  1. | `Single of 'a
  2. | `Ambiguous of 'a * 'a
]

Result for when a local date time may be involved, e.g. using a date time with no precise time zone offset attached.

  • `Single is yielded when the date time maps to exactly one 'a. This happens when date time carries an accurate offset, or when the date time is not affected by any offset shifts (thus an accurate offset can be inferred).
  • `Ambiguous is yielded when date time maps to more than one (exactly two) 'a. This happens when DST ends and "goes back an hour" for instance.
val min_of_local_date_time_result : 'a local_date_time_result -> 'a

For min_of_local_date_time_result x

  • if x = `Single a, yields a,
  • if x = `Ambiguous (a, b), yields a,
val max_of_local_date_time_result : 'a local_date_time_result -> 'a

For max_of_local_date_time_result x

  • if x = `Single a, yields a,
  • if x = `Ambiguous (a, b), yields b,
val equal_local_date_time_result : + (+1) (+2) (+2) (+1)

This start and end of the DST on and off periods, along with the corresponding offsets, form the basis of the table we mentioned above.

Timedesc date time API behaviour highlights

We highlight some critical cases in practice, and how Timedesc behaves and how it may differ from other libraries.

Take year 2021 for example, DST starts on 2021 Mar 28 for Paris, causing clocks to jump from 2am to 3am. Pick any intermediate point, say 2:30am, we yield an undefined date time. In this case, Timedesc refuses the construction of such t in make etc, while some libraries coerce the result into 3:30am.

And DST ends on 2021 Oct 31, causing clocks to jump from 3am to 2am. Say we pick 2:30am again, we are actually pointing at two time points (there are two 2:30am) unless we make an explicit selection between the first or second occurance. Whenever ambiguity of this form is a possiblity for the result of a function, say to_timestamp, Timedesc uses local_date_time_result variant type, of which `Single _ indicates lack of ambiguity for the particular result, and `Ambiguous _ indicates the result is ambiguous.

Some other libraries coerce the ambiguous result into one of the two possible choices (which exact one may not be guaranteed). If user wishes to do similar coercions, they may use min_of_local_date_time_result or max_of_local_date_time_result.

For constructions, make yields a possibly ambiguous construction, while make_unambiguous yields an unambiguous construction. In general, if you are provided with the exact offset to UTC, then make_unambiguous is the better choice.

Basic exceptions

exception Invalid_format_string of string

Printing exception

exception ISO8601_parse_exn of string
exception RFC9110_parse_exn of string

Basic types

type weekday = [
  1. | `Sun
  2. | `Mon
  3. | `Tue
  4. | `Wed
  5. | `Thu
  6. | `Fri
  7. | `Sat
]
type 'a local_date_time_result = [
  1. | `Single of 'a
  2. | `Ambiguous of 'a * 'a
]

Result for when a local date time may be involved, e.g. using a date time with no precise time zone offset attached.

  • `Single is yielded when the date time maps to exactly one 'a. This happens when date time carries an accurate offset, or when the date time is not affected by any offset shifts (thus an accurate offset can be inferred).
  • `Ambiguous is yielded when date time maps to more than one (exactly two) 'a. This happens when DST ends and "goes back an hour" for instance.
val min_of_local_date_time_result : 'a local_date_time_result -> 'a

For min_of_local_date_time_result x

  • if x = `Single a, yields a,
  • if x = `Ambiguous (a, b), yields a,
val max_of_local_date_time_result : 'a local_date_time_result -> 'a

For max_of_local_date_time_result x

  • if x = `Single a, yields a,
  • if x = `Ambiguous (a, b), yields b,
val equal_local_date_time_result : ('a -> 'a -> bool) -> 'a local_date_time_result -> 'a local_date_time_result -> - bool

Span

module Span : sig ... end
type timestamp = Span.t

Definition of timestamp throughout the library follows the "seconds since unix epoch" definition

Date time components

Partial date

Implementation of:

module Ym : sig ... end
module ISO_week : sig ... end

Date

Implementation of date in:

module Date : sig ... end

Time

Implementation of time of day with nanosecond precision

module Time : sig ... end

Time zone

Implementation of time zone which uses IANA time zone database underneath

module Time_zone : sig ... end

Date time

Implementation of time zone aware date time in:

type t

This is the main type, and represents a point in the local timeline with respect to the residing time zone. Conceptually a triple of "date", "time" (or "time of day"), and time zone.

A t always maps to at least one point on the UTC timeline, and make fails if this is not the case. t may also map to two points on the UTC timeline in the case of DST and without an unambiguous offset, however.

In the ambiguous case, functions which return _ local_date_time_result will yield an `Ambiguous _ value, and `Single _ otherwise.

ns may be >= 10^9 to represent leap second, but always remains < 2 * 10^9.

s is always >= 0 and < 60, even when second 60 is used during construction. In other words, second 60 is represented via ns field.

type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
  4. | `Invalid_day of int
  5. | `Invalid_hour of int
  6. | `Invalid_minute of int
  7. | `Invalid_second of int
  8. | `Invalid_s_frac of float
  9. | `Invalid_ns of int
  10. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string

Constructors

val make : + bool

Span

module Span : sig ... end
type timestamp = Span.t

Definition of timestamp throughout the library follows the "seconds since unix epoch" definition

Date time components

Partial date

Implementation of:

module Ym : sig ... end
module ISO_week : sig ... end

Date

Implementation of date in:

module Date : sig ... end

Time

Implementation of time of day with nanosecond precision

module Time : sig ... end

Time zone

Implementation of time zone which uses IANA time zone database underneath

module Time_zone : sig ... end

Date time

Implementation of time zone aware date time in:

type t

This is the main type, and represents a point in the local timeline with respect to the residing time zone. Conceptually a triple of "date", "time" (or "time of day"), and time zone.

A t always maps to at least one point on the UTC timeline, and make fails if this is not the case. t may also map to two points on the UTC timeline in the case of DST and without an unambiguous offset, however.

In the ambiguous case, functions which return _ local_date_time_result will yield an `Ambiguous _ value, and `Single _ otherwise.

ns may be >= 10^9 to represent leap second, but always remains < 2 * 10^9.

s is always >= 0 and < 60, even when second 60 is used during construction. In other words, second 60 is represented via ns field.

type error = [
  1. | `Does_not_exist
  2. | `Invalid_year of int
  3. | `Invalid_month of int
  4. | `Invalid_day of int
  5. | `Invalid_hour of int
  6. | `Invalid_minute of int
  7. | `Invalid_second of int
  8. | `Invalid_s_frac of float
  9. | `Invalid_ns of int
  10. | `Invalid_tz_info of string option * Span.t
]
exception Error_exn of error
val string_of_error : error -> string

Constructors

val make : ?tz:Time_zone.t -> ?ns:int -> ?s_frac:float -> diff --git a/timedesc/index.html b/timedesc/index.html index a91317a7..c62f5c41 100644 --- a/timedesc/index.html +++ b/timedesc/index.html @@ -1,2 +1,2 @@ -index (timedesc.index)

timedesc index

Library timedesc

The entry point of this library is the module: Timedesc.

+index (timedesc.index)

timedesc index

Library timedesc

The entry point of this library is the module: Timedesc.

diff --git a/timere-parse/Timere_parse/index.html b/timere-parse/Timere_parse/index.html index 213dbd24..a4e80c33 100644 --- a/timere-parse/Timere_parse/index.html +++ b/timere-parse/Timere_parse/index.html @@ -1,5 +1,5 @@ -Timere_parse (timere-parse.Timere_parse)

Module Timere_parse

exception Error_exn of string
val timere : string -> (Timere.t, string) Stdlib.result
val timere_exn : string -> Timere.t
val date_time : +Timere_parse (timere-parse.Timere_parse)

Module Timere_parse

exception Error_exn of string
val timere : string -> (Timere.t, string) Stdlib.result
val timere_exn : string -> Timere.t
val date_time : ?tz:Timedesc.Time_zone.t -> string -> (Timedesc.t, string) Stdlib.result
val date_time_exn : ?tz:Timedesc.Time_zone.t -> string -> Timedesc.t
val hms : string -> (Timedesc.Time.t, string) Stdlib.result
val hms_exn : string -> Timedesc.Time.t
val span : string -> (Timedesc.Span.t, string) Stdlib.result
val span_exn : string -> Timedesc.Span.t
diff --git a/timere-parse/index.html b/timere-parse/index.html index df659ac9..20fbd47b 100644 --- a/timere-parse/index.html +++ b/timere-parse/index.html @@ -1,2 +1,2 @@ -index (timere-parse.index)

timere-parse index

Library timere-parse

The entry point of this library is the module: Timere_parse.

+index (timere-parse.index)

timere-parse index

Library timere-parse

The entry point of this library is the module: Timere_parse.

diff --git a/timere/Timere/Points/index.html b/timere/Timere/Points/index.html index cfb82e30..511169a5 100644 --- a/timere/Timere/Points/index.html +++ b/timere/Timere/Points/index.html @@ -1,5 +1,5 @@ -Points (timere.Timere.Points)

Module Timere.Points

type t
type error = [
  1. | `Invalid_year of int
  2. | `Invalid_day of int
  3. | `Invalid_hour of int
  4. | `Invalid_minute of int
  5. | `Invalid_second of int
  6. | `Invalid_ns of int
  7. | `Invalid_pattern_combination
  8. | `Invalid_tz_info of string option * Timedesc.Span.t
]
exception Error_exn of error
type lean_toward = [
  1. | `Earlier
  2. | `Later
]
val make : +Points (timere.Timere.Points)

Module Timere.Points

type t
type error = [
  1. | `Invalid_year of int
  2. | `Invalid_day of int
  3. | `Invalid_hour of int
  4. | `Invalid_minute of int
  5. | `Invalid_second of int
  6. | `Invalid_ns of int
  7. | `Invalid_pattern_combination
  8. | `Invalid_tz_info of string option * Timedesc.Span.t
]
exception Error_exn of error
type lean_toward = [
  1. | `Earlier
  2. | `Later
]
val make : ?tz:Timedesc.Time_zone.t -> ?offset_from_utc:Timedesc.Span.t -> ?year:int -> diff --git a/timere/Timere/Utils/index.html b/timere/Timere/Utils/index.html index d4d292cd..69dfc083 100644 --- a/timere/Timere/Utils/index.html +++ b/timere/Timere/Utils/index.html @@ -1,5 +1,5 @@ -Utils (timere.Timere.Utils)

Module Timere.Utils

Range flattening

val flatten_month_ranges : int range Stdlib.Seq.t -> int Stdlib.Seq.t option
val flatten_iso_week_ranges : int range Stdlib.Seq.t -> int Stdlib.Seq.t option
val flatten_month_day_ranges : +Utils (timere.Timere.Utils)

Module Timere.Utils

Range flattening

val flatten_month_ranges : int range Stdlib.Seq.t -> int Stdlib.Seq.t option
val flatten_iso_week_ranges : int range Stdlib.Seq.t -> int Stdlib.Seq.t option
val flatten_month_day_ranges : int range Stdlib.Seq.t -> int Stdlib.Seq.t option
val flatten_weekday_ranges : Timedesc.weekday range Stdlib.Seq.t -> diff --git a/timere/Timere/index.html b/timere/Timere/index.html index 5e0df490..69f322b8 100644 --- a/timere/Timere/index.html +++ b/timere/Timere/index.html @@ -1,5 +1,5 @@ -Timere (timere.Timere)

Module Timere

Date time reasoning

Timere provides a set of highly expressive APIs to describe scheduling constraints, and an efficient resolution algorithm

type timestamp = Timedesc.timestamp
type t

This is the core type of Timere that represents sets of points in time, more precisely, unions of time intervals. For example, "all Mondays of year 2000 at the UTC timezone".

We call Timere.t values "timere object"; internally they are rich expressions representing the time computations (union, intersection, etc.), lazily forced into more low-level descriptions (lazy sequences of intervals).

type inc_exc = [
  1. | `Inc
  2. | `Exc
]
type 'a range = [
  1. | `Range_inc of 'a * 'a
  2. | `Range_exc of 'a * 'a
]

Basic constructors

val now : unit -> t

Time right now

val always : t

Entire interval that Timere can handle, i.e. [0000 Jan 01 14:00:00 +00:00:00, 9999 Dec 31 09:59:58 +00:00:00)

val empty : t

Empty interval

val before : Timedesc.t -> t
val since : Timedesc.t -> t
val after : Timedesc.t -> t
val date_time : Timedesc.t -> t
val date_times : Timedesc.t list -> t
val date_time_seq : Timedesc.t Stdlib.Seq.t -> t
val sorted_date_times : Timedesc.t list -> t
val sorted_date_time_seq : Timedesc.t Stdlib.Seq.t -> t
exception Invalid_timestamp
val timestamp : Timedesc.timestamp -> t
val before_timestamp : Timedesc.timestamp -> t
val since_timestamp : Timedesc.timestamp -> t
val after_timestamp : Timedesc.timestamp -> t
val timestamps : ?skip_invalid:bool -> Timedesc.timestamp list -> t

timestamps l

skip_invalid defaults to false

val timestamp_seq : ?skip_invalid:bool -> timestamp Stdlib.Seq.t -> t

timestamps s

skip_invalid defaults to false

val sorted_timestamps : ?skip_invalid:bool -> timestamp list -> t
val sorted_timestamp_seq : ?skip_invalid:bool -> timestamp Stdlib.Seq.t -> t

Pattern matching constructors

val pattern : +Timere (timere.Timere)

Module Timere

Date time reasoning

Timere provides a set of highly expressive APIs to describe scheduling constraints, and an efficient resolution algorithm

type timestamp = Timedesc.timestamp
type t

This is the core type of Timere that represents sets of points in time, more precisely, unions of time intervals. For example, "all Mondays of year 2000 at the UTC timezone".

We call Timere.t values "timere object"; internally they are rich expressions representing the time computations (union, intersection, etc.), lazily forced into more low-level descriptions (lazy sequences of intervals).

type inc_exc = [
  1. | `Inc
  2. | `Exc
]
type 'a range = [
  1. | `Range_inc of 'a * 'a
  2. | `Range_exc of 'a * 'a
]

Basic constructors

val now : unit -> t

Time right now

val always : t

Entire interval that Timere can handle, i.e. [0000 Jan 01 14:00:00 +00:00:00, 9999 Dec 31 09:59:58 +00:00:00)

val empty : t

Empty interval

val before : Timedesc.t -> t
val since : Timedesc.t -> t
val after : Timedesc.t -> t
val date_time : Timedesc.t -> t
val date_times : Timedesc.t list -> t
val date_time_seq : Timedesc.t Stdlib.Seq.t -> t
val sorted_date_times : Timedesc.t list -> t
val sorted_date_time_seq : Timedesc.t Stdlib.Seq.t -> t
exception Invalid_timestamp
val timestamp : Timedesc.timestamp -> t
val before_timestamp : Timedesc.timestamp -> t
val since_timestamp : Timedesc.timestamp -> t
val after_timestamp : Timedesc.timestamp -> t
val timestamps : ?skip_invalid:bool -> Timedesc.timestamp list -> t

timestamps l

skip_invalid defaults to false

val timestamp_seq : ?skip_invalid:bool -> timestamp Stdlib.Seq.t -> t

timestamps s

skip_invalid defaults to false

val sorted_timestamps : ?skip_invalid:bool -> timestamp list -> t
val sorted_timestamp_seq : ?skip_invalid:bool -> timestamp Stdlib.Seq.t -> t

Pattern matching constructors

val pattern : ?years:int list -> ?year_ranges:int range list -> ?months:int list -> @@ -46,7 +46,7 @@ (Points.make ~month:2 ~day:10 ~hour:13 ~minute:0 ~second:0 ()) (* p1 *) (Points.make ~hour:14 ~minute:0 ~second:0 ()) (* p2 *)

yields all the "Feb 10th 1pm to 2pm" intervals (or specifically "Feb 10th 1pm to Feb 10th 2pm")

pattern_intervals `Whole
   (Points.make ~month:`Feb ~day:10 ~hour:23 ~minute:0 ~second:0 ()) (* p1 *)
-  (Points.make                     ~hour:3  ~minute:0 ~second:0 ()) (* p2 *)

yields all the "Feb 10th 11pm to 3am" intervals (or specifically "Feb 10th 11pm to Feb 11th 3am")

  • raises Invalid_argument

    if bound is negative

  • raises Invalid_argument

    if precision (number of date time arguments passed to make_points during construction) of p1 < precision of p2

    For example, Points.make_exn ~hour:3 ~minute:0 ~second:0 () has a lower precision than make_points_exn ~day:10 ~hour:12 ~minute:30 ~second:0 ().

Hour minute second intervals

Convenience wrappers around points and pattern_intervals

val hms_intervals : ?inc_exc:inc_exc -> Timedesc.Time.t -> Timedesc.Time.t -> t

Same as pattern_intervals ... with bound fixed to Span.For_human.make ~days:1 ()

inc_exc defaults to `Exc

Algebraic operations

val inter : t list -> t

Intersection of list of timeres.

inter [] is equivalent to always.

val union : t list -> t

Union of list of timeres.

union [] is equivalent to empty.

val not : t -> t

Negation of timere.

not t is equivalent to all the intervals not included in t.

val shift : Timedesc.Span.t -> t -> t
val lengthen : Timedesc.Span.t -> t -> t
  • raises Invalid_argument

    if duration is negative

val with_tz : Timedesc.Time_zone.t -> t -> t

with_tz tz t changes the time zone to evaluate t in to tz

Chunking

type chunked
type chunking = [
  1. | `Disjoint_intervals
  2. | `By_duration of Timedesc.Span.t
  3. | `By_duration_drop_partial of Timedesc.Span.t
  4. | `At_year_boundary
  5. | `At_month_boundary
]

Ways to chunk/slice time intervals for the selector.

  • `Disjoint_intervals gives a sequence of disjoint intervals to the selector, specifically they are in ascending order, non-overlapping, non-connecting, and unique
  • `By_duration slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are preserved.
  • `By_duration_drop_partial slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are discarded.
  • `At_year_boundary slices at the year boundary (e.g. 2021 Jan 1st 00:00:00)
  • `At_month_boundary slices at the month boundary (e.g. Aug 1st 00:00:00)
val chunk : chunking -> (chunked -> chunked) -> t -> t

chunk chunking f t applies chunked selector f on t.

  • raises Invalid_argument

    if duration is negative in `By_duration or `By_duration_drop_partial

Chunked selectors

You may find (%>) useful for chaining selectors together, e.g. drop 5 %> take 2

val chunk_again : chunking -> chunked -> chunked

chunk_again chunking f applies chunked selector f as a selector

val first : chunked -> chunked

Takes only first chunk

val take : int -> chunked -> chunked

Takes n chunks

val take_nth : int -> chunked -> chunked

Take every nth chunk, specifically 0th, nth, 2nth, 3nth, ...

val drop : int -> chunked -> chunked

Discard n chunks

Infix operators

val (&&&) : t -> t -> t
val (|||) : t -> t -> t
val (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c

Composition, mainly for chunked selectors

f1 %> f2 is equivalent to fun x -> x |> f1 |> f2.

Resolution

val resolve : + (Points.make ~hour:3 ~minute:0 ~second:0 ()) (* p2 *)

yields all the "Feb 10th 11pm to 3am" intervals (or specifically "Feb 10th 11pm to Feb 11th 3am")

  • raises Invalid_argument

    if bound is negative

  • raises Invalid_argument

    if precision (number of date time arguments passed to make_points during construction) of p1 < precision of p2

    For example, Points.make_exn ~hour:3 ~minute:0 ~second:0 () has a lower precision than make_points_exn ~day:10 ~hour:12 ~minute:30 ~second:0 ().

Hour minute second intervals

Convenience wrappers around points and pattern_intervals

val hms_intervals : ?inc_exc:inc_exc -> Timedesc.Time.t -> Timedesc.Time.t -> t

Same as pattern_intervals ... with bound fixed to Span.For_human.make ~days:1 ()

inc_exc defaults to `Exc

Algebraic operations

val inter : t list -> t

Intersection of list of timeres.

inter [] is equivalent to always.

val union : t list -> t

Union of list of timeres.

union [] is equivalent to empty.

val not : t -> t

Negation of timere.

not t is equivalent to all the intervals not included in t.

val shift : Timedesc.Span.t -> t -> t
val lengthen : Timedesc.Span.t -> t -> t
  • raises Invalid_argument

    if duration is negative

val with_tz : Timedesc.Time_zone.t -> t -> t

with_tz tz t changes the time zone to evaluate t in to tz

Chunking

type chunked
type chunking = [
  1. | `Disjoint_intervals
  2. | `By_duration of Timedesc.Span.t
  3. | `By_duration_drop_partial of Timedesc.Span.t
  4. | `At_year_boundary
  5. | `At_month_boundary
]

Ways to chunk/slice time intervals for the selector.

  • `Disjoint_intervals gives a sequence of disjoint intervals to the selector, specifically they are in ascending order, non-overlapping, non-connecting, and unique
  • `By_duration slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are preserved.
  • `By_duration_drop_partial slices in the fixed size specified by the duration. Partial chunks (chunks less than the fixed size) are discarded.
  • `At_year_boundary slices at the year boundary (e.g. 2021 Jan 1st 00:00:00)
  • `At_month_boundary slices at the month boundary (e.g. Aug 1st 00:00:00)
val chunk : chunking -> (chunked -> chunked) -> t -> t

chunk chunking f t applies chunked selector f on t.

  • raises Invalid_argument

    if duration is negative in `By_duration or `By_duration_drop_partial

Chunked selectors

You may find (%>) useful for chaining selectors together, e.g. drop 5 %> take 2

val chunk_again : chunking -> chunked -> chunked

chunk_again chunking f applies chunked selector f as a selector

val first : chunked -> chunked

Takes only first chunk

val take : int -> chunked -> chunked

Takes n chunks

val take_nth : int -> chunked -> chunked

Take every nth chunk, specifically 0th, nth, 2nth, 3nth, ...

val drop : int -> chunked -> chunked

Discard n chunks

Infix operators

val (&&&) : t -> t -> t
val (|||) : t -> t -> t
val (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c

Composition, mainly for chunked selectors

f1 %> f2 is equivalent to fun x -> x |> f1 |> f2.

Resolution

val resolve : ?search_using_tz:Timedesc.Time_zone.t -> t -> (Timedesc.Interval.t Stdlib.Seq.t, string) Stdlib.result

Resolves a Timere object into a concrete interval sequence. * * Intervals are left-closed, right-open, i.e. each interval is * of the form [x, y), which includes x and excludes y. *

exception Resolution_error of string
val resolve_exn : diff --git a/timere/index.html b/timere/index.html index 83d85987..7c7ee924 100644 --- a/timere/index.html +++ b/timere/index.html @@ -1,2 +1,2 @@ -index (timere.index)

timere index

Library timere

The entry point of this library is the module: Timere.

+index (timere.index)

timere index

Library timere

The entry point of this library is the module: Timere.