├── .gitignore ├── .travis.yml ├── LICENSE ├── NOTICE ├── README.md ├── build.sbt ├── project ├── build.properties ├── coveralls-settings.sh ├── plugins.sbt └── site │ ├── site.css │ ├── site.html │ └── site.js ├── rootdoc.txt └── src ├── main └── scala │ ├── codes │ └── reactive │ │ └── package.scala │ └── scalatime │ ├── control │ ├── Catcher.scala │ └── package.scala │ ├── impl │ ├── ChronoOps.scala │ ├── IntOps.scala │ ├── LongOps.scala │ ├── MonthDayOps.scala │ ├── MonthOps.scala │ ├── StringOps.scala │ ├── TemporalAccessorOps.scala │ ├── TemporalAdjusterOps.scala │ ├── TemporalAmountOps.scala │ ├── TemporalOps.scala │ ├── TemporalQueryOps.scala │ ├── TemporalUnitOps.scala │ ├── ToAllOps.scala │ ├── YearMonthOps.scala │ └── YearOps.scala │ └── package.scala └── test └── scala ├── codes └── reactive │ └── CompatFunSuite.scala └── scalatime ├── control └── CatchersSuite.scala └── impl ├── ChronoLocalDateOpsSuite.scala ├── ChronoLocalDateTimeOpsSuite.scala ├── ChronoZonedDateTimeOpsSuite.scala ├── IntOpsSuite.scala ├── LongOpsSuite.scala ├── MonthDayOpsSuite.scala ├── MonthOpsSuite.scala ├── StringOpsSuite.scala ├── TemporalAccessorOpsSuite.scala ├── TemporalAdjusterOpsSuite.scala ├── TemporalAmountOpsSuite.scala ├── TemporalOpsSuite.scala ├── TemporalQueryOpsSuite.scala ├── TemporalUnitOpsSuite.scala ├── ToOpsSuite.scala ├── YearMonthOpsSuite.scala └── YearOpsSuite.scala /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | !.idea/copyright/ 3 | !.idea/inspectionProfiles/ 4 | !.idea/codeStyleSettings.xml 5 | !.idea/scalastyle_config.xml 6 | .idea_modules/ 7 | target/ 8 | out/ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: "scala" 4 | 5 | matrix: 6 | include: 7 | - jdk: oraclejdk8 8 | - jdk: openjdk11 9 | 10 | script: 11 | - sbt clean +test 12 | 13 | after_success: 14 | - ./project/coveralls-settings.sh 15 | - sbt clean test coverageReport coveralls 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | scala-time 2 | =========== 3 | 4 | Copyright 2014, 2019 the original author and/or authors. 5 | 6 | 7 | ------------------- 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | scala-time 2 | ========== 3 | 4 | Basic Scala utilities allowing for easier use of *`java.time`* APIs. 5 | 6 | *Note:* Support has now been dropped for JDK 7 and the [Threeten BP][12] backport APIs. 7 | 8 | ###### Supported Scala Versions: 9 | - 2.13 10 | - 2.12 11 | - 2.11 12 | - 2.10 13 | 14 |
15 | 16 | [![][Coverage Status Image]][Coverage Status] 17 | [![][Build Status Image]][Build Status] 18 | [![][License Badge]][License] 19 | [![][Maven Central Badge]][Maven Central Repo] 20 | 21 | __________________________________ 22 | 23 | Usage: 24 | ----- 25 | This project is not *yet* considered stable, and the API is subject to change, however version `0.4.2` binaries are 26 | published to the [`Maven Central`][Maven Central Repo] public repository. 27 | 28 | ###### [sbt][6] coordinates: 29 | 30 | ```scala 31 | // Requires JDK 1.8 and above 32 | "codes.reactive" %% "scala-time" % "0.4.2" 33 | ``` 34 | 35 | #### Documentation: 36 | See the [project website][9] for links to current documentation. 37 | 38 | #### Examples: 39 | ```scala 40 | import java.time._ 41 | import scalatime._ // NOTE: Package name was changed from codes.reactive.scalatime => scalatime 42 | // for versions 0.5.x and newer. If still using 0.4.x, use codes.reactive.scalatime 43 | 44 | // Obtain a Duration instance from a Long 45 | val duration = 10L minutes 46 | 47 | val otherDuration = 1L minute 48 | 49 | // Obtain a Period instance from an Int 50 | val period = 2 weeks 51 | 52 | // Obtains a LocalDate instance 53 | val localDate = LocalDate.of(2014, 6, 7) 54 | 55 | // Obtain a default TemporalQuery for precision 56 | val query = temporal.TemporalQueries.precision 57 | 58 | // Obtain a Duration instance from a sum of Durations 59 | duration + otherDuration 60 | 61 | // Add a TemporalAmount to a Temporal 62 | period <<+ localDate 63 | 64 | // Add a TemporalAmount to a Temporal 65 | localDate + period 66 | 67 | // Subtract a TemporalAmount from a Temporal 68 | localDate - period 69 | 70 | // Query a specified Temporal 71 | val result = query |> localDate 72 | ``` 73 | 74 | 75 | __________________________________ 76 | 77 | 78 | License 79 | ------- 80 | See the NOTICE file distributed with this work for additional 81 | information regarding copyright ownership 82 | 83 | Licensed under the Apache License, Version 2.0 (the "License"); 84 | you may not use this work except in compliance with the License. 85 | You may obtain a copy of the License at 86 | 87 | [`http://www.apache.org/licenses/LICENSE-2.0`][License] 88 | 89 | Unless required by applicable law or agreed to in writing, software 90 | distributed under the License is distributed on an "AS IS" BASIS, 91 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 92 | See the License for the specific language governing permissions and 93 | limitations under the License. 94 | 95 | 96 | 97 | [License]: http://www.apache.org/licenses/LICENSE-2.0 98 | [5]: https://oss.sonatype.org/content/repositories/snapshots 99 | [6]: http://scala-sbt.org 100 | [9]: http://oss.reactive.codes/scala-time 101 | [12]: http://www.threeten.org 102 | [Build Status]:https://travis-ci.org/reactivecodes/scala-time 103 | [Build Status Image]:https://travis-ci.org/reactivecodes/scala-time.svg?branch=master 104 | [Coverage Status]:https://coveralls.io/r/reactivecodes/scala-time?branch=master 105 | [Coverage Status Image]:https://coveralls.io/repos/github/reactivecodes/scala-time/badge.svg?branch=master 106 | [License Badge]:https://img.shields.io/badge/License-Apache%202-brightgreen.svg 107 | [Maven Central Badge]: https://maven-badges.herokuapp.com/maven-central/codes.reactive/scala-time_2.11/badge.svg 108 | [Maven Central Repo]: https://repo1.maven.org/maven2/codes/reactive/scala-time_2.11/ 109 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | lazy val scalaTime = (project in file(".")) 2 | .enablePlugins(SbtCodesOsgi) 3 | 4 | 5 | site.settings 6 | 7 | ghpages.settings 8 | 9 | version := "0.5.0-SNAPSHOT" 10 | 11 | organization := "codes.reactive" 12 | 13 | description := "Basic Scala wrapper for convenient use of JDK 1.8.0 time libraries." 14 | 15 | startYear := Some(2014) 16 | 17 | homepage := Some(url("https://oss.reactive.codes/scala-time")) 18 | 19 | apiURL := Some(url(s"http://oss.reactive.codes/scala-time/${version.value}")) 20 | 21 | apacheLicensed 22 | 23 | publishOSS 24 | 25 | scalaVersion := crossScalaVersions.value.head 26 | 27 | crossScalaVersions := Seq("2.13.0", "2.12.8", "2.11.12", "2.10.7") 28 | 29 | libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.0.+" % Test) 30 | 31 | codesCompileOpts 32 | 33 | codesDocOpts 34 | 35 | codesUnidocOpts 36 | 37 | scalacOptions in(Compile, compile) += "-language:postfixOps" 38 | 39 | OsgiKeys.bundleSymbolicName := "codes.reactive.scalatime" 40 | 41 | OsgiKeys.privatePackage := Seq("codes.reactive.scalatime*") 42 | 43 | OsgiKeys.exportPackage := Seq("codes.reactive.scalatime*") 44 | 45 | scalastyleConfig <<= baseDirectory(_ / ".idea/scalastyle_config.xml") 46 | 47 | SiteKeys.siteMappings := { 48 | val dir = baseDirectory.value / "project/site" 49 | Seq( 50 | (dir / "site.html") → "index.html", 51 | (dir / "site.css") → "site.css", 52 | (dir / "site.js") → "site.js") 53 | } 54 | 55 | SiteKeys.siteMappings <++= (mappings in(ScalaUnidoc, packageDoc), version) map { (m, v) => 56 | for ((f, d) <- m) yield (f, s"$v/$d") 57 | } 58 | 59 | git.remoteRepo := codesGithubRepo.value.developerConnection.drop(8) 60 | 61 | addDevelopers(("arashi01", "Ali Salim Rashid", "a.rashid@zantekk.com")) 62 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | # See the NOTICE file distributed with this work for additional 2 | # information regarding Copyright ownership. The author/authors 3 | # license this file to you under the terms of the Apache License 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. You may obtain a copy of the 6 | # License at: 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the 15 | # License. 16 | 17 | sbt.version=0.13.18 18 | -------------------------------------------------------------------------------- /project/coveralls-settings.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ## Hack to workaround scoverage/sbt-scoverage#115 3 | ## We let travis append coverage settings for coverage tasks only 4 | 5 | ci=${TRAVIS} 6 | 7 | scoverage_plugin_dependency="addSbtPlugin(\"org.scoverage\" % \"sbt-scoverage\" % \"1.6.0\")" 8 | 9 | coveralls_plugin_dependency="addSbtPlugin(\"org.scoverage\" % \"sbt-coveralls\" % \"1.2.7\")" 10 | 11 | coveralls_token_setting="CoverallsKeys.coverallsToken := sys.env.get(\"COVERALLS_TOKEN\")" 12 | 13 | coveralls_enabled_setting="coverageEnabled := true" 14 | 15 | if [ -n "${ci}" ]; then 16 | echo -e "\n\n${scoverage_plugin_dependency}\n\n${coveralls_plugin_dependency}" >> ${TRAVIS_BUILD_DIR}/project/plugins.sbt 17 | echo -e "\n\n${coveralls_token_setting}\n\n${coveralls_enabled_setting}\n\n" >> ${TRAVIS_BUILD_DIR}/build.sbt 18 | exit 0 19 | else 20 | exit 0 21 | fi 22 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | logLevel := Level.Warn 2 | 3 | addSbtPlugin("codes.reactive.sbt" % "sbt-codes" % "0.3.0") 4 | 5 | addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0") 6 | 7 | addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3") 8 | 9 | addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.1") 10 | -------------------------------------------------------------------------------- /project/site/site.css: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | /* TeamCity Status Widget */ 20 | table.tcTable { 21 | width: 100%; 22 | margin-bottom: 5px; 23 | padding: 5px; 24 | font: 80% "Helvetica Neue", Arial, sans-serif; 25 | } 26 | 27 | table.tcTable tr { 28 | vertical-align: top; 29 | } 30 | 31 | table.tcTable td { 32 | padding-bottom: 5px; 33 | } 34 | 35 | /*----------- Components*/ 36 | table.tcTable div.projectName { 37 | /* UNCOMMENT TO REMOVE PROJECT NAME FROM THE EMBEDLET */ 38 | display: none; 39 | 40 | margin: 0; 41 | padding: 0; 42 | border-bottom: 1px solid #ccc; 43 | font-size: 130%; 44 | } 45 | 46 | table.tcTable td.buildConfigurationName { 47 | font-weight: bold; 48 | padding-right: 10px; 49 | } 50 | 51 | table.tcTable td.buildNumberDate { 52 | /* UNCOMMENT TO REMOVE BUILD NUMBER AND DATE FROM THE EMBEDLET */ 53 | /*display:none;*/ 54 | 55 | padding-right: 10px; 56 | } 57 | 58 | table.tcTable td.buildResults { 59 | /* UNCOMMENT TO REMOVE BUILD RESULTS/ARTIFACTS LINK FROM THE EMBEDLET */ 60 | display: none; 61 | } 62 | 63 | table.tcTable td.buildNumberDate div.teamCityDateTime { 64 | /* UNCOMMENT TO REMOVE THE LAST BUILD DATE FROM THE EMBEDLET */ 65 | /*display:none;*/ 66 | 67 | color: #696B71; 68 | } 69 | 70 | table.tcTable span.teamCityIcon { 71 | white-space: nowrap; 72 | } 73 | 74 | /*------- Appearance */ 75 | table.tcTable img { 76 | vertical-align: top; 77 | } 78 | 79 | table.tcTable a { 80 | color: #1564C2; 81 | text-decoration: none; 82 | } 83 | 84 | table.tcTable a:hover { 85 | text-decoration: underline; 86 | color: #1564C2; 87 | } 88 | 89 | /* Sticky footer styles */ 90 | html { 91 | position: relative; 92 | min-height: 100%; 93 | } 94 | 95 | body { 96 | /* Margin bottom by footer height */ 97 | margin-bottom: 60px; 98 | } 99 | 100 | .footer { 101 | position: absolute; 102 | bottom: 0; 103 | width: 100%; 104 | /* Set the fixed height of the footer here */ 105 | height: 60px; 106 | background-color: #f5f5f5; 107 | } 108 | 109 | /* Custom page CSS */ 110 | 111 | body > .container { 112 | padding: 60px 15px 0; 113 | } 114 | 115 | .container .text-muted { 116 | margin: 20px 0; 117 | } 118 | 119 | .footer > .container { 120 | padding-right: 15px; 121 | padding-left: 15px; 122 | } 123 | 124 | code { 125 | font-size: 80%; 126 | } 127 | -------------------------------------------------------------------------------- /project/site/site.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Scala Time 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 45 | 46 |
47 | 53 | 54 |
55 | 56 |
57 |

Documentation

58 | 59 |
60 | 61 |
62 | 63 |
64 | 65 |
66 |
67 |

Usage

68 | 69 |
70 |

71 | This project is not yet considered stable, and the API is subject to change, however binaries are published to the Maven Central Repository.

72 | 73 |
74 | If using sbt, the current artefacts can be found 75 | at the following coordinates: 76 |
77 |

"codes.reactive" %% "scala-time" % "0.4.1"

78 |
79 |
80 |

81 | See version specific documentation for usage examples and information. 82 |

83 |
84 |
85 |
86 | 87 |
88 |

Build Status

89 | 100 |
101 |
102 |
103 |
104 | 105 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /project/site/site.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var callback = function (data) { 3 | for (var i = 0; i < data.tree.length; i++) { 4 | var tree = data.tree[i]; 5 | if (tree.type === "tree") { 6 | var path = tree.path; 7 | $("#scaladoc").append("" + path + "") 8 | } 9 | } 10 | }; 11 | $.get("https://api.github.com/repos/reactivecodes/scala-time/git/trees/gh-pages", {}, callback) 12 | })(); 13 | -------------------------------------------------------------------------------- /rootdoc.txt: -------------------------------------------------------------------------------- 1 | == Scala Time == 2 | '''scala-time''' is a simple Scala wrapper for easier use of the '''java.time''' time API. 3 | 4 | ==== Overview ==== 5 | The library is contained in the '''[[scalatime]]''' package which includes extension methods provided via implicit 6 | conversion methods to Scala value classes. Value classes themselves are contained in the '''[[scalatime.impl impl]]''' 7 | package and are named after the corresponding type for which extension methods are provided. 8 | 9 | For example, to see methods available to [[scala.Int Int]] instances, see the [[scalatime.impl.IntOps IntOps]] api 10 | documentation. A quick reference table to documentation for all available extension methods is below: 11 | 12 | | Type | Value Class | 13 | |------------------------------------------ |------------------------------------------------------------------ | 14 | | [[java.time.chrono.ChronoLocalDate]] | [[scalatime.impl.ChronoLocalDateOps ChronoLocalDateOps]] | 15 | | [[java.time.chrono.ChronoLocalDateTime]] | [[scalatime.impl.ChronoLocalDateTimeOps ChronoLocalDateTimeOps]] | 16 | | [[java.time.chrono.ChronoZonedDateTime]] | [[scalatime.impl.ChronoZonedDateTime ChronoZonedDateTime]] | 17 | | [[java.time.Duration]] | [[scalatime.impl.DurationOps DurationOps]] | 18 | | [[scala.Int Int]] | [[scalatime.impl.IntOps IntOps]] | 19 | | [[scala.Long Long]] | [[scalatime.impl.LongOps LongOps]] | 20 | | [[java.time.MonthDay]] | [[scalatime.impl.MonthDayOps MonthDayOps]] | 21 | | [[java.time.Month]] | [[scalatime.impl.MonthOps MonthOps]] | 22 | | [[java.time.Period]] | [[scalatime.impl.PeriodOps PeriodOps]] | 23 | | [[scala.Predef.String String]] | [[scalatime.impl.StringOps StringOps]] | 24 | | [[java.time.temporal.TemporalAccessor]] | [[scalatime.impl.TemporalAccessorOps TemporalAccessorOps]] | 25 | | [[java.time.temporal.TemporalAdjuster]] | [[scalatime.impl.TemporalAdjusterOps TemporalAdjusterOps]] | 26 | | [[java.time.temporal.TemporalAmount]] | [[scalatime.impl.TemporalAmountOps TemporalAmountOps]] | 27 | | [[java.time.temporal.Temporal]] | [[scalatime.impl.TemporalOps TemporalOps]] | 28 | | [[java.time.temporal.TemporalQuery]] | [[scalatime.impl.TemporalQueryOps TemporalQueryOps]] | 29 | | [[java.time.temporal.TemporalUnit]] | [[scalatime.impl.TemporalUnitOps TemporalUnitOps]] | 30 | 31 |
32 | 33 | ==== Usage Examples ==== 34 | @example 35 | {{{ 36 | // Import the required classes path: 37 | import java.time._ 38 | import scalatime._ 39 | 40 | // Obtain a Duration instance from a Long 41 | val duration = 10L minutes 42 | 43 | val otherDuration = 1L minute 44 | 45 | // Obtain a Period instance from an Int 46 | val period = 2 weeks 47 | 48 | // Obtain a LocalDate instance 49 | val localDate = LocalDate.of(2014, 6, 7) 50 | 51 | // Obtain a default TemporalQuery for the precision 52 | val query = temporal.TemporalQueries.precision 53 | 54 | // Obtain a Duration instance from a sum of Durations 55 | duration + otherDuration 56 | 57 | // Add a TemporalAmount to a Temporal 58 | localDate + period 59 | 60 | // Add a TemporalAmount to a Temporal 61 | period <<+ localDate 62 | 63 | // Subtract a TemporalAmount from a Temporal 64 | localDate - period 65 | 66 | // Query a specified Temporal 67 | val result = query |> localDate 68 | }}} 69 | -------------------------------------------------------------------------------- /src/main/scala/codes/reactive/package.scala: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package codes 20 | 21 | 22 | package object reactive { 23 | 24 | /** Compatibility layer to allow easier migration from codes.reactive.scalatime -> scalatime 25 | * We need this hack since Scala does not support deprecating package objects yet. 26 | */ 27 | @deprecated("The package name changed from 'codes.reactive.scalatime' -> 'scalatime'. Please update imports" + 28 | " accordingly by removing references to the 'codes.reactive' prefix.", "0.5.0") 29 | object scalatime extends _root_.scalatime.impl.ToAllOps with _root_.scalatime.impl.ToAllStd { 30 | 31 | @deprecated("The package name changed from 'codes.reactive.scalatime' -> 'scalatime'. Please update imports" + 32 | " accordingly by removing references to the 'codes.reactive' prefix.", "0.5.0") 33 | object control { 34 | 35 | import _root_.scalatime.control.{Catcher => RealCatcher} 36 | 37 | @deprecated("The package name changed from 'codes.reactive.scalatime' -> 'scalatime'. Please update imports" + 38 | " accordingly by removing references to the 'codes.reactive' prefix.", "0.5.0") 39 | val Catcher = RealCatcher 40 | } 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/control/Catcher.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime 20 | package control 21 | 22 | import java.time.DateTimeException 23 | import java.time.format.DateTimeParseException 24 | import java.time.temporal.UnsupportedTemporalTypeException 25 | import java.time.zone.ZoneRulesException 26 | 27 | import scala.reflect.ClassTag 28 | import scala.util.control.Exception 29 | import scala.util.control.Exception.Catcher 30 | 31 | /** Provides methods for obtaining default [[scala.util.control.Exception.Catcher Catchers]] for possible 32 | * [[DateTimeException DateTimeExceptions]] thrown by the underlying Java API. 33 | * 34 | * @example 35 | * {{{ 36 | * import java.time._ 37 | * import codes.reactive.scalatime._ 38 | * import control.Catcher 39 | * 40 | * // Obtain a TimeCatcher for all DateTimeExceptions 41 | * val catchAllLocalDate = Catcher.all(_ => LocalDate.now()) 42 | * 43 | * // Use the catcher to recover from a parse error 44 | * val recovered = Try { LocalDate.parse(")(&#)(@*@&#%@#%@#%)") } recover catchAllLocalDate 45 | * }}} 46 | * @define Obt Obtains a [[scala.util.control.Exception.Catcher Catcher]] for 47 | */ 48 | object Catcher { 49 | 50 | private def catcher[A, Ex <: Throwable : ClassTag](f: Ex => A): Catcher[A] = 51 | Exception.mkCatcher((x: Ex) => x match { 52 | case _: Ex => true; 53 | case _ => false 54 | }, f)(implicitly[ClassTag[Ex]]) 55 | 56 | /** $Obt all [[DateTimeException]]s. 57 | * 58 | * @param f function to execute if the exception is encountered. 59 | */ 60 | def all[A](f: DateTimeException => A): Catcher[A] = catcher(f) 61 | 62 | /** $Obt an [[java.time.temporal.UnsupportedTemporalTypeException]], an exception indicating that a 63 | * [[java.time.temporal.ChronoField]] or [[java.time.temporal.ChronoUnit]]is not supported for a Temporal class. 64 | * 65 | * @param f function to execute if the exception is encountered. 66 | */ 67 | def unsupportedTemporalType[A](f: UnsupportedTemporalTypeException => A): Catcher[A] = 68 | catcher(f) 69 | 70 | /** $Obt a [[java.time.zone.ZoneRulesException]], an exception indicating a problems with the configured time-zone rules. */ 71 | def zoneRules[A](f: ZoneRulesException => A): Catcher[A] = catcher(f) 72 | 73 | /** $Obt a [[java.time.format.DateTimeParseException]], an exception indicating when an error occurs during parsing. */ 74 | def dateTimeParseException[A](f: DateTimeParseException => A): Catcher[A] = catcher(f) 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/control/package.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime 20 | 21 | 22 | /** Provides functionality relating to Exception handling, validation and control structures. 23 | * 24 | * @see [[scalatime.control.Catcher]] 25 | */ 26 | package object control 27 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/ChronoOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.chrono.{ChronoLocalDate, ChronoLocalDateTime, ChronoZonedDateTime} 22 | import java.time.format.DateTimeFormatter 23 | import java.time.{DateTimeException, LocalTime, ZoneId} 24 | 25 | import scala.language.implicitConversions 26 | 27 | /** Enriches a [[ChronoLocalDate]] with additional methods. */ 28 | final case class ChronoLocalDateOps(underlying: ChronoLocalDate) extends AnyVal { 29 | 30 | /** Combines this date with a time to create a LocalDateTime. **/ 31 | def %%[A <: underlying.type](time: LocalTime): ChronoLocalDateTime[A] = 32 | underlying.atTime(time).asInstanceOf[ChronoLocalDateTime[A]] 33 | 34 | /** Formats this date using the specified formatter. 35 | * 36 | * @throws DateTimeException - if an error occurs during formatting. 37 | */ 38 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 39 | 40 | /** Formats this date using the specified formatter. 41 | * 42 | * @throws DateTimeException - if an error occurs during formatting. 43 | */ 44 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 45 | } 46 | 47 | trait ToChronoLocalDateOps { 48 | implicit final def toChronoLocalDateOpsFromChronoLocalDate(f: ChronoLocalDate): ChronoLocalDateOps = 49 | new ChronoLocalDateOps(f) 50 | } 51 | 52 | 53 | /** Enriches a [[ChronoLocalDateTime]] with additional methods. */ 54 | final case class ChronoLocalDateTimeOps[A <: ChronoLocalDate](underlying: ChronoLocalDateTime[A]) extends AnyVal { 55 | 56 | /** Combines this date-time with a time-zone to create a ZonedDateTime. **/ 57 | def %%(zone: ZoneId): ChronoZonedDateTime[A] = underlying.atZone(zone) 58 | 59 | /** Alias for [[%%]].Combines this date-time with a time-zone to create a ZonedDateTime. **/ 60 | def ±(zone: ZoneId): ChronoZonedDateTime[A] = %%(zone) 61 | 62 | /** Formats this date using the specified formatter. 63 | * 64 | * @throws DateTimeException - if an error occurs during formatting. 65 | */ 66 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 67 | 68 | /** Formats this date using the specified formatter. 69 | * 70 | * @throws DateTimeException - if an error occurs during formatting. 71 | */ 72 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 73 | 74 | } 75 | 76 | trait ToChronoLocalDateTimeOps { 77 | implicit final def toChronoLocalDatetimeOpsFromChronoLocalDateTime[A <: ChronoLocalDate](f: ChronoLocalDateTime[A]): 78 | ChronoLocalDateTimeOps[A] = new ChronoLocalDateTimeOps(f) 79 | } 80 | 81 | 82 | /** Enriches a [[ChronoZonedDateTime]] with additional methods. */ 83 | final case class ChronoZonedDateTimeOps[A <: ChronoLocalDate](underlying: ChronoZonedDateTime[A]) extends AnyVal { 84 | 85 | /** Formats this date using the specified formatter. 86 | * 87 | * @throws DateTimeException - if an error occurs during formatting. 88 | */ 89 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 90 | 91 | /** Formats this date using the specified formatter. 92 | * 93 | * @throws DateTimeException - if an error occurs during formatting. 94 | */ 95 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 96 | 97 | } 98 | 99 | trait ToChronoZonedDateTimeOps { 100 | implicit final def toChronoZonedDatetimeOpsFromChronoLocalDateTime[A <: ChronoLocalDate](f: ChronoZonedDateTime[A]): 101 | ChronoZonedDateTimeOps[A] = new ChronoZonedDateTimeOps(f) 102 | } 103 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/IntOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.Period 22 | 23 | import scala.language.implicitConversions 24 | 25 | /** Enriches a [[scala.Int]] with methods for obtaining [[Period]] instances. */ 26 | final case class IntOps(underlying: Int) extends AnyVal { 27 | 28 | /** Obtains a [[Period]] representing a number of days. */ 29 | def day: Period = days 30 | 31 | /** Obtains a [[Period]] representing a number of days. */ 32 | def days: Period = Period.ofDays(underlying) // TODO? Better way to overload day/days when used on literals. 33 | // ie. both Period and Duration can be constructed from Int literals 34 | 35 | /** Obtains a [[Period]] representing a number of weeks. */ 36 | def week: Period = weeks 37 | 38 | /** Obtains a [[Period]] representing a number of weeks. */ 39 | def weeks: Period = Period.ofWeeks(underlying) 40 | 41 | /** Obtains a [[Period]] representing a number of months. */ 42 | def month: Period = months 43 | 44 | /** Obtains a [[Period]] representing a number of months. */ 45 | def months: Period = Period.ofMonths(underlying) 46 | 47 | /** Obtains a [[Period]] representing a number of years. */ 48 | def year: Period = years 49 | 50 | /** Obtains a [[Period]] representing a number of years. */ 51 | def years: Period = Period.ofYears(underlying) 52 | 53 | } 54 | 55 | trait ToIntOps extends Any { 56 | implicit final def toIntOpsFromLong(v: Int): IntOps = new IntOps(v) 57 | } 58 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/LongOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.Duration 22 | 23 | import scala.language.implicitConversions 24 | 25 | /** Enriches a [[scala.Int]] with methods for obtaining [[Duration]] instances. */ 26 | final case class LongOps(underlying: Long) extends AnyVal { 27 | 28 | /** Obtains a [[Duration]] representing a number of nanoseconds. */ 29 | def nano: Duration = nanos 30 | 31 | /** Obtains a [[Duration]] representing a number of nanoseconds. */ 32 | def nanos: Duration = Duration.ofNanos(underlying) 33 | 34 | /** Obtains a [[Duration]] representing a number of milliseconds. */ 35 | def milli: Duration = millis 36 | 37 | /** Obtains a [[Duration]] representing a number of milliseconds. */ 38 | def millis: Duration = Duration.ofMillis(underlying) 39 | 40 | /** Obtains a [[Duration]] representing a number of seconds. */ 41 | def second: Duration = seconds 42 | 43 | /** Obtains a [[Duration]] representing a number of seconds. */ 44 | def seconds: Duration = Duration.ofSeconds(underlying) 45 | 46 | /** Obtains a [[Duration]] representing a number of minutes. */ 47 | def minute: Duration = minutes 48 | 49 | /** Obtains a [[Duration]] representing a number of minutes. */ 50 | def minutes: Duration = Duration.ofMinutes(underlying) 51 | 52 | /** Obtains a [[Duration]] representing a number of hours. */ 53 | def hour: Duration = hours 54 | 55 | /** Obtains a [[Duration]] representing a number of hours. */ 56 | def hours: Duration = Duration.ofHours(underlying) 57 | 58 | /** Obtains a [[Duration]] representing a number of days. */ 59 | def day: Duration = days 60 | 61 | /** Obtains a [[Duration]] representing a number of days. */ 62 | def days: Duration = Duration.ofDays(underlying) 63 | 64 | } 65 | 66 | trait ToLongOps extends Any { 67 | implicit final def toLongOpsFromLong(v: Long): LongOps = new LongOps(v) 68 | } 69 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/MonthDayOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatter 22 | import java.time.{DateTimeException, Month, MonthDay} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches [[MonthDay]] instances with additional methods. */ 27 | final case class MonthDayOps(underlying: MonthDay) extends AnyVal { 28 | 29 | /** Returns `true` if this month-day is before the specified one. */ 30 | def <(other: MonthDay): Boolean = underlying.isBefore(other) 31 | 32 | /** Returns `true` if this month-day is equal to or before the specified one. */ 33 | def <=(other: MonthDay): Boolean = underlying.equals(other) || underlying.isBefore(other) 34 | 35 | /** Returns `true` if this month-day is after the specified one. */ 36 | def >(other: MonthDay): Boolean = underlying.isAfter(other) 37 | 38 | /** Returns `true` if this month-day is equal to or after the specified one. */ 39 | def >=(other: MonthDay): Boolean = underlying.equals(other) || underlying.isAfter(other) 40 | 41 | /** Obtains a copy of this MonthDay with the month-of-year altered. */ 42 | def ~=(month: Month): MonthDay = underlying.`with`(month) 43 | 44 | /** Obtains a copy of this MonthDay with the day-of-month altered. 45 | * 46 | * @throws DateTimeException if the day-of-month value is invalid. 47 | * @throws DateTimeException if the day-of-month value is invalid for the month. 48 | */ 49 | def ~=(day: Int): MonthDay = underlying.withDayOfMonth(day) 50 | 51 | /** Obtains a copy of this MonthDay with the month-of-year and/or day-of-month altered. 52 | * 53 | * @throws DateTimeException if the day-of-month value is invalid. 54 | * @throws DateTimeException if the day-of-month value is invalid for the month. 55 | */ 56 | def ~=(month: Option[Month], day: Option[Int]): MonthDay = (month, day) match { 57 | case (Some(m), Some(d)) => def md1 = underlying.withMonth(m.getValue); md1.withDayOfMonth(d) 58 | case (Some(m), None) => underlying.withMonth(m.getValue) 59 | case (None, Some(d)) => underlying.withDayOfMonth(d) 60 | case _ => underlying 61 | } 62 | 63 | /** Formats this month-day using the specified formatter. 64 | * 65 | * @throws DateTimeException - if an error occurs during printing 66 | */ 67 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 68 | 69 | /** Formats this month-day using the specified formatter. 70 | * 71 | * @throws DateTimeException - if an error occurs during printing 72 | */ 73 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 74 | } 75 | 76 | trait ToMonthDayOps extends Any { 77 | implicit final def toMonthDayOpsFromMonthDay(f: MonthDay): MonthDayOps = new MonthDayOps(f) 78 | } 79 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/MonthOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.temporal.Temporal 22 | import java.time.{DateTimeException, Month, MonthDay} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches a [[Month]] with additional methods. */ 27 | final case class MonthOps(underlying: Month) extends AnyVal { 28 | 29 | /** Obtains the month-of-year which is the specified number of months after this one. */ 30 | def +(months: Int): Month = underlying.plus(months) 31 | 32 | /** Obtains the month-of-year which is the specified number of months before this one. */ 33 | def -(months: Int): Month = underlying.minus(months) 34 | 35 | /** Obtains a [[java.time.MonthDay]] by combining this month with the specified day-of-month. 36 | * 37 | * @throws DateTimeException if the day-of-month is invalid for the month. 38 | */ 39 | def /(day: Int): MonthDay = MonthDay.of(underlying, day) 40 | 41 | def =~(temporal: Temporal): Temporal = underlying.adjustInto(temporal) 42 | 43 | } 44 | 45 | trait ToMonthOps extends Any { 46 | implicit final def toMonthOpsFromMonth(f: Month): MonthOps = new MonthOps(f) 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/StringOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | 22 | import java.time.format.{DateTimeFormatter, DateTimeParseException} 23 | import java.time.temporal.{TemporalAccessor, TemporalQuery} 24 | 25 | import scala.language.implicitConversions 26 | 27 | 28 | final case class StringOps(underlying: String) extends AnyVal { 29 | 30 | def |>(formatter: DateTimeFormatter): TemporalAccessor = formatter.parse(underlying) 31 | 32 | def |>[A](formatter: DateTimeFormatter, query: TemporalQuery[A]): A = formatter.parse(underlying, query) 33 | 34 | 35 | /** Fully parses the text producing a temporal object. 36 | * 37 | * @throws DateTimeParseException if unable to parse the requested result. 38 | */ 39 | def ▹(formatter: DateTimeFormatter): TemporalAccessor = formatter.parse(underlying) 40 | 41 | def ▹[A](formatter: DateTimeFormatter, query: TemporalQuery[A]): A = formatter.parse(underlying, query) 42 | 43 | 44 | 45 | } 46 | 47 | trait ToStringOps { 48 | implicit final def toStringOpsFromString(f: String): StringOps = new StringOps(f) 49 | } 50 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalAccessorOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.DateTimeException 22 | import java.time.temporal.{TemporalAccessor, TemporalField, TemporalQuery} 23 | 24 | import scala.language.implicitConversions 25 | 26 | 27 | /** Enriches a [[TemporalAccessor]] with additional methods. */ 28 | final case class TemporalAccessorOps(underlying: TemporalAccessor) extends AnyVal { 29 | 30 | /** Queries this object using the specified [[java.time.temporal.TemporalQuery]] strategy object. 31 | * 32 | * @throws DateTimeException - if unable to query. 33 | * @throws ArithmeticException - if numeric overflow occurs. 34 | */ 35 | def |>[A](query: TemporalQuery[A]): A = underlying.query(query) 36 | 37 | /** Queries this object using the specified [[TemporalQuery]] strategy object. 38 | * 39 | * @throws DateTimeException - if unable to query. 40 | * @throws ArithmeticException - if numeric overflow occurs. 41 | */ 42 | def ▹[A](query: TemporalQuery[A]): A = underlying.query(query) 43 | 44 | /** Queries this object to obtain the value of the specified field as a `Long`. 45 | * 46 | * @throws DateTimeException - if a value for the field cannot be obtained. 47 | * @throws ArithmeticException - if numeric overflow occurs. 48 | */ 49 | def #|>(field: TemporalField): Long = underlying.getLong(field) 50 | 51 | /** Queries this object to obtain the value of the specified field as a `Long`. 52 | * 53 | * @throws DateTimeException - if a value for the field cannot be obtained. 54 | * @throws ArithmeticException - if numeric overflow occurs. 55 | */ 56 | def #▹(field: TemporalField): Long = underlying.getLong(field) 57 | 58 | } 59 | 60 | trait ToTemporalAccessorOps extends Any { 61 | 62 | implicit final def toTemporalAccessorOpsFromTemporalAccessor(f: TemporalAccessor): TemporalAccessorOps = 63 | new TemporalAccessorOps(f) 64 | } 65 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalAdjusterOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.DateTimeException 22 | import java.time.temporal.{Temporal, TemporalAdjuster} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches a [[TemporalAdjuster]] with additional methods. */ 27 | final case class TemporalAdjusterOps(underlying: TemporalAdjuster) extends AnyVal { 28 | 29 | /** Adjusts the provided temporal object using the logic encapsulated in this. 30 | * 31 | * @throws DateTimeException if unable to make the adjustment. 32 | * @throws ArithmeticException if numeric overflow occurs. 33 | */ 34 | def <<=[A <: Temporal](temporal: A): A = underlying.adjustInto(temporal).asInstanceOf[A] //TODO: Finalise method name 35 | 36 | } 37 | 38 | trait ToTemporalAdjusterOps extends Any { 39 | 40 | implicit final def toTemporalAdjusterOpsFromTemporalAdjuster(f: TemporalAdjuster): TemporalAdjusterOps = new TemporalAdjusterOps(f) 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalAmountOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.temporal.{Temporal, TemporalAmount, TemporalUnit, UnsupportedTemporalTypeException} 22 | import java.time.{Duration, Period} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches a [[TemporalAmount]] with scala friendly methods. */ 27 | final case class TemporalAmountOps(underlying: TemporalAmount) extends AnyVal { 28 | 29 | /** Adds this amount to the specified temporal object **/ 30 | def <<+(temporal: Temporal): Temporal = underlying.addTo(temporal) 31 | 32 | /** Subtracts this amount from the specified temporal object **/ 33 | def <<-(temporal: Temporal): Temporal = underlying.subtractFrom(temporal) 34 | } 35 | 36 | trait ToTemporalAmountOps extends Any { 37 | implicit final def toTemporalAmountOpsFromTemporalAmount(f: TemporalAmount): TemporalAmountOps = TemporalAmountOps(f) 38 | } 39 | 40 | 41 | /** Enriches a [[Duration! Duration]] with scala friendly methods. */ 42 | final case class DurationOps(underlying: Duration) extends AnyVal { 43 | 44 | /** Obtains a copy of this duration multiplied by the scalar. 45 | * 46 | * @throws ArithmeticException - if numeric overflow occurs 47 | */ 48 | def *(scalar: Int): Duration = underlying.multipliedBy(scalar) 49 | 50 | /** Obtains a copy of this duration with the specified duration added. 51 | * 52 | * @throws ArithmeticException - if numeric overflow occurs 53 | */ 54 | def +(duration: Duration): Duration = underlying.plus(duration) 55 | 56 | /** Obtains a copy of this duration with a duration added measured in terms of the specified unit. 57 | * 58 | * @throws UnsupportedTemporalTypeException - if the unit is not supported 59 | * @throws ArithmeticException - if numeric overflow occurs 60 | */ 61 | def +(amount: Long, unit: TemporalUnit): Duration = underlying.plus(amount, unit) 62 | 63 | /** Obtains a copy of this duration with the specified duration subtracted. 64 | * 65 | * @throws ArithmeticException - if numeric overflow occurs 66 | */ 67 | def -(duration: Duration): Duration = underlying.minus(duration) 68 | 69 | /** Obtains a copy of this duration with a duration subtracted measured in terms of the specified unit. 70 | * 71 | * @throws UnsupportedTemporalTypeException - if the unit is not supported 72 | * @throws ArithmeticException - if numeric overflow occurs 73 | */ 74 | def -(amount: Long, unit: TemporalUnit): Duration = underlying.minus(amount, unit) 75 | 76 | /** Obtains a copy of this duration divided by the divisor. 77 | * 78 | * @throws ArithmeticException - if numeric overflow occurs 79 | */ 80 | def /(divisor: Int): Duration = underlying.dividedBy(divisor) 81 | 82 | /** Swaps the sign of the total length of this duration. For example, PT1.3S will be returned as PT-1.3S. 83 | * 84 | * @throws ArithmeticException - if numeric overflow occurs 85 | */ 86 | def unary_! : Duration = underlying.negated 87 | 88 | /** Obtains a [[scala.concurrent.duration.Duration]] from the value of this duration in nanoseconds. 89 | * 90 | * @throws ArithmeticException - if numeric overflow occurs 91 | */ 92 | def asConcurrentDuration: concurrent.duration.Duration = concurrent.duration.Duration.fromNanos(underlying.toNanos) 93 | } 94 | 95 | trait ToDurationOps extends Any { 96 | implicit final def toDurationOpsFromDuration(f: Duration): DurationOps = DurationOps(f) 97 | } 98 | 99 | 100 | /** Enriches a [[Period! Period]] with scala friendly methods. */ 101 | final case class PeriodOps(underlying: Period) extends AnyVal { 102 | 103 | /** Obtains a copy of this period multiplied by the scalar. 104 | * 105 | * @throws ArithmeticException - if numeric overflow occurs 106 | */ 107 | def *(scalar: Int): Period = underlying.multipliedBy(scalar) 108 | 109 | /** Obtains a copy of this period with the specified period added. 110 | * 111 | * @throws ArithmeticException - if numeric overflow occurs 112 | */ 113 | def +(amount: TemporalAmount): Period = underlying.plus(amount) 114 | 115 | /** Obtains a copy of this period with the specified period subtracted. 116 | * 117 | * @throws ArithmeticException - if numeric overflow occurs 118 | */ 119 | def -(amount: TemporalAmount): Period = underlying.minus(amount) 120 | 121 | /** Obtains an instance of this type with each amount in this period negated. For example, a period of 122 | * "2 years, -3 months and 4 days" will be negated to "-2 years, 3 months and -4 days". No normalization is 123 | * performed. 124 | * 125 | * @throws ArithmeticException - if numeric overflow occurs, which only happens if one of the units 126 | * has the value Long.MIN_VALUE 127 | */ 128 | def unary_! : Period = underlying.negated 129 | } 130 | 131 | trait ToPeriodOps extends Any { 132 | 133 | implicit final def toPeriodOpsFromPeriod(f: Period): PeriodOps = PeriodOps(f) 134 | } 135 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.DateTimeException 22 | import java.time.temporal._ 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches a [[Temporal]] with additional methods. 27 | * 28 | * @define sameType Obtains an object of the same type as this object 29 | */ 30 | final case class TemporalOps(underlying: Temporal) extends AnyVal { 31 | 32 | /** $sameType with an amount added. 33 | * 34 | * @throws DateTimeException - if the addition cannot be made. 35 | * @throws ArithmeticException - if numeric overflow occurs. 36 | */ 37 | def +(amount: TemporalAmount): underlying.type = underlying.plus(amount) 38 | 39 | /** $sameType with an amount added. 40 | * 41 | * @throws DateTimeException - if the unit cannot be added. 42 | * @throws UnsupportedTemporalTypeException - if the unit is not supported. 43 | * @throws ArithmeticException - if numeric overflow occurs. 44 | */ 45 | def +(amount: Long, unit: TemporalUnit): underlying.type = underlying.plus(amount, unit) 46 | 47 | /** $sameType with an amount subtracted. 48 | * 49 | * @throws DateTimeException - if the subtraction cannot be made 50 | * @throws ArithmeticException - if numeric overflow occurs 51 | */ 52 | def -(amount: TemporalAmount): underlying.type = underlying.minus(amount) 53 | 54 | /** $sameType with an amount subtracted. 55 | * 56 | * @throws DateTimeException - if the unit cannot be subtracted 57 | * @throws UnsupportedTemporalTypeException - if the unit is not supported 58 | * @throws ArithmeticException - if numeric overflow occurs 59 | */ 60 | def -(amount: Long, unit: TemporalUnit): underlying.type = underlying.minus(amount, unit) 61 | 62 | /** Obtains an adjusted object of the same type as this object with the adjustment made. 63 | * 64 | * @throws DateTimeException - if unable to make the adjustment 65 | * @throws ArithmeticException - if numeric overflow occurs 66 | */ 67 | def ~=(adjuster: TemporalAdjuster): underlying.type = underlying.`with`(adjuster) 68 | 69 | /** Obtains an adjusted object of the same type as this object with the adjustment made. 70 | * 71 | * @throws DateTimeException - if the field cannot be set 72 | * @throws UnsupportedTemporalTypeException - if the field is not supported 73 | * @throws ArithmeticException - if numeric overflow occurs 74 | */ 75 | def ~=(field: TemporalField, fieldValue: Long): underlying.type = underlying.`with`(field, fieldValue) 76 | 77 | /** Calculates the amount of time until this temporal in terms of the specified unit. 78 | * 79 | * @throws DateTimeException - if the amount cannot be calculated, or the end temporal cannot be converted 80 | * to the same type as this temporal. 81 | * @throws UnsupportedTemporalTypeException - if the unit is not supported. 82 | * @throws ArithmeticException - if numeric overflow occurs. 83 | */ 84 | def from(begin: Temporal, inUnits: TemporalUnit): Long = begin.until(underlying, inUnits) 85 | 86 | private implicit def t(t: Temporal): underlying.type = t.asInstanceOf[underlying.type] 87 | 88 | } 89 | 90 | trait ToTemporalOps extends Any { 91 | 92 | implicit final def toTemporalOpsFromTemporal(v: Temporal): TemporalOps = new TemporalOps(v) 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalQueryOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.DateTimeException 22 | import java.time.temporal.{TemporalAccessor, TemporalQuery} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches instances of [[TemporalQuery! TemporalQuery]] with additional methods. */ 27 | final case class TemporalQueryOps[A](underlying: TemporalQuery[A]) extends AnyVal { 28 | 29 | /** Queries the specified [[TemporalAccessor]] using this query strategy. 30 | * 31 | * @throws DateTimeException if unable to query. 32 | * @throws ArithmeticException if numeric overflow occurs. 33 | */ 34 | def |>(temporal: TemporalAccessor): A = temporal.query(underlying) 35 | 36 | /** Queries the specified [[TemporalAccessor]] using this query strategy. 37 | * 38 | * @throws DateTimeException if unable to query. 39 | * @throws ArithmeticException if numeric overflow occurs. 40 | */ 41 | def ▹(temporal: TemporalAccessor): A = temporal.query(underlying) 42 | } 43 | 44 | trait ToTemporalQueryOps extends Any { 45 | 46 | implicit final def toTemporalQueryOpsFromTemporalQuery[A](v: TemporalQuery[A]): TemporalQueryOps[A] = new TemporalQueryOps(v) 47 | 48 | implicit final def toTemporalQueryOpsFromFunction1[A](f: (TemporalAccessor) => A): TemporalQueryOps[A] = 49 | new TemporalQueryOps(new TemporalQuery[A] { 50 | override def queryFrom(temporalAccessor: TemporalAccessor): A = f(temporalAccessor) 51 | }) 52 | } 53 | 54 | trait ToTemporalQuery extends Any { 55 | 56 | implicit final def toTemporalQueryFromFunction1[A](f: (TemporalAccessor) => A): TemporalQuery[A] = new TemporalQuery[A] { 57 | override def queryFrom(temporalAccessor: TemporalAccessor): A = f(temporalAccessor) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/TemporalUnitOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.DateTimeException 22 | import java.time.temporal.{Temporal, TemporalUnit} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches [[TemporalUnit]] with additional methods. */ 27 | final case class TemporalUnitOps(underlying: TemporalUnit) { 28 | 29 | /** Returns a copy of the specified temporal object with the specified amount of this unit added. 30 | * 31 | * @throws DateTimeException - if the amount cannot be added. 32 | */ 33 | def <<+[A <: Temporal](temporal: A, amount: Long): A = underlying.addTo(temporal, amount) 34 | } 35 | 36 | trait ToTemporalUnitOps extends Any { 37 | implicit final def toTemporalUnitOpsFromTemporalUnit(f: TemporalUnit): TemporalUnitOps = new TemporalUnitOps(f) 38 | } 39 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/ToAllOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | 22 | abstract class ToAllOps extends ToIntOps 23 | with ToLongOps 24 | with ToMonthDayOps 25 | with ToMonthOps 26 | with ToTemporalAccessorOps 27 | with ToTemporalAdjusterOps 28 | with ToTemporalAmountOps 29 | with ToDurationOps 30 | with ToPeriodOps 31 | with ToTemporalOps 32 | with ToTemporalQueryOps 33 | with ToTemporalUnitOps 34 | with ToYearMonthOps 35 | with ToYearOps 36 | with ToChronoLocalDateOps 37 | with ToChronoLocalDateTimeOps 38 | with ToChronoZonedDateTimeOps 39 | with ToStringOps 40 | 41 | trait ToAllStd extends Any with ToTemporalQuery 42 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/YearMonthOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatter 22 | import java.time.{DateTimeException, LocalDate, YearMonth} 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches [[YearMonth]] instances with additional methods. */ 27 | final case class YearMonthOps(underlying: YearMonth) extends AnyVal { 28 | 29 | /** Obtains a [[java.time.YearMonth]] with the specified number of months added. 30 | * 31 | * @throws DateTimeException if the result exceeds the supported range. 32 | */ 33 | def +(months: Int): YearMonth = underlying.plusMonths(months) 34 | 35 | /** Obtains a [[YearMonth]] with the specified number of months subtracted. 36 | * 37 | * @throws DateTimeException if the result exceeds the supported range. 38 | */ 39 | def -(months: Int): YearMonth = underlying.minusMonths(months) 40 | 41 | /** Returns `true` if this year-month is before the specified one. */ 42 | def <(other: YearMonth): Boolean = underlying.isBefore(other) 43 | 44 | /** Returns `true` if this year-month is equal to or before the specified one. */ 45 | def <=(other: YearMonth): Boolean = underlying.equals(other) || underlying.isBefore(other) 46 | 47 | /** Returns `true` if this year-month is after the specified one. */ 48 | def >(other: YearMonth): Boolean = underlying.isAfter(other) 49 | 50 | /** Returns `true` if this year-month is equal to or after the specified one. */ 51 | def >=(other: YearMonth): Boolean = underlying.equals(other) || underlying.isAfter(other) 52 | 53 | /** Obtains a [[java.time.LocalDate]] by combining this year-month with the specified day. 54 | * 55 | * @throws DateTimeException if the day is invalid for the year-month 56 | */ 57 | def /(day: Int): LocalDate = underlying.atDay(day) 58 | 59 | /** Formats this year-month using the specified formatter. 60 | * 61 | * @throws DateTimeException - if an error occurs during printing 62 | */ 63 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 64 | 65 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 66 | 67 | } 68 | 69 | trait ToYearMonthOps extends Any { 70 | implicit final def toYearMonthOpsFromYearMonth(f: YearMonth): YearMonthOps = new YearMonthOps(f) 71 | } 72 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/impl/YearOps.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time._ 22 | import java.time.format.DateTimeFormatter 23 | 24 | import scala.language.implicitConversions 25 | 26 | /** Enriches [[Year]] instances with additional methods. */ 27 | final case class YearOps(underlying: Year) extends AnyVal { 28 | 29 | /** Obtains a year with the specified number of years added. */ 30 | def +(years: Int): Year = underlying.plusYears(years) 31 | 32 | /** Obtains a year with the specified number of years subtracted. */ 33 | def -(years: Int): Year = underlying.minusYears(years) 34 | 35 | /** Returns `true` if this year is before the specified one. */ 36 | def <(other: Year): Boolean = underlying.isBefore(other) 37 | 38 | /** Returns `true` if this year is equal to or before the specified one. */ 39 | def <=(other: Year): Boolean = underlying.equals(other) || underlying.isBefore(other) 40 | 41 | /** Returns `true` if this year is after the specified one. */ 42 | def >(other: Year): Boolean = underlying.isAfter(other) 43 | 44 | /** Returns `true` if this year is equal to or after the specified one. */ 45 | def >=(other: Year): Boolean = underlying.equals(other) || underlying.isAfter(other) 46 | 47 | /** Obtains a [[YearMonth]] by combining this year with the specified [[java.time.Month]]. */ 48 | def /(month: Month): YearMonth = underlying.atMonth(month) 49 | 50 | /** Obtains a [[YearMonth]] by combining this year with the specified month, from 1 (January) to 12 (December). 51 | * 52 | * @throws DateTimeException if the month is invalid. 53 | */ 54 | def /(month: Int): YearMonth = underlying.atMonth(month) 55 | 56 | /** Obtains a [[LocalDate]] by combining this year with the specified [[MonthDay]]. */ 57 | def /(monthDay: MonthDay): LocalDate = underlying.atMonthDay(monthDay) 58 | 59 | /** Formats this year using the specified formatter. 60 | * 61 | * @throws DateTimeException - if an error occurs during printing 62 | */ 63 | def |>(formatter: DateTimeFormatter): String = underlying.format(formatter) 64 | 65 | def ▹(formatter: DateTimeFormatter): String = underlying.format(formatter) 66 | 67 | 68 | } 69 | 70 | trait ToYearOps extends Any { 71 | implicit final def toYearOpsFromYear(f: Year): YearOps = new YearOps(f) 72 | } 73 | -------------------------------------------------------------------------------- /src/main/scala/scalatime/package.scala: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | /** Provides an API for convenient use of 'java.time' classes. 20 | * 21 | * @example 22 | * {{{ 23 | * import java.time._ 24 | * import scalatime._ // NOTE: Package name was changed from codes.reactive.scalatime => scalatime 25 | * // for versions 0.5.x and newer. If still using 0.4.x, use codes.reactive.scalatime 26 | * 27 | * // Obtain a Duration instance from a Long 28 | * val duration = 10L minutes 29 | * 30 | * val otherDuration = 1L minute 31 | * 32 | * // Obtain a Period instance from an Int 33 | * val period = 2 weeks 34 | * 35 | * // Obtains a LocalDate instance 36 | * val localDate = LocalDate.of(2014, 6, 7) 37 | * 38 | * // Obtain a default TemporalQuery for precision 39 | * val query = temporal.TemporalQueries.precision 40 | * 41 | * // Obtain a Duration instance from a sum of Durations 42 | * duration + otherDuration 43 | * 44 | * // Add a TemporalAmount to a Temporal 45 | * period <<+ localDate 46 | * 47 | * // Add a TemporalAmount to a Temporal 48 | * localDate + period 49 | * 50 | * // Subtract a TemporalAmount from a Temporal 51 | * localDate - period 52 | * 53 | * // Query a specified Temporal 54 | * val result = query |> localDate 55 | * }}} 56 | * 57 | */ 58 | package object scalatime extends impl.ToAllOps with impl.ToAllStd 59 | -------------------------------------------------------------------------------- /src/test/scala/codes/reactive/CompatFunSuite.scala: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package codes.reactive 20 | 21 | import java.time.DateTimeException 22 | 23 | import org.scalatest.{FunSuite, Matchers} 24 | 25 | import scala.language.postfixOps 26 | import scala.util.{Success, Try} 27 | 28 | class CompatFunSuite extends FunSuite with Matchers { 29 | 30 | test("Users of deprecated package should still have functionality using old import") { 31 | import java.time._ 32 | import codes.reactive.scalatime._ 33 | 34 | val duration = 1L day 35 | 36 | val period = 1 day 37 | 38 | val otherDuration = 1 hour 39 | 40 | val durationSum = duration + otherDuration 41 | 42 | duration.isInstanceOf[Duration] shouldBe true 43 | period.isInstanceOf[Period] shouldBe true 44 | durationSum shouldEqual Duration.ofHours(25) 45 | 46 | } 47 | 48 | test("Users of Catcher from deprecated package should still have functionality using old import") { 49 | import codes.reactive.scalatime.control._ 50 | Try(throw new DateTimeException("test")).recover(Catcher.all(_ => true)) shouldBe Success(true) } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/control/CatchersSuite.scala: -------------------------------------------------------------------------------- 1 | /** **************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | * *****************************************************************/ 18 | 19 | package scalatime 20 | package control 21 | 22 | import java.time.DateTimeException 23 | import java.time.format.DateTimeParseException 24 | import java.time.temporal.UnsupportedTemporalTypeException 25 | import java.time.zone.ZoneRulesException 26 | 27 | import org.scalatest.{FunSuite, Matchers} 28 | 29 | import scala.util.{Failure, Success, Try} 30 | 31 | 32 | class CatchersSuite extends FunSuite with Matchers { 33 | 34 | case class Exceptions(base: Throwable = new DateTimeException("test"), 35 | temporalType: Throwable = new UnsupportedTemporalTypeException("test"), 36 | zoneRules: Throwable = new ZoneRulesException("test"), 37 | parse: Throwable = new DateTimeParseException("test", "", 0)) 38 | 39 | 40 | test("Catcher instances do not match unrelated Throwables") { 41 | val es = Exceptions() 42 | (Try(throw new RuntimeException).recover(Catcher.all(_ ⇒ true)) orElse Success(false)) shouldBe Success(false) 43 | (Try(throw new RuntimeException).recover(Catcher.dateTimeParseException(_ ⇒ true)) orElse Success(false)) shouldBe Success(false) 44 | (Try(throw new RuntimeException).recover(Catcher.unsupportedTemporalType(_ ⇒ true)) orElse Success(false)) shouldBe Success(false) 45 | (Try(throw new RuntimeException).recover(Catcher.zoneRules(_ ⇒ true)) orElse Success(false)) shouldBe Success(false) 46 | } 47 | 48 | test("Catcher.all matches all 'DateTimeException' instances") { 49 | val es = Exceptions() 50 | Try(throw es.base).recover(Catcher.all(_ ⇒ true)) shouldBe Success(true) 51 | Try(throw es.zoneRules).recover(Catcher.all(_ ⇒ true)) shouldBe Success(true) 52 | } 53 | 54 | test("Catcher.dateTimeParseException matches 'DateTimeParseException' instances") { 55 | val es = Exceptions() 56 | Try(throw es.parse).recover(Catcher.dateTimeParseException(_ ⇒ true)) shouldBe Success(true) 57 | Try(throw es.zoneRules).recover(Catcher.dateTimeParseException(_ ⇒ true)) shouldBe Failure(es.zoneRules) 58 | } 59 | 60 | test("Catcher.unsupportedTemporalType matches 'UnsupportedTemporalTypeException' instances") { 61 | val es = Exceptions() 62 | Try(throw es.temporalType).recover(Catcher.unsupportedTemporalType(_ ⇒ true)) shouldBe Success(true) 63 | Try(throw es.zoneRules).recover(Catcher.unsupportedTemporalType(_ ⇒ true)) shouldBe Failure(es.zoneRules) 64 | } 65 | 66 | test("Catcher.zoneRules matches 'ZoneRulesException' instances") { 67 | val es = Exceptions() 68 | Try(throw es.zoneRules).recover(Catcher.zoneRules(_ ⇒ true)) shouldBe Success(true) 69 | Try(throw es.temporalType).recover(Catcher.zoneRules(_ ⇒ true)) shouldBe Failure(es.temporalType) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/ChronoLocalDateOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatter._ 22 | import java.time.{LocalDate, LocalTime} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class ChronoLocalDateOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | test("`%%` combines a ChronoLocalDate with a LocalTime") { ld => 30 | val lt = LocalTime.now() 31 | ld %% lt shouldBe ld.underlying.atTime(lt) 32 | } 33 | 34 | test("`>>` formats a ChronoLocalDate according to the specified formatter") { ld => 35 | ld |> ISO_LOCAL_DATE shouldBe ld.underlying.format(ISO_LOCAL_DATE) 36 | } 37 | 38 | test("`▹` formats a ChronoLocalDate according to the specified formatter") { ld => 39 | ld ▹ ISO_LOCAL_DATE shouldBe ld.underlying.format(ISO_LOCAL_DATE) 40 | } 41 | 42 | override type FixtureParam = ChronoLocalDateOps 43 | 44 | override protected def withFixture(test: OneArgTest): Outcome = 45 | withFixture(test.toNoArgTest(new ChronoLocalDateOps(LocalDate.now()))) 46 | } 47 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/ChronoLocalDateTimeOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatter._ 22 | import java.time.{LocalDate, LocalDateTime, ZoneId, ZoneOffset} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class ChronoLocalDateTimeOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | test("`%%` combines a ChronoLocalDateTime with a time zone") { (ldt: ChronoLocalDateTimeOps[LocalDate]) => 30 | ldt %% ZoneId.of("Z") shouldBe ldt.underlying.atZone(ZoneOffset.UTC) 31 | } 32 | 33 | test("`±` combines a ChronoLocalDateTime with a time zone") { ldt => 34 | ldt ± ZoneId.of("Z") shouldBe ldt.underlying.atZone(ZoneOffset.UTC) 35 | } 36 | 37 | test("`>>` formats a ChronoLocalDateTime according to the specified formatter") { ldt => 38 | ldt |> ISO_LOCAL_DATE shouldBe ldt.underlying.format(ISO_LOCAL_DATE) 39 | } 40 | 41 | test("`▹` formats a ChronoLocalDateTime according to the specified formatter") { ldt => 42 | ldt ▹ ISO_LOCAL_DATE shouldBe ldt.underlying.format(ISO_LOCAL_DATE) 43 | } 44 | 45 | override type FixtureParam = ChronoLocalDateTimeOps[LocalDate] 46 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new ChronoLocalDateTimeOps(LocalDateTime.now()))) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/ChronoZonedDateTimeOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatter._ 22 | import java.time.{LocalDate, ZoneId, ZonedDateTime} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class ChronoZonedDateTimeOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | override type FixtureParam = ChronoZonedDateTimeOps[LocalDate] 30 | 31 | override protected def withFixture(test: OneArgTest): Outcome = 32 | withFixture(test.toNoArgTest(new ChronoZonedDateTimeOps(ZonedDateTime.of(2015, 4, 25, 23, 50, 0, 0, ZoneId.of("+3"))))) 33 | 34 | test("`|>` formats the boxed ChronoZonedDateTime according to the specified formatter") { 35 | _ |> ISO_DATE shouldBe "2015-04-25+03:00" 36 | } 37 | 38 | test("`▹` formats the boxed ChronoZonedDateTime according to the specified formatter") { 39 | _ ▹ ISO_DATE shouldBe "2015-04-25+03:00" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/IntOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.{Month, Period, YearMonth} 22 | 23 | import org.scalatest.{Matchers, Outcome, fixture} 24 | 25 | 26 | class IntOpsSuite extends fixture.FunSuite with Matchers { 27 | 28 | test("`day` obtains a period equal to the specified number of days")(_.day shouldBe Period.ofDays(10)) 29 | 30 | test("`days` obtains a period equal to the specified number of days")(_.days shouldBe Period.ofDays(10)) 31 | 32 | test("`week` obtains a period equal to the specified number of weeks")(_.week shouldBe Period.ofWeeks(10)) 33 | 34 | test("`weeks` obtains a period equal to the specified number of weeks")(_.weeks shouldBe Period.ofWeeks(10)) 35 | 36 | test("`month` obtains a period equal to the specified number of months")(_.month shouldBe Period.ofMonths(10)) 37 | 38 | test("`months` obtains a period equal to the specified number of months")(_.months shouldBe Period.ofMonths(10)) 39 | 40 | test("`year` obtains a period equal to the specified number of years")(_.year shouldBe Period.ofYears(10)) 41 | 42 | test("`years` obtains a period equal to the specified number of years")(_.years shouldBe Period.ofYears(10)) 43 | 44 | override type FixtureParam = IntOps 45 | 46 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new IntOps(10))) 47 | } 48 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/LongOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.Duration 22 | 23 | import org.scalatest.{Matchers, Outcome, fixture} 24 | 25 | 26 | class LongOpsSuite extends fixture.FunSuite with Matchers { 27 | 28 | test("`nano` obtains a Duration equal to the specified number of nanoseconds")(_.nano shouldBe Duration.ofNanos(10)) 29 | 30 | test("`nanos` obtains a Duration equal to the specified number of nanoseconds")(_.nanos shouldBe Duration.ofNanos(10)) 31 | 32 | test("`milli` obtains a Duration equal to the specified number of milliseconds")(_.milli shouldBe Duration.ofMillis(10)) 33 | 34 | test("`millis` obtains a Duration equal to the specified number of milliseconds")(_.millis shouldBe Duration.ofMillis(10)) 35 | 36 | test("`second` obtains a Duration equal to the specified number of seconds")(_.second shouldBe Duration.ofSeconds(10)) 37 | 38 | test("`seconds` obtains a Duration equal to the specified number of seconds")(_.seconds shouldBe Duration.ofSeconds(10)) 39 | 40 | test("`minute` obtains a Duration equal to the specified number of minutes")(_.minute shouldBe Duration.ofMinutes(10)) 41 | 42 | test("`minutes` obtains a Duration equal to the specified number of minutes")(_.minutes shouldBe Duration.ofMinutes(10)) 43 | 44 | test("`hour` obtains a Duration equal to the specified number of hours")(_.hour shouldBe Duration.ofHours(10)) 45 | 46 | test("`hours` obtains a Duration equal to the specified number of hours")(_.hours shouldBe Duration.ofHours(10)) 47 | 48 | test("`day` obtains a Duration equal to the specified number of days")(_.day shouldBe Duration.ofDays(10)) 49 | 50 | test("`days` obtains a Duration equal to the specified number of days")(_.days shouldBe Duration.ofDays(10)) 51 | 52 | 53 | override type FixtureParam = LongOps 54 | 55 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new LongOps(10L))) 56 | } 57 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/MonthDayOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.DateTimeFormatterBuilder 22 | import java.time.temporal.ChronoField._ 23 | import java.time.{Month, MonthDay} 24 | 25 | import org.scalatest.{Matchers, Outcome, fixture} 26 | 27 | 28 | class MonthDayOpsSuite extends fixture.FunSuite with Matchers { 29 | 30 | test("`<` returns true if underlying value is before the specified MonthDay")(_.<(MonthDay.of(11, 11)) shouldBe true) 31 | 32 | test("`<=` returns true if underlying value is before or equal to the specified MonthDay")(_.<=(MonthDay.of(10, 11)) shouldBe true) 33 | 34 | test("`>` returns true if underlying value is after the specified MonthDay")(_.>(MonthDay.of(1, 1)) shouldBe true) 35 | 36 | test("`>=` returns true if underlying value is after or equal to the specified MonthDay")(_.>=(MonthDay.of(10, 11)) shouldBe true) 37 | 38 | test("`~=(month: Month)` obtains a MonthDay from the underlying value with the specified Month")(_.~=(Month.JANUARY) shouldBe MonthDay.of(1, 11)) 39 | 40 | test("`~=(day: Int)` obtains a MonthDay from the underlying value with the specified day")(_.~=(1) shouldBe MonthDay.of(10, 1)) 41 | 42 | test("`~=(month: Option[Month], day: Option[Int])` obtains a MonthDay from the underlying value with the specified month or day")(_.~=(Some(Month.JANUARY), Some(1)) shouldBe MonthDay.of(1, 1)) 43 | 44 | test("`|>` formats the underlying value with the specified formatter.")(_.|>(formatter) shouldBe "--10-11") 45 | 46 | test("`▹` formats the underlying value with the specified formatter.")(_.▹(formatter) shouldBe "--10-11") 47 | 48 | 49 | override type FixtureParam = MonthDayOps 50 | 51 | private def formatter = new DateTimeFormatterBuilder() 52 | .appendLiteral("--") 53 | .appendValue(MONTH_OF_YEAR, 2) 54 | .appendLiteral('-') 55 | .appendValue(DAY_OF_MONTH, 2) 56 | .toFormatter 57 | 58 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new MonthDayOps(MonthDay.of(10, 11)))) 59 | } 60 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/MonthOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.{LocalDate, Month, MonthDay} 22 | 23 | import org.scalatest.{Matchers, Outcome, fixture} 24 | 25 | 26 | class MonthOpsSuite extends fixture.FunSuite with Matchers { 27 | 28 | test("`+` obtains a Month after the underlying value by the specified number of months")(_ + 13 shouldBe Month.SEPTEMBER) 29 | 30 | test("`-` obtains a Month before the underlying value by the specified number of months")(_ - 13 shouldBe Month.JULY) 31 | 32 | test("`/` obtains a MonthDay by combining the underlying value with the specified day")(_ / 1 shouldBe MonthDay.of(8, 1)) 33 | 34 | test("`=~` adjusts the specified Temporal to have this month")(_ =~ LocalDate.of(2016, 4, 4) shouldBe LocalDate.of(2016, 8, 4)) 35 | 36 | override type FixtureParam = MonthOps 37 | 38 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new MonthOps(Month.AUGUST))) 39 | } 40 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/StringOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.LocalDate 22 | import java.time.format.DateTimeFormatter.ISO_LOCAL_DATE 23 | import java.time.temporal.TemporalQueries.localDate 24 | 25 | import org.scalatest.{Matchers, Outcome, fixture} 26 | 27 | 28 | class StringOpsSuite extends fixture.FunSuite with Matchers { 29 | 30 | test("`|>(formatter: DateTimeFormatter)` parses the underlying value according to the specified DateTimeFormatter to produce a Temporal") { v ⇒ 31 | localDate.queryFrom(v |> ISO_LOCAL_DATE) shouldEqual LocalDate.of(2016, 4, 4) 32 | } 33 | 34 | test("`|>(formatter: DateTimeFormatter)` parses the underlying value according to the specified DateTimeFormatter to produce a Temporal defined by the specified TemporalQuery") { v ⇒ 35 | v |> (ISO_LOCAL_DATE, localDate) shouldEqual LocalDate.of(2016, 4, 4) 36 | } 37 | 38 | test("`▹(formatter: DateTimeFormatter)` parses the underlying value according to the specified DateTimeFormatter to produce a Temporal") { v ⇒ 39 | localDate.queryFrom(v ▹ ISO_LOCAL_DATE) shouldEqual LocalDate.of(2016, 4, 4) 40 | } 41 | 42 | test("`▹(formatter: DateTimeFormatter)` parses the underlying value according to the specified DateTimeFormatter to produce a Temporal defined by the specified TemporalQuery") { v ⇒ 43 | v ▹ (ISO_LOCAL_DATE, localDate) shouldEqual LocalDate.of(2016, 4, 4) 44 | } 45 | override type FixtureParam = StringOps 46 | 47 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new StringOps("2016-04-04"))) 48 | } 49 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalAccessorOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.LocalDate 22 | import java.time.temporal.{ChronoField, ChronoUnit, TemporalQueries} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalAccessorOpsSuite extends fixture.FunSuite with Matchers { 28 | override type FixtureParam = TemporalAccessorOps 29 | 30 | override protected def withFixture(test: OneArgTest): Outcome = { 31 | val accessor = LocalDate.of(2015, 4, 25) 32 | withFixture(test.toNoArgTest(new FixtureParam(accessor))) 33 | } 34 | 35 | test("`|>` queries the boxed object using the specified TemporalQuery strategy object.") { 36 | _ |> TemporalQueries.precision shouldBe ChronoUnit.DAYS 37 | } 38 | 39 | test("`▹` queries the boxed object using the specified TemporalQuery strategy object.") { 40 | _ |> TemporalQueries.precision shouldBe ChronoUnit.DAYS 41 | } 42 | 43 | test("`#|>` queries the boxed object to obtains the value of the specified field as a `Long`") { 44 | _ #|> ChronoField.DAY_OF_MONTH shouldBe 25L 45 | } 46 | 47 | test("`#▹` queries the boxed object to obtains the value of the specified field as a `Long`") { 48 | _ #▹ ChronoField.DAY_OF_MONTH shouldBe 25L 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalAdjusterOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.LocalDate 22 | import java.time.temporal.TemporalAdjusters 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalAdjusterOpsSuite extends fixture.FunSuite with Matchers { 28 | override type FixtureParam = TemporalAdjusterOps 29 | 30 | override protected def withFixture(test: OneArgTest): Outcome = { 31 | val adj = TemporalAdjusters.firstDayOfMonth() 32 | withFixture(test.toNoArgTest(new FixtureParam(adj))) 33 | } 34 | 35 | test("`<<=` applies the boxed TemporalAdjuster to the specified Temporal") { a ⇒ 36 | (a <<= LocalDate.of(2015, 4, 25)) shouldBe LocalDate.of(2015, 4, 1) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalAmountOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.temporal.ChronoUnit 22 | import java.time.{Duration, LocalTime, Period} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalAmountOpsSuite extends fixture.FunSuite with Matchers { 28 | override type FixtureParam = (TemporalAmountOps) 29 | 30 | override protected def withFixture(test: OneArgTest): Outcome = { 31 | val amt = Duration.ofMinutes(60) 32 | withFixture(test.toNoArgTest(TemporalAmountOps(amt))) 33 | } 34 | 35 | test("`<<+` adds the boxed amount to the specified Temporal") { 36 | _ <<+ LocalTime.of(14, 50) shouldBe LocalTime.of(15, 50) 37 | } 38 | 39 | test("`<<+` subtracts the boxed amount from the specified Temporal") { 40 | _ <<- LocalTime.of(14, 50) shouldBe LocalTime.of(13, 50) 41 | } 42 | } 43 | 44 | 45 | class DurationOpsSuite extends fixture.FunSuite with Matchers { 46 | override type FixtureParam = DurationOps 47 | 48 | override protected def withFixture(test: OneArgTest): Outcome = { 49 | val dur = Duration.ofMinutes(60) 50 | withFixture(test.toNoArgTest(DurationOps(dur))) 51 | } 52 | 53 | test("`*` obtains a copy of the boxed Duration multiplied by the scalar") { 54 | _ * 2 shouldBe Duration.ofMinutes(120) 55 | } 56 | 57 | test("`+` obtains a copy of the boxed Duration with the specified Duration added") { 58 | _ + Duration.ofMinutes(60) shouldBe Duration.ofMinutes(120) 59 | } 60 | 61 | test("`+` obtains a copy of the boxed Duration with a duration added in terms of the specified unit") { 62 | _ +(60, ChronoUnit.MINUTES) shouldBe Duration.ofMinutes(120) 63 | } 64 | 65 | test("`-` obtains a copy of the boxed Duration with the specified Duration subtracted") { 66 | _ - Duration.ofMinutes(60) shouldBe Duration.ofMinutes(0) 67 | } 68 | 69 | test("`-` obtains a copy of the boxed Duration with a duration subtracted in terms of the specified unit") { 70 | _ -(60, ChronoUnit.MINUTES) shouldBe Duration.ofMinutes(0) 71 | } 72 | 73 | test("`/` obtains a copy of the boxed Duration divided by the divisor") { 74 | _ / 2 shouldBe Duration.ofMinutes(30) 75 | } 76 | 77 | test("`unary_!` negates the boxed Duration") { 78 | !_ shouldBe Duration.ofMinutes(-60) 79 | } 80 | 81 | test("`asConcurrentDuration` obtains the Duration as a `concurrent.duration.Duration`") { 82 | _.asConcurrentDuration shouldBe concurrent.duration.Duration.fromNanos(3600000000000L) 83 | } 84 | } 85 | 86 | 87 | class PeriodOpsSuite extends fixture.FunSuite with Matchers { 88 | override type FixtureParam = PeriodOps 89 | 90 | override protected def withFixture(test: OneArgTest): Outcome = { 91 | val period = Period.ofDays(60) 92 | withFixture(test.toNoArgTest(new FixtureParam(period))) 93 | } 94 | 95 | test("`*` obtains a copy of the boxed Period multiplied by the scalar") { 96 | _ * 2 shouldBe Period.ofDays(120) 97 | } 98 | 99 | test("`+` obtains a copy of the boxed Period with the specified TemporalAmount added") { 100 | _ + Period.ofDays(60) shouldBe Period.ofDays(120) 101 | } 102 | 103 | test("`+` obtains a copy of the boxed Period with the specified TemporalAmount subtracted") { 104 | _ - Period.ofDays(60) shouldBe Period.ofDays(0) 105 | } 106 | 107 | test("`unary_!` negates the boxed Period") { 108 | !_ shouldBe Period.ofDays(-60) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.temporal.{ChronoField, ChronoUnit, TemporalAdjusters} 22 | import java.time.{Period, ZoneId, ZonedDateTime} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | 30 | override type FixtureParam = (TemporalOps, ZonedDateTime) 31 | 32 | override protected def withFixture(test: OneArgTest): Outcome = { 33 | val temporal = ZonedDateTime.of(2015, 5, 25, 7, 6, 30, 0, ZoneId.of("Z")) 34 | withFixture(test.toNoArgTest(new FixtureParam(new TemporalOps(temporal), temporal))) 35 | } 36 | 37 | 38 | test("`+` obtains an instance of the same type as the boxed type with the TemporalAmount added") { 39 | _._1 + Period.ofDays(1) shouldBe ZonedDateTime.of(2015, 5, 26, 7, 6, 30, 0, ZoneId.of("Z")) 40 | } 41 | 42 | test("`+` obtains an instance of the same type as the boxed type with the amount of TemporalUnits added") { 43 | _._1 +(1, ChronoUnit.DAYS) shouldBe ZonedDateTime.of(2015, 5, 26, 7, 6, 30, 0, ZoneId.of("Z")) 44 | } 45 | 46 | test("`-` obtains an instance of the same type as the boxed type with the TemporalAmount subtracted") { 47 | _._1 - Period.ofDays(1) shouldBe ZonedDateTime.of(2015, 5, 24, 7, 6, 30, 0, ZoneId.of("Z")) 48 | } 49 | 50 | test("`-` obtains an instance of the same type as the boxed type with the amount of TemporalUnits subtracted") { 51 | _._1 -(1, ChronoUnit.DAYS) shouldBe ZonedDateTime.of(2015, 5, 24, 7, 6, 30, 0, ZoneId.of("Z")) 52 | } 53 | 54 | test("`=~` obtains an instance of the same type as the boxed type with a TemporalAdjuster applied.") { t ⇒ 55 | (t._1 ~= TemporalAdjusters.firstDayOfMonth()) shouldBe ZonedDateTime.of(2015, 5, 1, 7, 6, 30, 0, ZoneId.of("Z")) 56 | } 57 | 58 | test("`=~` obtains an instance of the same type as the boxed type with an adjustment applied.") { t ⇒ 59 | (t._1 ~=(ChronoField.DAY_OF_MONTH, 1)) shouldBe ZonedDateTime.of(2015, 5, 1, 7, 6, 30, 0, ZoneId.of("Z")) 60 | } 61 | 62 | test("`from` obtains the amount of time until the boxed Temporal from the specified Temporal in terms of the specified units.") { t ⇒ 63 | t._1 from(t._2.minusDays(1), ChronoUnit.DAYS) shouldBe 1L 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalQueryOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.temporal.TemporalQueries 22 | import java.time.{LocalDate, LocalDateTime} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalQueryOpsSuite extends fixture.FunSuite with Matchers { 28 | override type FixtureParam = TemporalQueryOps[_] 29 | 30 | override protected def withFixture(test: OneArgTest): Outcome = { 31 | val query = TemporalQueries.localDate 32 | withFixture(test.toNoArgTest(new TemporalQueryOps(query))) 33 | } 34 | 35 | 36 | test("`▹` queries the specified TemporalAccessor using the boxed TemporalQuery.") { 37 | _ ▹ LocalDateTime.of(2015, 4, 25, 22, 50) shouldBe LocalDate.of(2015, 4, 25) 38 | } 39 | 40 | test("`|>` queries the specified TemporalAccessor using the boxed TemporalQuery.") { 41 | _ |> LocalDateTime.of(2015, 4, 25, 22, 50) shouldBe LocalDate.of(2015, 4, 25) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/TemporalUnitOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.LocalDate 22 | import java.time.temporal.ChronoUnit 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class TemporalUnitOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | test("`<<+` adjusts the specified temporal with the specified amount of the underlying unit")( 30 | _ <<+ (LocalDate.of(2016, 4, 4), 2) shouldBe LocalDate.of(2016, 4, 6) 31 | ) 32 | 33 | override type FixtureParam = TemporalUnitOps 34 | 35 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new TemporalUnitOps(ChronoUnit.DAYS))) 36 | } 37 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/ToOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time._ 22 | import java.time.temporal.{ChronoUnit, TemporalAccessor, TemporalQueries, TemporalQuery} 23 | 24 | import org.scalatest.{Matchers, Outcome, fixture} 25 | 26 | 27 | class ToAllOpsSuite extends fixture.FunSuite with Matchers { 28 | 29 | test("implicit conversion to ChronoLocalDateOps from ChronoLocalDate") { f ⇒ 30 | import f._ 31 | val v: ChronoLocalDateOps = LocalDate.MIN 32 | v.isInstanceOf[ChronoLocalDateOps] shouldBe true 33 | } 34 | 35 | test("implicit conversion to ChronoLocalDateTimeOps from ChronoLocalDateTime") { f ⇒ 36 | import f._ 37 | val v: ChronoLocalDateTimeOps[_] = LocalDateTime.MIN 38 | v.isInstanceOf[ChronoLocalDateTimeOps[_]] shouldBe true 39 | } 40 | 41 | test("implicit conversion to ChronoZonedDateTimeOps from ChronoZonedDateTime") { f ⇒ 42 | import f._ 43 | val v: ChronoZonedDateTimeOps[_] = ZonedDateTime.now() 44 | v.isInstanceOf[ChronoZonedDateTimeOps[_]] shouldBe true 45 | } 46 | 47 | test("implicit conversion to IntOps from Int") { f ⇒ 48 | import f._ 49 | val v: IntOps = 1 50 | v.isInstanceOf[IntOps] shouldBe true 51 | } 52 | 53 | test("implicit conversion to LongOps from Long") { f ⇒ 54 | import f._ 55 | val v: LongOps = 1L 56 | v.isInstanceOf[LongOps] shouldBe true 57 | } 58 | 59 | test("implicit conversion to MonthDayOps from MonthDay") { f ⇒ 60 | import f._ 61 | val v: MonthDayOps = MonthDay.now() 62 | v.isInstanceOf[MonthDayOps] shouldBe true 63 | } 64 | 65 | test("implicit conversion to MonthOps from Month") { f ⇒ 66 | import f._ 67 | val v: MonthOps = Month.JANUARY 68 | v.isInstanceOf[MonthOps] shouldBe true 69 | } 70 | 71 | test("implicit conversion to StringOps from String") { f ⇒ 72 | import f._ 73 | val v: StringOps = "" 74 | v.isInstanceOf[StringOps] shouldBe true 75 | } 76 | 77 | test("implicit conversion to TemporalAccessorOps from TemporalAccessor") { f ⇒ 78 | import f._ 79 | val v: TemporalAccessorOps = LocalDate.MIN 80 | v.isInstanceOf[TemporalAccessorOps] shouldBe true 81 | } 82 | 83 | test("implicit conversion to TemporalAdjusterOps from TemporalAdjuster") { f ⇒ 84 | import f._ 85 | val v: TemporalAdjusterOps = MonthDay.now() 86 | v.isInstanceOf[TemporalAdjusterOps] shouldBe true 87 | } 88 | 89 | test("implicit conversion to DurationOps from Duration") { f ⇒ 90 | import f._ 91 | val v: DurationOps = Duration.ZERO 92 | v.isInstanceOf[DurationOps] shouldBe true 93 | } 94 | 95 | test("implicit conversion to PeriodOps from Period") { f ⇒ 96 | import f._ 97 | val v: PeriodOps = Period.ZERO 98 | v.isInstanceOf[PeriodOps] shouldBe true 99 | } 100 | 101 | test("implicit conversion to TemporalAmountOps from TemporalAmount") { f ⇒ 102 | import f._ 103 | val v: TemporalAmountOps = Period.ZERO 104 | v.isInstanceOf[TemporalAmountOps] shouldBe true 105 | } 106 | 107 | test("implicit conversion to TemporalOps from Temporal") { f ⇒ 108 | import f._ 109 | val v: TemporalOps = LocalDate.MIN 110 | v.isInstanceOf[TemporalOps] shouldBe true 111 | } 112 | 113 | test("implicit conversion to TemporalQuery from a function (TemporalAccessor) => A") { f ⇒ 114 | import f._ 115 | val v: TemporalQuery[_] = (a: TemporalAccessor) ⇒ a 116 | v.isInstanceOf[TemporalQuery[_]] shouldBe true 117 | } 118 | 119 | test("implicit conversion to TemporalQueryOps from a function (TemporalAccessor) => A") { f ⇒ 120 | import f._ 121 | val v: TemporalQueryOps[_] = (a: TemporalAccessor) ⇒ a 122 | v.isInstanceOf[TemporalQueryOps[_]] shouldBe true 123 | } 124 | 125 | test("implicit conversion to TemporalQueryOps from a TemporalQuery") { f ⇒ 126 | import f._ 127 | val v: TemporalQueryOps[_] = TemporalQueries.chronology() 128 | v.isInstanceOf[TemporalQueryOps[_]] shouldBe true 129 | } 130 | 131 | test("implicit conversion to TemporalUnitOps from a TemporalUnit") { f ⇒ 132 | import f._ 133 | val v: TemporalUnitOps = ChronoUnit.FOREVER 134 | v.isInstanceOf[TemporalUnitOps] shouldBe true 135 | } 136 | 137 | test("implicit conversion to YearMonthOps from a YearMonth") { f ⇒ 138 | import f._ 139 | val v: YearMonthOps = YearMonth.now() 140 | v.isInstanceOf[YearMonthOps] shouldBe true 141 | } 142 | 143 | test("implicit conversion to YearOps from a Year") { f ⇒ 144 | import f._ 145 | val v: YearOps = Year.now() 146 | v.isInstanceOf[YearOps] shouldBe true 147 | } 148 | 149 | override type FixtureParam = ToAllOps with ToAllStd 150 | 151 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new ToAllOps with ToAllStd {})) 152 | } 153 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/YearMonthOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time.format.{DateTimeFormatterBuilder, SignStyle} 22 | import java.time.temporal.ChronoField._ 23 | import java.time.{LocalDate, YearMonth} 24 | 25 | import org.scalatest.{Matchers, Outcome, fixture} 26 | 27 | 28 | class YearMonthOpsSuite extends fixture.FunSuite with Matchers { 29 | 30 | test("`+` obtains a YearMonth with the specified number of months added")(_ + 6 shouldBe YearMonth.of(2016, 10)) 31 | 32 | test("`-` obtains a YearMonth with the specified number of months subtracted")(_ - 6 shouldBe YearMonth.of(2015, 10)) 33 | 34 | test("`<` returns true if the specified YearMonth is before the underlying value")(_ < YearMonth.of(2016, 10) shouldBe true) 35 | 36 | test("`<=` returns true if the specified YearMonth is before or equal the underlying value") { ym ⇒ 37 | ym <= YearMonth.of(2016, 10) shouldBe true 38 | ym <= YearMonth.of(2016, 4) shouldBe true 39 | } 40 | 41 | test("`>` returns true if the specified YearMonth is after the underlying value")(_ > YearMonth.of(2015, 10) shouldBe true) 42 | 43 | test("`>=` returns true if the specified YearMonth is after or equal the underlying value") { ym ⇒ 44 | ym >= YearMonth.of(2015, 10) shouldBe true 45 | ym >= YearMonth.of(2016, 4) shouldBe true 46 | } 47 | 48 | test("`/` obtains a LocalDate by combining the underlying value with the specified day-of-month")(_ / 4 shouldBe LocalDate.of(2016, 4, 4)) 49 | 50 | test("`|>` formats the underlying value with the specified formatter.")(_ |> formatter shouldBe "2016-04") 51 | 52 | test("`▹` formats the underlying value with the specified formatter.")(_ ▹ formatter shouldBe "2016-04") 53 | 54 | 55 | private def formatter = new DateTimeFormatterBuilder() 56 | .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD) 57 | .appendLiteral('-').appendValue(MONTH_OF_YEAR, 2) 58 | .toFormatter 59 | 60 | override type FixtureParam = YearMonthOps 61 | 62 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new YearMonthOps(YearMonth.of(2016, 4)))) 63 | } 64 | -------------------------------------------------------------------------------- /src/test/scala/scalatime/impl/YearOpsSuite.scala: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * See the NOTICE file distributed with this work for additional * 3 | * information regarding Copyright ownership. The author/authors * 4 | * license this file to you under the terms of the Apache License * 5 | * Version 2.0 (the "License"); you may not use this file except * 6 | * in compliance with the License. You may obtain a copy of the * 7 | * License at: * 8 | * * 9 | * http://www.apache.org/licenses/LICENSE-2.0 * 10 | * * 11 | * Unless required by applicable law or agreed to in writing, * 12 | * software distributed under the License is distributed on an * 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * 14 | * either express or implied. See the License for the specific * 15 | * language governing permissions and limitations under the * 16 | * License. * 17 | ******************************************************************/ 18 | 19 | package scalatime.impl 20 | 21 | import java.time._ 22 | import java.time.format.{DateTimeFormatterBuilder, SignStyle} 23 | import java.time.temporal.ChronoField._ 24 | 25 | import org.scalatest.{Matchers, Outcome, fixture} 26 | 27 | 28 | class YearOpsSuite extends fixture.FunSuite with Matchers { 29 | 30 | test("`+` obtains a Year with the specified number of years added")(_ + 6 shouldBe Year.of(2022)) 31 | 32 | test("`-` obtains a Year with the specified number of years subtracted")(_ - 6 shouldBe Year.of(2010)) 33 | 34 | test("`<` returns true if the specified Year is before the underlying value")(_ < Year.of(2017) shouldBe true) 35 | 36 | test("`<` returns true if the specified Year is before or equal to the underlying value") { y ⇒ 37 | y <= Year.of(2017) shouldBe true 38 | y <= Year.of(2016) shouldBe true 39 | } 40 | 41 | test("`>` returns true if the specified Year is after the underlying value")(_ > Year.of(2015) shouldBe true) 42 | 43 | test("`>=` returns true if the specified Year is after or equal to the underlying value") { y ⇒ 44 | y >= Year.of(2015) shouldBe true 45 | y >= Year.of(2016) shouldBe true 46 | } 47 | 48 | test("`/(month: Month)` obtains a YearMonth by combining the underlying value with the specified Month")(_ / Month.JANUARY shouldBe YearMonth.of(2016, 1)) 49 | 50 | test("`/(month: Int)` obtains a YearMonth by combining the underlying value with the specified Month")(_ / 1 shouldBe YearMonth.of(2016, 1)) 51 | 52 | test("`/(monthDay: MonthDay)` obtains a LocalDate by combining the underlying value with the specified MonthDay")(_ / MonthDay.of(1, 1) shouldBe LocalDate.of(2016, 1, 1)) 53 | 54 | test("`|>` formats the underlying value with the specified formatter.")(_ |> formatter shouldBe "2016") 55 | 56 | test("`▹` formats the underlying value with the specified formatter.")(_ ▹ formatter shouldBe "2016") 57 | 58 | private def formatter = new DateTimeFormatterBuilder() 59 | .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD) 60 | .toFormatter 61 | 62 | override type FixtureParam = YearOps 63 | 64 | override protected def withFixture(test: OneArgTest): Outcome = withFixture(test.toNoArgTest(new YearOps(Year.of(2016)))) 65 | } 66 | --------------------------------------------------------------------------------