{"id":37016823,"url":"https://github.com/mlopes/wen","last_synced_at":"2026-01-14T01:55:06.030Z","repository":{"id":57731173,"uuid":"182158000","full_name":"mlopes/wen","owner":"mlopes","description":"Date and time types and instances","archived":false,"fork":false,"pushed_at":"2019-08-04T13:48:35.000Z","size":334,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2023-08-06T08:11:27.839Z","etag":null,"topics":["cats","datetime","functional","functional-programming","scala","typeclasses"],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlopes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-18T21:09:58.000Z","updated_at":"2020-07-17T19:05:02.000Z","dependencies_parsed_at":"2022-09-26T22:10:12.144Z","dependency_job_id":null,"html_url":"https://github.com/mlopes/wen","commit_stats":null,"previous_names":[],"tags_count":12,"template":null,"template_full_name":null,"purl":"pkg:github/mlopes/wen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlopes%2Fwen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlopes%2Fwen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlopes%2Fwen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlopes%2Fwen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlopes","download_url":"https://codeload.github.com/mlopes/wen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlopes%2Fwen/sbom","scorecard":{"id":653589,"data":{"date":"2025-08-11","repo":{"name":"github.com/mlopes/wen","commit":"821b45b15cc3f1eb09212cac921ead276d599893"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 1/12 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T14:08:36.465Z","repository_id":57731173,"created_at":"2025-08-21T14:08:36.465Z","updated_at":"2025-08-21T14:08:36.465Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408692,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cats","datetime","functional","functional-programming","scala","typeclasses"],"created_at":"2026-01-14T01:55:05.485Z","updated_at":"2026-01-14T01:55:06.021Z","avatar_url":"https://github.com/mlopes.png","language":"Scala","readme":"[![Build Status](https://travis-ci.org/mlopes/wen.svg?branch=master)](https://travis-ci.org/mlopes/wen) \n[![Coverage Status](https://coveralls.io/repos/github/mlopes/wen/badge.svg?branch=master)](https://coveralls.io/github/mlopes/wen?branch=master)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b6dc3789e00d4f19a3e8a4a02bf4ac61)](https://app.codacy.com/app/marco.paulo.lopes/wen?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=mlopes/wen\u0026utm_campaign=Badge_Grade_Dashboard)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n![Maven Central](https://img.shields.io/maven-central/v/dev.mlopes/wen_2.12.svg?label=version)\n\n# wen\n\n\u003e 'Wen considered the nature of time and understood that the universe is, instant by instant, recreated anew. Therefore, he understood, there is in truth no past, only a memory of the past. Blink your eyes, and the world you see next did not exist when you closed them. Therefore, he said, the only appropriate state of the mind is surprise. The only appropriate state of the heart is joy. The sky you see now, you have never seen before. The perfect moment is now. Be glad of it.'\n\u003e\n\u003e ― Terry Pratchett, Thief of Time\n\nDate and time types and instances\n\n- [wen](#wen)\n  - [Getting Started](#getting-started)\n  - [What is Wen?](#what-is-wen)\n    - [What Wen isn't?](#what-wen-isnt)\n  - [Types](#types)\n    - [Date/Time Components](#datetime-components)\n      - [Day](#day)\n      - [Month](#month)\n      - [Year](#year)\n      - [Epoch](#epoch)\n      - [WeekDay](#weekday)\n      - [Hour](#hour)\n      - [Minute](#minute)\n      - [Second](#second)\n      - [Millisecond](#millisecond)\n    - [Full Representations](#full-representations)\n      - [Time](#time)\n      - [ZoneTime](#zonetime)\n        - [Offset](#offset)\n        - [OffsetType](#offsettype)\n      - [Date](#date)\n      - [DateTime](#datetime)\n      - [ZoneDateTime](#zonedatetime)\n    - [Numeric types](#numeric-types)\n      - [NumericDay](#numericday)\n      - [NumericMonth](#numericmonth)\n      - [NumericYear](#numericyear)\n      - [NumericHour](#numerichour)\n      - [NumericMinute](#numericminute)\n      - [NumericSecond](#numericsecond)\n      - [NumericMillisecond](#numericmillisecond)\n  - [Refinement Helpers](#refinement-helpers)\n  - [ISO-8601 instances](#iso-8601-instances)\n  - [Circe Instances](#circe-instances)\n\n## Getting Started\n\nWen is available for Scala 2.12. You can add wen to your sbt project by adding the following to\nyour `build.sbt`:\n\n```scala\nlibraryDependencies += \"dev.mlopes\" %% \"wen\" % \"1.0.0-M1\"\nlibraryDependencies += \"dev.mlopes\" %% \"wen-cats\" % \"1.0.0-M1\" // For cats instances\nlibraryDependencies += \"dev.mlopes\" %% \"wen-circe\" % \"1.0.0-M1\" // For circe encoders and decoders\n```\n\n## What is Wen?\n\nWen provides types to safely represent months, weekdays, years, epoch, hours, minutes,\nseconds and milliseconds, as well as instances of the `Order`, `Eq` and `Show` cats type classes.\n\nShould cats ever support the `Enum` and `Bounded` type classes, and we should implement those as\nwell, for the relevant types.\n\n### What Wen isn't?\n\nWen does not aim for date/time related functionality like the one provided by the\n`java.time`. Its purpose is to provide stateless representations for date/time data types.\n\n## Types\n\nWen provides types to represent date/time components, as well as types for full time and date representations, and auxiliary refined types for numeric representation of date/time components.\n\n### Date/Time Components\n\n#### Day\n\n| Constructors |\n| ------------ |\n| Day(day: [NumericDay](#NumericDay)): Day |\n| Day.fromInt(day: Int): Option[Day] |\n\n| Instances |\n| --------- |\n| Order[Day] |\n| Eq[Day] |\n| Show[Day] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.Interval\n\nval day = Day.fromInt(31)\n// day: Option[wen.types.Day] = Some(Day(31))\n\nval notDay = Day.fromInt(32)\n// notDay: Option[wen.types.Day] = None\n\n// You need to use refineV when refining non-literal values\nval refinedDay = Day(refineMV[Interval.Closed[W.`1`.T, W.`31`.T]](22))\n// refinedDay: wen.types.Day = Day(22)\n\nimport eu.timepit.refined.auto._\n\n\n// This works because we add the type annotation to `autoRefinedDay`\n// so Scala infers that we're using the constructor\n// Day(numericDay: NumericDay): Day\n// refined.auto provides the necessary implicit conversion from Int.\nval autoRefinedDay: Day = Day(25)\n// autoRefinedDay: wen.types.Day = Day(25)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedDay.show\n// res0: String = 22\n\nautoRefinedDay \u003e= refinedDay\n// res1: Boolean = true\n\nrefinedDay =!= autoRefinedDay\n// res2: Boolean = true\n\n```\n\n#### Month\n\n| Constructors |\n| ------------ |\n| January |\n| February |\n| March |\n| April |\n| May |\n| June |\n| July |\n| August|\n| September |\n| October |\n| November |\n| December |\n| Month(numericMonth: [NumericMonth](#NumericMonth)): Month |\n| Month.fromInt(month: Int): Option[Month] |\n| Month.fromString(month: String): Option[Month] |\n\n| Instances |\n| --------- |\n| Order[Month] |\n| Eq[Month] |\n| Show[Month] |\n\n**Members**\n\n```scala\nMonth.asInt: Int\n```\n\nReturns the ordinal number of a Month, starting at 1 for January and ending in 12 for December.\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.Interval\n\nval month: Month = December\n// month: wen.types.Month = December\n\nval monthFromInt = Month.fromInt(7)\n// monthFromInt: Option[wen.types.Month] = Some(July)\n\nval monthFromString = Month.fromString(\"July\")\n// monthFromString: Option[wen.types.Month] = Some(July)\n\nval notMonth = Month.fromInt(24)\n// notMonth: Option[wen.types.Month] = None\n\nval notMonthFromString = Month.fromString(\"Grune\")\n// notMonthFromString: Option[wen.types.Month] = None\n\n// You need to use refineV when refining non-literal values\nval refinedMonth = Month(refineMV[Interval.Closed[W.`1`.T, W.`12`.T]](4))\n// refinedMonth: wen.types.Month = April\n\nval monthInt = June.asInt\n// monthInt: Int = 6\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedMonth: Month =  Month(8)\n// autoRefinedMonth: wen.types.Month = August\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedMonth.show\n// res0: String = April\n\nrefinedMonth \u003e autoRefinedMonth\n// res1: Boolean = false\n\nrefinedMonth === autoRefinedMonth\n// res2: Boolean = false\n\n// Note that we have to specify the type Month so that Scala doesn't infer the type as July\n(July : Month).show\n// res3: String = July\n```\n\n#### Year\n\n| Constructors |\n| ------------ |\n| Year(year: [NumericYear](#NumericYear)): Year |\n| Year(year: [NumericYear](#NumericYear), epoch: [Epoch](#Epoch)): Year |\n| Year.fromInt(year: Int): Option[Year] |\n| Year.fromIntWithEpoch(year: Int, epoch: [Epoch](#Epoch)): Option[Year] |\n\n| Instances |\n| --------- |\n| Order[Year] |\n| Eq[Year] |\n| Show[Year] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.{Interval, Positive}\n\nval adYear = Year.fromIntWithEpoch(2019, AD)\n// adYear: Option[wen.types.Year] = Some(Year(2019,AD))\n\nval yearWithDefaultEpoch1 = Year.fromInt(2012)\n// yearWithDefaultEpoch1: Option[wen.types.Year] = Some(Year(2012,AD))\n\nval bcYear = Year.fromIntWithEpoch(19, BC)\n// bcYear: Option[wen.types.Year] = Some(Year(19,BC))\n\nval notYear = Year.fromIntWithEpoch(-21, AD)\n// notYear: Option[wen.types.Year] = None\n\n// You need to use refineV when refining non-literal values\nval refinedYear = Year(refineMV[Positive](2019), AD)\n// refinedYear: wen.types.Year = Year(2019,AD)\n\nval yearWithDefaultEpoch = Year(refineMV[Positive](2011))\n// yearWithDefaultEpoch: wen.types.Year = Year(2011,AD)\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedYear: Year = Year(2000, AD)\n// autoRefinedYear: wen.types.Year = Year(2000,AD)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedYear.show\n// res0: String = 2019\n\nyearWithDefaultEpoch.show\n// res1: String = 2011\n\nrefinedYear \u003c= refinedYear\n// res2: Boolean = true\n\nrefinedYear ===  autoRefinedYear\n// res3: Boolean = false\n```\n\n#### Epoch\n\n| Constructors |\n| ------------ |\n| BC |\n| AD |\n| Epoch.fromString(epoch: String) |\n\n| Instances |\n| --------- |\n| Order[Epoch] |\n| Eq[Epoch] |\n| Show[Epoch] |\n\n```scala\nval epochFromString = Epoch.fromString(\"AD\")\n// epochFromString: Option[wen.types.Epoch] = Some(AD)\n\nval notEpochFromString = Epoch.fromString(\"ACDC\")\n// notEpochFromString: Option[wen.types.Epoch] = None\n```\n\n#### WeekDay\n\n| Constructors |\n| ------------ |\n| Sunday |\n| Monday |\n| Tuesday |\n| Wednesday |\n| Thursday |\n| Friday |\n| Saturday |\n| WeekDay.fromString(weekDay: String): Option[WeekDay] |\n\n| Instances |\n| --------- |\n| Order[WeekDay] |\n| Eq[WeekDay] |\n| Show[WeekDay] |\n\nThe provided `Order` instance starts on `Sunday` and ends on `Saturday`.\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can do the following:\n\n**Usage**\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nval oneDay: WeekDay = Tuesday\n// oneDay: wen.types.WeekDay = Tuesday\n\nval otherDay: WeekDay = Friday\n// otherDay: wen.types.WeekDay = Friday\n\nval yetAnotherDay: WeekDay = WeekDay.fromString(\"Saturday\")\n// yetAnotherDay: Option[wen.types.WeekDay] = Some(Saturday)\n\nval notAnotherDay: WeekDay = WeekDay.fromString(\"Caturday\")\n// notAnotherDay: Option[wen.types.WeekDay] = None\n\notherDay \u003c oneDay\n// res0: Boolean = false\n\notherDay ===  oneDay\n// res1: Boolean = false\n\notherDay.show\n// res2: String = Friday\n\n// Note that we have to specify the type WeekDay so that Scala doesn't infer the type as Saturday\n(Saturday: WeekDay).show\n// res3: String = Saturday\n```\n\nThere's also an `Order[WeekDay]`  instance starting on `Monday`, but it requires the user\nto explicitly import it and make it implicit. Note that if you import the default `Order`\ninstance for weekday, it will conflict with this one and the compiler won't be able to infer\nwhich one to use.\n\n**Usage**\n\n```scala\nimport cats.implicits._\n\nimplicit val orderInstance = wen.instances.WeekDayInstances.mondayFirstWeekDayOrderInstance\norderInstance: cats.Order[wen.types.WeekDay] = wen.instances.WeekDayInstances$$anon$1@7da2d02d\n\nimport wen.types._\n\nval oneDay: WeekDay = Sunday\n// oneDay: wen.types.WeekDay = Sunday\n\nval otherDay: WeekDay = Monday\n// otherDay: wen.types.WeekDay = Monday\n\notherDay \u003c oneDay\n// res0: Boolean = true\n```\n\n#### Hour\n\n| Constructors |\n| ------------ |\n| Hour(hour: [NumericHour](#NumericHour)): Hour |\n| Hour.fromInt(hour: Int): Option[Hour] |\n\n| Instances |\n| --------- |\n| Order[Hour] |\n| Eq[Hour] |\n| Show[Hour] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.{Interval, Positive}\n\nval hour = Hour.fromInt(23)\n// hour: Option[wen.types.Hour] = Some(Hour(23))\n\nval notHour = Hour.fromInt(25)\n// notHour: Option[wen.types.Hour] = None\n\n// You need to use refineV when refining non-literal values\nval refinedHour = Hour(refineMV[Interval.Closed[W.`0`.T, W.`23`.T]](10))\n// refinedHour: wen.types.Hour = Hour(10)\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedHour: Hour = Hour(12)\n// autoRefinedHour: wen.types.Hour = Hour(12)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedHour.show\n// res0: String = 10\n\nrefinedHour \u003e autoRefinedHour\n// res1: Boolean = false\n\nautoRefinedHour === autoRefinedHour\n// res2: Boolean = true\n```\n\n#### Minute\n\n| Constructors |\n| ------------ |\n| Minute(minute: [NumericMinute](#NumericMinute)): Minute |\n| Minute.fromInt(minute: Int): Option[Minute] |\n\n| Instances |\n| --------- |\n| Order[Minute] |\n| Eq[Minute] |\n| Show[Minute] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.{Interval, Positive}\n\nval minute = Minute.fromInt(0)\n// minute: Option[wen.types.Minute] = Some(Minute(0))\n\nval notMinute = Minute.fromInt(-12)\n// notMinute: Option[wen.types.Minute] = None\n\n// You need to use refineV when refining non-literal values\nval refinedMinute: Minute = Minute(refineMV[Interval.Closed[W.`0`.T, W.`59`.T]](15))\n// refinedMinute: wen.types.Minute = Minute(15)\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedMinute: Minute = Minute(45)\n// autoRefinedMinute: wen.types.Minute = Minute(45)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nautoRefinedMinute.show\n// res0: String = 45\n\nautoRefinedMinute \u003e refinedMinute\n// res1: Boolean = true\n\nautoRefinedMinute =!= refinedMinute\n// res2: Boolean = true\n```\n\n#### Second\n\n| Constructors |\n| ------------ |\n| Second(second: [NumericSecond](#NumericSecond)): Second |\n| Second.fromInt(second: Int): Option[Second] |\n\n| Instances |\n| --------- |\n| Order[Second] |\n| Eq[Second] |\n| Show[Second] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.{Interval, Positive}\n\nval second = Second.fromInt(42)\n// second: Option[wen.types.Second] = Some(Second(42))\n\nval notSecond = Second.fromInt(591)\n// notSecond: Option[wen.types.Second] = None\n\n// You need to use refineV when refining non-literal values\nval refinedSecond = Second(refineMV[Interval.Closed[W.`0`.T, W.`59`.T]](20))\n// refinedSecond: wen.types.Second = Second(20)\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedSecond: Second = Second(12)\n// autoRefinedSecond: wen.types.Second = Second(12)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedSecond.show\n// res0: String = Some(20)\n\nrefinedSecond \u003e autoRefinedSecond\n// res1: Boolean = true\n\nrefinedSecond === autoRefinedSecond\n// res2: Boolean = false\n```\n\n#### Millisecond\n\n| Constructors |\n| ------------ |\n| Millisecond(millisecond: [NumericMillisecond](#NumericMillisecond)): Millisecond |\n| Millisecond.fromInt(millisecond: Int): Option[Millisecond] |\n\n| Instances |\n| --------- |\n| Order[Millisecond] |\n| Eq[Millisecond] |\n| Show[Millisecond] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.{W, refineMV}\nimport eu.timepit.refined.numeric.{Interval, Positive}\n\nval millisecond = Millisecond.fromInt(456)\n// millisecond: Option[wen.types.Millisecond] = Some(Millisecond(456))\n\nval notMillisecond = Millisecond.fromInt(-1)\n// notMillisecond: Option[wen.types.Millisecond] = None\n\n// You need to use refineV when refining non-literal values\nval refinedMillisecond = Millisecond(refineMV[Interval.Closed[W.`0`.T,\nW.`999`.T]](999))\n// refinedMillisecond: wen.types.Millisecond = Millisecond(999)\n\nimport eu.timepit.refined.auto._\n\nval autoRefinedMillisecond: Millisecond = Millisecond(999)\n// autoRefinedMillisecond: wen.types.Millisecond = Millisecond(999)\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nrefinedMillisecond.show\n// res0: String = 999\n\nrefinedMillisecond \u003e= autoRefinedMillisecond\n// res1: Boolean = true\n\nrefinedMillisecond === autoRefinedMillisecond\n// res2: Boolean = true\n```\n\n### Full Representations\n\n#### Time\n\n| Constructors |\n| ------------ |\n| Time(hour: [Hour](#Hour), minute: [Minute](#Minute), second: [Second](#Second), millisecond: [Millisecond](#Millisecond)): Time |\n| Time(hour: [Hour](#Hour), minute: [Minute](#Minute), second: [Second](#Second)): Time |\n| Time(hour: [Hour](#Hour), minute: [Minute](#Minute)): Time |\n| Time(hour: [Hour](#Hour)): Time |\n| Time(time: LocalTime): Time  |\n\n| Instances |\n| --------- |\n| Order[Time] |\n| Eq[Time] |\n| Show[Time] |\n\nValues for the properties that are not specified, will default to 0.\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.auto._\nimport wen.datetime._\n\nval time1 = Time(Hour(7), Minute(5), Second(10), Millisecond(200))\n// time1: wen.datetime.Time = Time(Hour(7),Minute(5),Second(10),Millisecond(200))\n\nval time2 = Time(Hour(7), Minute(5), Second(10))\n// time2: wen.datetime.Time = Time(Hour(7),Minute(5),Second(10),Millisecond(0))\n\nval time3 = Time(Hour(7), Minute(5))\n// time3: wen.datetime.Time = Time(Hour(7),Minute(5),Second(0),Millisecond(0))\n\nval time4 = Time(Hour(7))\n// time4: wen.datetime.Time = Time(Hour(7),Minute(0),Second(0),Millisecond(0))\n\nimport java.time.LocalTime\n\nval time5 = Time(LocalTime.now)\n// time5: wen.datetime.Time = Time(Hour(7),Minute(2),Second(48),Millisecond(159))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\ntime1.show\n// res0: String = 07:05:10.200\n\ntime3.show\n// res1: String = 07:05:00.0\n\ntime1 \u003e time3\n// res2: Boolean = true\n\ntime2 =!= time4\n// res3: Boolean = true\n```\n\nTo create a `Time` from non-refined values, you can do the following:\n\n```scala\nimport wen.types._\nimport wen.datetime._\n\nval optionTime = for {\n  hour \u003c- Hour.fromInt(12)\n  minute \u003c- Minute.fromInt(15)\n  second \u003c- Second.fromInt(59)\n  millisecond \u003c- Millisecond.fromInt(908)\n} yield Time(hour, minute, second, millisecond)\n// optionTime: Option[wen.datetime.Time] = Some(Time(Hour(12),Minute(15),Second(59),Millisecond(908)))\n```\n\n#### ZoneTime\n\n| Constructors |\n| ------------ |\n| ZoneTime(time: [Time](#Time), offset: [Offset](#Offset)): ZoneTime |\n| ZoneTime(offsetTime: OffsetTime): ZoneTime |\n\n| Instances |\n| --------- |\n| Order[ZoneTime] |\n| Eq[ZoneTime] |\n| Show[ZoneTime] |\n\n##### Offset\n\n| Constructors |\n| ------------ |\n| Offset(offsetType: [OffsetType](#OffsetType), hour: [Hour](#Hour), minute: [Minute](#Minute)): Offset |\n| Offset(zoneOffset: ZoneOffset): Offset |\n\n**Members**\n\n```scala\nUTC: Offset = Offset([UTCPlus](#OffsetType), Hour(0), Minute(0))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport wen.datetime._\nimport wen.implicits._\nimport cats.implicits._\nimport wen.types.\n\nval offset1 = Offset.UTC\n// offset1: wen.datetime.Offset = Offset(UTCPlus,Hour(0),Minute(0))\n\nval offset2 = Offset(Offset.UTCMinus, Hour.fromInt(5).get, Minute.fromInt(45).get)\n// offset2: wen.datetime.Offset = Offset(UTCMinus,Hour(5),Minute(45))\n\nval offset3 = Offset(Offset.UTCPlus, Hour.fromInt(12).get, Minute.fromInt(20).get)\n// offset3: wen.datetime.Offset = Offset(UTCPlus,Hour(12),Minute(20))\n\n\noffset1 \u003e offset2\n// res0: Boolean = true\n\noffset3 \u003e offset2\n// res1: Boolean = true\n\noffset2 \u003e offset3\n// res2: Boolean = false\n\noffset1 === offset2\n// res3: Boolean = false\n\noffset1 =!= offset3\n// res4: Boolean = true\n\noffset1.show\n// res5: String = +00:00\n\noffset2.show\n// res6: String = -05:45\n\noffset3.show\n// res7: String = +12:20\n```\n\nA Show instance in ISO format is also available:\n\n```scala\nimport wen.types._\nimport cats.implicits._\nimport wen.datetime._\nimport wen.instances.iso.isoOffsetShowInstance\n\nval offset1 = Offset.UTC\n// offset1: wen.datetime.Offset = Offset(UTCPlus,Hour(0),Minute(0))\n\nval offset2 = Offset(Offset.UTCMinus, Hour.fromInt(5).get, Minute.fromInt(45).get)\n// offset2: wen.datetime.Offset = Offset(UTCMinus,Hour(5),Minute(45))\n\nval offset3 = Offset(Offset.UTCPlus, Hour.fromInt(12).get, Minute.fromInt(20).get)\n// offset3: wen.datetime.Offset = Offset(UTCPlus,Hour(12),Minute(20))\n\noffset1.show\n// res0: String = Z\n\noffset2.show\n// res1: String = -05:45\n\noffset3.show\n// res2: String = +12:20\n```\n\n\n##### OffsetType\n \n| Constructors |\n| ------------ |\n| UTCMinus |\n| UTCPlus |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.auto._\nimport wen.datetime._\n\nval time1 = Time(Hour(10), Minute(11), Second(12), Millisecond(13))\n// time1: wen.datetime.Time = Time(Hour(10),Minute(11),Second(12),Millisecond(13))\n\nval zoneTime1 = ZoneTime(time1, Offset.UTC)\n// zoneTime1: wen.datetime.ZoneTime = ZoneTime(Time(Hour(10),Minute(11),Second(12),Millisecond(13)),Offset(UTCPlus,Hour(0),Minute(0)))\n\nval offset1 = Offset(Offset.UTCPlus, Hour(1), Minute(0))\n// offset1: wen.datetime.Offset = Offset(UTCPlus,Hour(1),Minute(0))\n\nval offset2 = Offset(Offset.UTCMinus, Hour(1), Minute(0))\n// offset2: wen.datetime.Offset = Offset(UTCMinus,Hour(1),Minute(0))\n\nval zoneTime2 = ZoneTime(time1, offset1)\n// zoneTime2: wen.datetime.ZoneTime = ZoneTime(Time(Hour(10),Minute(11),Second(12),Millisecond(13)),Offset(UTCPlus,Hour(1),Minute(0)))\n\nval zoneTime3 = ZoneTime(time1, offset2)\n// zoneTime3: wen.datetime.ZoneTime = ZoneTime(Time(Hour(10),Minute(11),Second(12),Millisecond(13)),Offset(UTCMinus,Hour(1),Minute(0)))\n\nval time2 = Time(Hour(9), Minute(11), Second(12), Millisecond(13))\ntime2: wen.datetime.Time = Time(Hour(9),Minute(11),Second(12),Millisecond(13))\n\nval zoneTime4 = ZoneTime(time2, offset1)\n// zoneTime4: wen.datetime.ZoneTime = ZoneTime(Time(Hour(9),Minute(11),Second(12),Millisecond(13)),Offset(UTCPlus,Hour(1),Minute(0)))\n\nimport java.time.ZoneOffset\n\nval offset3 = Offset(ZoneOffset.MIN)\n// offset3: wen.datetime.Offset = Offset(UTCMinus,Hour(18),Minute(0))\n\nimport java.time.OffsetTime\n\nval zoneTime5 = ZoneTime(OffsetTime.now)\n// zoneTime5: wen.datetime.ZoneTime = ZoneTime(Time(Hour(21),Minute(33),Second(10),Millisecond(1)),Offset(UTCPlus,Hour(1),Minute(0)))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nzoneTime1.show\n// res0: String = 10:11:12.13 +00:00\n\nzoneTime2.show\n// res1: String = 10:11:12.13 +01:00\n\nzoneTime4.show\n// res2: String = 09:11:12.13 +01:00\n\nzoneTime1 \u003c zoneTime2\n// res3: Boolean = true\n\nzoneTime1 === zoneTime4\n// res4: Boolean = true\n```\n\n#### Date\n\n| Constructors |\n| ------------ |\n| Date(localDate: LocalDate): Date |\n| Date.safe(day: [Day](#Day), month: [Month](#Month), year: [Year](#Year)): Option[Date] |\n| Date.unsafe(day: [Day](#Day), month: [Month](#Month), year: [Year](#Year)): Date |\n\n| Instances |\n| --------- |\n| Order[Date] |\n| Eq[Date] |\n| Show[Date] |\n\nThe constructor `Date.safe(day: Day, month: Month, year: Year): Option[Date]` only allows the creation of valid dates, and will return `None` for invalid dates. The unsafe constructor `Date.unsafe(day: Day, month: Month, year: Year): Date` allows for creating invalid date combinations such as _30 February 2019_.\n\nDates created from `java.time.LocalDate are unsafe, as `java.time.LocalDate` allow for invalid dates in the BC epoch. See [issue #19](https://github.com/mlopes/wen/issues/19) for details of why. For all AD, and non leap year BC dates, date creation should yield valid dates only. This is a problem with `java.time.LocalDate`, if you wish to avoid this you'll need to use one of the other safe constructors.\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.auto._\nimport wen.datetime._\n\nval date = Date.safe(Day(12), Month(8), Year(2016, AD)) \n// date: Option[wen.datetime.Date] = Some(Date(Day(12),August,Year(2016,AD)))\n\nval notDate = Date.safe((31), September, Year(2000, AD))\n// notDate: Option[wen.datetime.Date] = None\n\nval unsafeDate = Date.unsafe(Day(31), August, Year(2019, AD))\n// unsafeDate: wen.datetime.Date = Date(Day(31),August,Year(2019,AD))\n\n// This creates an invalid date\nval unsafeNotDate = Date.unsafe(Day(31), February, Year(2018, AD))\n// unsafeNotDate: wen.datetime.Date = Date(Day(31),February,Year(2018,AD))\n\nimport java.time.LocalDate\n\nval date2 = Date(LocalDate.now)\n// date2: wen.datetime.Date = Date(Day(2),May,Year(2019,AD))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\n unsafeDate.show\n// res0: String = 31 August 2019\n\nval unsafeDate1 = Date.unsafe(Day(31), August, Year(2018, AD))\n// unsafeDate1: wen.datetime.Date = Date(Day(31),August,Year(2018,AD))\n\nunsafeDate \u003c unsafeDate1\n// res1: Boolean = false\n\nunsafeDate === unsafeDate1\n// res1: Boolean = false\n```\n\n#### DateTime\n\n| Constructors |\n| ------------ |\n| DateTime(date: [Date](#Date), time: [Time](#Time)): DateTime |\n| DateTime(localDateTime: LocalDateTime): DateTime |\n\n| Instances |\n| --------- |\n| Order[DateTime] |\n| Eq[DateTime] |\n| Show[DateTime] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.auto._\nimport wen.datetime._\n\nval date1 = Date.unsafe(Day(12), Month(8), Year(2016, AD))\n// date1: wen.datetime.Date = Date(Day(12),August,Year(2016,AD))\n\nval date2 = Date.unsafe(Day(22), Month(8), Year(1982, AD))\n// date2: wen.datetime.Date = Date(Day(22),August,Year(1982,AD))\n\nval time1 = Time(Hour(7), Minute(5))\n// time1: wen.datetime.Time = Time(Hour(7),Minute(5),Second(0),Millisecond(0))\n\nval time2 = Time(Hour(20), Minute(30))\n// time2: wen.datetime.Time = Time(Hour(20),Minute(30),Second(0),Millisecond(0))\n\nval dateTime1 = DateTime(date1, time1)\n// dateTime1: wen.datetime.DateTime = DateTime(Date(Day(12),August,Year(2016,AD)),Time(Hour(7),Minute(5),Second(0),Millisecond(0)))\n\nval dateTime2 = DateTime(date2, time2)\n// dateTime2: wen.datetime.DateTime = DateTime(Date(Day(22),August,Year(1982,AD)),Time(Hour(20),Minute(30),Second(0),Millisecond(0)))\n\nval dateTime3 = DateTime(date1, time2)\n// dateTime3: wen.datetime.DateTime = DateTime(Date(Day(12),August,Year(2016,AD)),Time(Hour(20),Minute(30),Second(0),Millisecond(0)))\n\nimport java.time.LocalDateTime\n\nval dateTime4 = DateTime(LocalDateTime.now)\n// dateTime4: wen.datetime.DateTime = DateTime(Date(Day(2),May,Year(2019,AD)),Time(Hour(20),Minute(40),Second(16),Millisecond(612)))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\ndateTime1.show\n// res0: String = 12 August 2016 07:05:00.0\n\ndateTime1 \u003e dateTime2\n// res1: Boolean = true\n\ndateTime3 \u003e dateTime1\n// res2: Boolean = true\n\ndateTime1 =!= dateTime2\n// res3: Boolean = true\n```\n\n#### ZoneDateTime\n\n| Constructors |\n| ------------ |\n| ZoneDateTime(date: [Date](#Date), zoneTime: [ZoneTime](#ZoneTime)): ZoneDateTime |\n| ZoneDateTime(offsetDateTime: OffsetDateTime): ZoneDateTime |\n| ZoneDateTime(instant: Instant): ZoneDateTime |\n\n| Instances |\n| --------- |\n| Order[ZoneDateTime] |\n| Eq[ZoneDateTime] |\n| Show[ZoneDateTime] |\n\n**Usage**\n\n```scala\nimport wen.types._\nimport eu.timepit.refined.auto._\nimport wen.datetime._\n\nval date1 = Date.unsafe(Day(12), Month(8), Year(2016, AD))\n// date1: wen.datetime.Date = Date(Day(12),August,Year(2016,AD))\n\nval time1 = ZoneTime(Time(Hour(7), Minute(5)), Offset.UTC)\n// time1: wen.datetime.ZoneTime = ZoneTime(Time(Hour(7),Minute(5),Second(0),Millisecond(0)),Offset(UTCPlus,Hour(0),Minute(0)))\n\nval time2 = ZoneTime(Time(Hour(7), Minute(5)), Offset(Offset.UTCMinus, Hour(1), Minute(0)))\n// time2: wen.datetime.ZoneTime = ZoneTime(Time(Hour(7),Minute(5),Second(0),Millisecond(0)),Offset(UTCMinus,Hour(1),Minute(0)))\n\nval time3 = ZoneTime(Time(Hour(8), Minute(5)), Offset(Offset.UTCMinus, Hour(1), Minute(0)))\n// time3: wen.datetime.ZoneTime = ZoneTime(Time(Hour(8),Minute(5),Second(0),Millisecond(0)),Offset(UTCMinus,Hour(1),Minute(0)))\n\nval zoneDateTime1 = ZoneDateTime(date1, time1)\n// zoneDateTime1: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(12),August,Year(2016,AD)),ZoneTime(Time(Hour(7),Minute(5),Second(0),Millisecond(0)),Offset(UTCPlus,Hour(0),Minute(0))))\n\nval zoneDateTime2 = ZoneDateTime(date1, time2)\n// zoneDateTime2: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(12),August,Year(2016,AD)),ZoneTime(Time(Hour(7),Minute(5),Second(0),Millisecond(0)),Offset(UTCMinus,Hour(1),Minute(0))))\n\nval zoneDateTime3 = ZoneDateTime(date1, time3)\n// zoneDateTime3: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(12),August,Year(2016,AD)),ZoneTime(Time(Hour(8),Minute(5),Second(0),Millisecond(0)),Offset(UTCMinus,Hour(1),Minute(0))))\n\nimport java.time.OffsetDateTime\nimport java.time.Instant\n\nval zoneDateTime4 = ZoneDateTime(OffsetDateTime.now)\n// zoneDateTime4: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(2),May,Year(2019,AD)),ZoneTime(Time(Hour(22),Minute(44),Second(34),Millisecond(833)),Offset(UTCPlus,Hour(1),Minute(0))))\n\nval zoneDateTime5 = ZoneDateTime(Instant.now)\n// zoneDateTime5: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(2),May,Year(2019,AD)),ZoneTime(Time(Hour(21),Minute(45),Second(7),Millisecond(704)),Offset(UTCPlus,Hour(0),Minute(0))))\n```\n\nBecause instances of cats's `Eq`, `Order` and `Show` are available, we can also do the following:\n\n```scala\nimport cats.implicits._ // for cats syntax\nimport wen.implicits._ // for wen's instances\n\nzoneDateTime1.show\n// res0: String = 12 August 2016 07:05:00.0 +00:00\n\nscala\u003e zoneDateTime2.show\n// res1: String = 12 August 2016 07:05:00.0 -01:00\n\nscala\u003e zoneDateTime3.show\n// res2: String = 12 August 2016 08:05:00.0 -01:00\n\nzoneDateTime1 \u003e zoneDateTime2\n// res3: Boolean = true\n\nzoneDateTime1 === zoneDateTime3\n// res4: Boolean = true\n```\n\n### Numeric types\n\nNumeric types use [refined](https://github.com/fthomas/refined) for type safe representation of date/time components as integers.\nThese types are available under the `wen.types.NumericTypes` namespace.\n\n#### NumericDay\n\n```scala\ntype NumericDay = Int Refined Interval.Closed[W.`1`.T, W.`31`.T]\n```\n\n#### NumericMonth\n\n```scala\ntype NumericMonth =  Int Refined Interval.Closed[W.`1`.T, W.`12`.T]\n```\n\n#### NumericYear\n\n```scala\ntype NumericYear = Int Refined Positive\n```\n\n#### NumericHour\n\n```scala\ntype NumericHour = Int Refined Interval.Closed[W.`0`.T, W.`23`.T]\n```\n\n#### NumericMinute\n\n```scala\ntype NumericMinute = Int Refined Interval.Closed[W.`0`.T, W.`59`.T]\n```\n\n#### NumericSecond\n\n```scala\ntype NumericSecond = Int Refined Interval.Closed[W.`0`.T, W.`59`.T]\n```\n\n#### NumericMillisecond\n\n```scala\ntype NumericMillisecond = Int Refined Interval.Closed[W.`0`.T, W.`999`.T]\n```\n\n## Refinement Helpers\n\nRefinement helpers are made available under the `wen.refine` namespace.\n\nTheir purpose is to make it easier to refine integer values into\n[NumericTypes](#NumericTypes), without the user having to know about\nun-specialised refinement types.\n\nThe following refinement helper functions are available:\n\n| functions |\n| --------- |\n| def refineHour(hour: Int): Either[String, NumericHour] |\n| def refineMinute(minute: Int): Either[String, NumericMinute] |\n| def refineSecond(second: Int): Either[String, NumericSecond] |\n| def refineMilliSecond(millisecond: Int): Either[String, NumericMillisecond] |\n| def refineYear(year: Int): Either[String, NumericYear] |\n| def refineMonth(month: Int): Either[String, NumericMonth] |\n| def refineDay(day: Int): Either[String, NumericDay] |\n\n**Usage**\n\n```scala\ndef time(hour: Int, minute: Int, second: Int): Either[String, Time] =\n  for {\n    h \u003c- refineHour(hour)\n    m \u003c- refineMinute(minute)\n    s \u003c- refineSecond(second)\n    ms \u003c- refineMilliSecond(millisecond)\n  } yield new Time(Hour(h), Minute(m), Second(s), Millisecond(ms))\n```\n\n## ISO-8601 instances\n\nISO-8601 instances are made available under the `wen.instances.iso` namespace.\n\n| ISO Instances |\n| ------------- |\n| Show[Date] |\n| Show[Time] |\n| Show[ZoneTime] |\n| Show[DateTime] |\n| Show[ZoneDateTime] |\n\nISO show instances are an alternative to the default ones provided in `wen.implicits`.\nUnlike the default instances which return the dates/times in human readable format,\nISO instances return the dates in ISO-8601 format.\n\nSee [here for the wikipedia entry on ISO-8601](https://en.m.wikipedia.org/wiki/ISO_8601).\n\nNote that when using the ISO instances you can't import the instances under `wen.implicits`\nor `wen.instances` otherwise the compiler won't be able to infer which instances to use for\n`Show`.\n\n**Usage**\n\n```scala\nimport cats.implicits._\nimport wen.instances.iso._\nimport wen.datetime._\nimport wen.types._\nimport eu.timepit.refined.auto._\n\nval date1 = Date.unsafe(Day(25), July, Year(1975, AD))\n// date1: wen.datetime.Date = Date(Day(25),July,Year(1975,AD))\n\nval date2 = Date.unsafe(Day(1), January, Year(2131, BC))\n// date2: wen.datetime.Date = Date(Day(1),January,Year(2131,BC))\n\ndate1.show\n// res0: String = 1975-07-25\n\nscala\u003e date2.show\n// res1: String = -2130-01-01\n\nval date3 = Date.unsafe(Day(2), March, Year(1, BC))\n// date3: wen.datetime.Date = Date(Day(2),March,Year(1,BC))\n\nval time = Time(Hour(8), Minute(53), Second(23), Millisecond(900))\n// time: wen.datetime.Time = Time(Hour(8),Minute(53),Second(23),Millisecond(900))\n\nval dateTime1 = DateTime(date1, time)\n// dateTime1: wen.datetime.DateTime = DateTime(Date(Day(25),July,Year(1975,AD)),Time(Hour(8),Minute(53),Second(23),Millisecond(900)))\n\nval dateTime2 = DateTime(date2, time)\n// dateTime2: wen.datetime.DateTime = DateTime(Date(Day(1),January,Year(2131,BC)),Time(Hour(8),Minute(53),Second(23),Millisecond(900)))\n\nval dateTime3 = DateTime(date3, time)\n// dateTime3: wen.datetime.DateTime = DateTime(Date(Day(2),March,Year(1,BC)),Time(Hour(8),Minute(53),Second(23),Millisecond(900)))\n\ndateTime1.show\n// res2: String = 1975-07-25T08:53:23\n\ndateTime2.show\n// res3: String = -2130-01-01T08:53:23\n\ndateTime3.show\n// res4: String = 0000-03-02T08:53:23\n\nval zoneTime1 = ZoneTime(Time(Hour(8), Minute(15), Second(2), Millisecond(33)),\n                         Offset.UTC)\n// zoneTime1: wen.datetime.ZoneTime = ZoneTime(Time(Hour(8),Minute(15),Second(2),Millisecond(33)),Offset(UTCPlus,Hour(0),Minute(0)))\n\nval zoneTime2 = ZoneTime(Time(Hour(10), Minute(31), Second(23), Millisecond(606)),\n                         Offset(Offset.UTCMinus, Hour(1), Minute(0)))\n// zoneTime2: wen.datetime.ZoneTime = ZoneTime(Time(Hour(10),Minute(31),Second(23),Millisecond(606)),Offset(UTCMinus,Hour(1),Minute(0)))\n\nval zoneTime3 = ZoneTime(Time(Hour(7), Minute(53), Second(23), Millisecond(900)),\n                         Offset(Offset.UTCPlus, Hour(0), Minute(30)))\n// zoneTime3: wen.datetime.ZoneTime = ZoneTime(Time(Hour(7),Minute(53),Second(23),Millisecond(900)),Offset(UTCPlus,Hour(0),Minute(30)))\n\nzoneTime1.show\n// res5: String = 08:15:02Z\n\nzoneTime2.show\n// res6: String = 10:31:23-01:00\n\nzoneTime3.show\n// res7: String = 07:53:23+00:30\n\nval zoneTime1 = ZoneTime(time, Offset.UTC)\n// zoneTime1: wen.datetime.ZoneTime = ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCPlus,Hour(0),Minute(0)))\n\nval zoneTime2 = ZoneTime(time, Offset(Offset.UTCMinus, Hour(1), Minute(0)))\n// zoneTime2: wen.datetime.ZoneTime = ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCMinus,Hour(1),Minute(0)))\n\nval zoneTime3 = ZoneTime(time, Offset(Offset.UTCPlus, Hour(2), Minute(45)))\n// zoneTime3: wen.datetime.ZoneTime = ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCPlus,Hour(2),Minute(45)))\n\nval zoneDateTime1 = ZoneDateTime(date1, zoneTime1)\n// zoneDateTime1: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(25),July,Year(1975,AD)),ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCPlus,Hour(0),Minute(0))))\n\nval zoneDateTime2 = ZoneDateTime(date2, zoneTime2)\n// zoneDateTime2: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(1),January,Year(2131,BC)),ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCMinus,Hour(1),Minute(0))))\n\nval zoneDateTime3 = ZoneDateTime(date3, zoneTime3)\n// zoneDateTime3: wen.datetime.ZoneDateTime = ZoneDateTime(Date(Day(2),March,Year(1,BC)),ZoneTime(Time(Hour(8),Minute(53),Second(23),Millisecond(900)),Offset(UTCPlus,Hour(2),Minute(45))))\n\nzoneDateTime1.show\n// res9: String = 1975-07-25T08:53:23Z\n\nzoneDateTime2.show\n// res10: String = -2130-01-01T08:53:23-01:00\n\nzoneDateTime3.show\n// res11: String = 0000-03-02T08:53:23+02:45\n```\n\n## Circe Instances\n\nCirce ISO-8601 encoders and decoders are provided for Date, Time, DateTime, ZoneTime, Offset, and ZoneDateTime.\nCirce encoders and decoders are also provided for Day, WeekDay, Month, Year, Epoch, Hour, Minute, Second, and Millisecond.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlopes%2Fwen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlopes%2Fwen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlopes%2Fwen/lists"}