├── .gitignore ├── .travis.yml ├── README.md ├── build.sbt ├── package-lock.json ├── project ├── build.properties └── plugins.sbt ├── src ├── main │ └── scala │ │ └── moment │ │ ├── Date.scala │ │ ├── Duration.scala │ │ ├── Getters.scala │ │ ├── Moment.scala │ │ ├── Setters.scala │ │ ├── Timezone.scala │ │ └── Units.scala └── test │ └── scala │ └── compatibilty │ ├── DateSpec.scala │ ├── DurationSpec.scala │ ├── MomentSpec.scala │ └── TimezoneSpec.scala └── version.sbt /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Scala template 3 | *.class 4 | *.log 5 | 6 | # sbt specific 7 | .cache 8 | .history 9 | .lib/ 10 | .bsp/ 11 | dist/* 12 | target/ 13 | lib_managed/ 14 | src_managed/ 15 | project/boot/ 16 | project/plugins/project/ 17 | 18 | # Scala-IDE specific 19 | .scala_dependencies 20 | .worksheet 21 | 22 | 23 | ### SBT template 24 | # Simple Build Tool 25 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control 26 | 27 | target/ 28 | lib_managed/ 29 | src_managed/ 30 | project/boot/ 31 | .history 32 | .cache 33 | 34 | .idea/ 35 | /project/credentials.sbt 36 | 37 | project/.DS_Store 38 | src/.DS_Store 39 | .DS_Store 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | scala: 3 | - 2.12.12 4 | - 2.13.3 5 | 6 | dist: trusty 7 | group: edge 8 | sudo: required 9 | 10 | jdk: 11 | - oraclejdk8 12 | 13 | cache: 14 | directories: 15 | - $HOME/.ivy2/cache 16 | - $HOME/.sbt/boot 17 | 18 | script: 19 | - sbt ++$TRAVIS_SCALA_VERSION! clean test 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moment.js façade for Scala.js 2 | 3 | [![Maven Central](https://img.shields.io/maven-central/v/ru.pavkin/scala-js-momentjs_sjs1_2.13.svg)](https://github.com/vpavkin/scala-js-momentjs) 4 | [![Scala.js](https://www.scala-js.org/assets/badges/scalajs-1.0.0.svg)](https://www.scala-js.org) 5 | 6 | ## Installation 7 | Add the following dependency to your `build.sbt`: 8 | 9 | ```scala 10 | libraryDependencies += 11 | "ru.pavkin" %%% "scala-js-momentjs" % "0.10.9" 12 | ``` 13 | 14 | **Since 0.9.0 scala-js-momentjs can be used with scalajs-bundler**. 15 | 16 | ## Example 17 | ```scala 18 | import moment._ 19 | 20 | Moment.locale("en_GB") 21 | 22 | Moment().calendar() 23 | Moment(millis).calendar() 24 | Moment(millis).fromNow() 25 | ``` 26 | 27 | ## Versions 0.2.0 and earlier 28 | If for some reason you want to use version prior to 0.3.1, then use following examples to import and use the facade: 29 | 30 | ```scala 31 | libraryDependencies += 32 | "io.github.widok" %%% "scala-js-momentjs" % "0.2.0" 33 | ``` 34 | 35 | ```scala 36 | import org.widok.moment._ 37 | 38 | Moment() 39 | ``` 40 | 41 | ## Versions of Moment.js 42 | 43 | | Facade | Moment.js | Moment-timezone | Scala versions | Scala.js version | 44 | |:---------------:|:---------:|:---------------:|:----------------------:|:-----------------: 45 | | 0.10.9 | >=2.29.4 | 0.5.40 | 2.13 | 1.12.0 | 46 | | 0.10.8 | 2.22.2 | 0.5.35 | 2.13 | 1.10.1 | 47 | | 0.10.7 | 2.22.2 | 0.5.34 | 2.13 | 1.10.1 | 48 | | 0.10.5 | 2.22.2 | 0.5.31 | 2.12.11, 2.13.2 | 1.2.0 | 49 | | 0.10.4 | 2.22.2 | 0.5.28 | 2.12.11, 2.13.2 | 0.6.32, 1.0.1 | 50 | | 0.10.3 | 2.22.2 | 0.5.25 | 2.12.10, 2.13.0 | 0.6.32, 1.0.0 | 51 | | 0.10.2 (broken) | 2.22.2 | 0.5.25 | 2.12.10, 2.13.0 | 0.6.32, 1.0.0 | 52 | | 0.10.1 | 2.22.2 | 0.5.25 | 2.12.10, 2.13.0 | 0.6.31, 1.0.0-RC1 | 53 | | 0.10.0 | 2.22.2 | 0.5.25 |2.11.12, 2.12.8, 2.13.0 | 0.6.x | 54 | | 0.9.1 | 2.19.2 | 0.5.14 | 2.11.11, 2.12.4 | 0.6.x | 55 | | 0.9.0 | 2.18.1 | 0.5.13 | 2.11.11, 2.12.2 | 0.6.x | 56 | | 0.8.* | 2.18.1 | 0.5.11 | 2.11.11, 2.12.2 | 0.6.x | 57 | | 0.7.0 | 2.18.1 | 0.5.11 | 2.11.8, 2.12.1 | 0.6.x | 58 | | 0.6.0 | 2.18.0 | 0.5.11 | 2.11.8, 2.12.1 | 0.6.x | 59 | | 0.5.1 | 2.17.1 | 0.5.11 | 2.11.8, 2.12.1 | 0.6.x | 60 | | 0.5.0 | 2.17.1 | 0.5.11 | 2.11.8, 2.12.1 | 0.6.x | 61 | | 0.4.1 | 2.16.0 | 0.5.9 | 2.11.8, 2.12.0 | 0.6.x | 62 | | 0.4.0 | 2.16.0 | 0.5.9 | 2.11.8 | 0.6.x | 63 | | 0.3.3 | 2.15.2 | 0.5.5 | 2.11.8 | 0.6.x | 64 | | 0.3.2 | 2.15.1 | 0.5.5 | 2.11.8 | 0.6.x | 65 | | 0.3.1 | 2.15.1 | 0.5.5 | 2.11.8 | 0.6.x | 66 | 67 | ## License 68 | This façade is licensed under the terms of the Apache v2.0 license. 69 | 70 | ## Authors 71 | * Tim Nieradzik 72 | * Erik LaBianca 73 | * Vladimir Pavkin 74 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | lazy val scalaJsMomentJs = project.in(file(".")). 2 | enablePlugins(ScalaJSBundlerPlugin). 3 | settings(jsEnv := new org.scalajs.jsenv.nodejs.NodeJSEnv()) 4 | 5 | name := "Scala.js façade for Moment.js" 6 | 7 | normalizedName := "scala-js-momentjs" 8 | 9 | organization := "ru.pavkin" 10 | 11 | scalaVersion := "2.13.10" 12 | 13 | scalaJSLinkerConfig ~= { 14 | _.withModuleKind(ModuleKind.CommonJSModule) 15 | } 16 | 17 | val MomentVersion = ">=2.29.4" 18 | val MomentTimezoneVersion = "0.5.40" 19 | val ScalaTestVersion = "3.2.15" 20 | 21 | lazy val npmDeps = Seq( 22 | "moment" -> MomentVersion, 23 | "moment-timezone" -> MomentTimezoneVersion, 24 | ) 25 | 26 | Compile / npmDependencies ++= npmDeps 27 | Test / npmDependencies ++= npmDeps 28 | 29 | libraryDependencies ++= Seq( 30 | "org.scalatest" %%% "scalatest" % ScalaTestVersion % "test", 31 | "org.scalatest" %%% "scalatest-mustmatchers" % ScalaTestVersion % "test", 32 | "org.scalatest" %%% "scalatest-funsuite" % ScalaTestVersion % "test", 33 | ) 34 | 35 | pomExtra := 36 | https://github.com/vpavkin/scala-js-momentjs 37 | 38 | 39 | Apache-2.0 40 | https://www.apache.org/licenses/LICENSE-2.0.html 41 | 42 | 43 | 44 | git://github.com/vpavkin/scala-js-momentjs.git 45 | 46 | 47 | 48 | tindzk 49 | Tim Nieradzik 50 | http://github.com/tindzk/ 51 | 52 | 53 | vpavkin 54 | Vladimir Pavkin 55 | http://github.com/vpavkin/ 56 | 57 | 58 | 59 | publishTo := Some( 60 | if (isSnapshot.value) 61 | Opts.resolver.sonatypeSnapshots 62 | else 63 | Opts.resolver.sonatypeStaging 64 | ) 65 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.7.2 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | val scalaJSVersion = "1.12.0" 2 | 3 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalaJSVersion) 4 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.0") 5 | addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") 6 | addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.21.1") 7 | addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.11") 8 | -------------------------------------------------------------------------------- /src/main/scala/moment/Date.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.UndefOr 5 | import scala.scalajs.js.annotation.JSName 6 | 7 | @js.native 8 | trait CalendarOpts extends js.Object { 9 | val sameDay: UndefOr[String] = js.native 10 | val nextDay: UndefOr[String] = js.native 11 | val lastDay: UndefOr[String] = js.native 12 | val lastWeek: UndefOr[String] = js.native 13 | val sameElse: UndefOr[String] = js.native 14 | } 15 | 16 | @js.native 17 | trait Date extends js.Object with Getters with Setters[Date] { 18 | def toDate(): js.Date = js.native 19 | def toISOString(): String = js.native 20 | def fromNow(): String = js.native 21 | def fromNow(withoutSuffix: Boolean): String = js.native 22 | def isValid(): Boolean = js.native 23 | def format(): String = js.native 24 | def format(pattern: String): String = js.native 25 | def startOf(unit: String): Date = js.native 26 | def endOf(unit: String): Date = js.native 27 | def calendar(): String = js.native 28 | def calendar(reference: Date): String = js.native 29 | def calendar(reference: UndefOr[Date], opts: CalendarOpts): String = js.native 30 | def isBefore(date: Date): Boolean = js.native 31 | def isBefore(date: Date, unit: String): Boolean = js.native 32 | def isBetween(m1: Date, m2: Date): Boolean = js.native 33 | def isAfter(date: Date): Boolean = js.native 34 | def isAfter(date: Date, unit: String): Boolean = js.native 35 | def isSame(date: Date): Boolean = js.native 36 | def isSame(date: Date, unit: String): Boolean = js.native 37 | def isoWeekday(): Int = js.native 38 | def isoWeekday(newDay: Int): Date = js.native 39 | def diff(date: Date): Int = js.native 40 | def diff(date: Date, unit: String): Double = js.native 41 | def diff(date: Date, unit: String, asFloat: Boolean): Double = js.native 42 | def local(): Date = js.native 43 | def utc(): Date = js.native 44 | def utcOffset(): Double = js.native 45 | def utcOffset(newOffset: String): Date = js.native 46 | def utcOffset(newOffset: Int): Date = js.native 47 | 48 | def unix(): Double = js.native 49 | 50 | def tz(tz: String): Date = js.native 51 | def tz(): String = js.native 52 | 53 | def seconds(n: Int): Date = js.native 54 | def minutes(n: Int): Date = js.native 55 | def hours(n: Int): Date = js.native 56 | 57 | // direct field setters 58 | def millisecond(value: Double): Date = js.native 59 | def second(value: Double): Date = js.native 60 | def minute(value: Double): Date = js.native 61 | def hour(value: Double): Date = js.native 62 | def day(value: Double): Date = js.native 63 | def month(value: Double): Date = js.native 64 | def year(value: Double): Date = js.native 65 | def date(value: Double): Date = js.native 66 | 67 | @JSName("valueOf") 68 | def value(): Double = js.native 69 | 70 | def isDST(): Boolean = js.native 71 | } 72 | -------------------------------------------------------------------------------- /src/main/scala/moment/Duration.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.JSName 5 | 6 | @js.native 7 | trait Duration extends js.Object with Setters[Duration] { 8 | @JSName("humanize") 9 | def humanise(): String = js.native 10 | 11 | @JSName("humanize") 12 | def humanise(withSuffix: Boolean): String = js.native 13 | 14 | def hours(): Int = js.native 15 | def minutes(): Int = js.native 16 | def milliseconds(): Int = js.native 17 | def seconds(): Int = js.native 18 | def days(): Int = js.native 19 | def months(): Int = js.native 20 | def years(): Int = js.native 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/moment/Getters.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait Getters extends js.Object { 7 | def millisecond(): Int = js.native 8 | def second(): Int = js.native 9 | def minute(): Int = js.native 10 | def hour(): Int = js.native 11 | def day(): Int = js.native 12 | def month(): Int = js.native 13 | def year(): Int = js.native 14 | def date(): Int = js.native 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/moment/Moment.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.JSImport 5 | 6 | @js.native 7 | trait Moment extends js.Object { 8 | def apply(): Date = js.native 9 | 10 | /* Long has different semantics than JavaScript's numbers, therefore Double 11 | * must be used. 12 | */ 13 | def apply(millis: Double): Date = js.native 14 | 15 | def apply(moment: Date): Date = js.native 16 | def apply(date: js.Date): Date = js.native 17 | def apply(string: String): Date = js.native 18 | def apply(string: String, format: String): Date = js.native 19 | def apply(string: String, format: String, locale: String): Date = js.native 20 | def apply(string: String, format: String, strict: Boolean): Date = js.native 21 | def apply(string: String, format: String, locale: String, strict: Boolean): Date = js.native 22 | def apply(opts: js.Any): Date = js.native 23 | 24 | def utc(): Date = js.native 25 | 26 | /* Long has different semantics than JavaScript's numbers, therefore Double 27 | * must be used. 28 | */ 29 | def utc(millis: Double): Date = js.native 30 | 31 | def utc(arr: js.Array[Int]): Date = js.native 32 | def utc(string: String): Date = js.native 33 | def utc(string: String, format: String): Date = js.native 34 | def utc(string: String, formats: js.Array[String]): Date = js.native 35 | def utc(string: String, format: String, locale: String): Date = js.native 36 | def utc(moment: Date): Date = js.native 37 | def utc(date: js.Date): Date = js.native 38 | 39 | def locale(s: String): Unit = js.native 40 | 41 | def duration(millis: Int): Duration = js.native 42 | def duration(time: Int, unit: String): Duration = js.native 43 | def duration(time: String): Duration = js.native 44 | 45 | def weekdaysShort(): js.Array[String] = js.native 46 | def weekdaysShort(index: Int): String = js.native 47 | 48 | def tz(millis: Double, zone: String): Date = js.native 49 | def tz(arr: js.Array[Int], zone: String): Date = js.native 50 | def tz(moment: Date, zone: String): Date = js.native 51 | def tz(date: js.Date, zone: String): Date = js.native 52 | def tz(string: String, zone: String): Date = js.native 53 | def tz(string: String, format: String, zone: String): Date = js.native 54 | def tz(string: String, format: String, locale: String, zone: String): Date = js.native 55 | def tz(string: String, format: String, strict: Boolean, zone: String): Date = js.native 56 | def tz(string: String, format: String, locale: String, strict: Boolean, zone: String): Date = js.native 57 | 58 | def tz: Timezone = js.native 59 | 60 | def isDate(): Boolean = js.native 61 | 62 | /* Check if a variable is a native js Date object */ 63 | def isDate(moment: js.Date): Boolean = js.native 64 | 65 | } 66 | 67 | @JSImport("moment-timezone", JSImport.Namespace, "moment") 68 | @js.native 69 | object Moment extends Moment 70 | 71 | -------------------------------------------------------------------------------- /src/main/scala/moment/Setters.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait Setters[T] extends js.Object { 7 | def add(time: Int, unit: String): T = js.native 8 | def add(time: Double, unit: String): T = js.native 9 | def add(millis: Int): T = js.native 10 | def add(duration: Duration): T = js.native 11 | 12 | def subtract(time: Int, unit: String): T = js.native 13 | def subtract(time: Double, unit: String): T = js.native 14 | def subtract(millis: Int): T = js.native 15 | def subtract(duration: Duration): T = js.native 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/moment/Timezone.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait Timezone extends js.Any { 7 | def names(): js.Array[String] = js.native 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/moment/Units.scala: -------------------------------------------------------------------------------- 1 | package moment 2 | 3 | object Units { 4 | val Millisecond = "millisecond" 5 | val Second = "second" 6 | val Minute = "minute" 7 | val Hour = "hour" 8 | val Day = "day" 9 | val Date = "date" 10 | val Week = "week" 11 | val ISOWeek = "isoweek" 12 | val Month = "month" 13 | val Quarter = "quarter" 14 | val Year = "year" 15 | } 16 | -------------------------------------------------------------------------------- /src/test/scala/compatibilty/DateSpec.scala: -------------------------------------------------------------------------------- 1 | package compatibilty 2 | 3 | import moment.{Moment, Units} 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.must.Matchers 6 | 7 | class DateSpec extends AnyFunSuite with Matchers { 8 | 9 | val jsDate: Double = scala.scalajs.js.Date.UTC(2019, 5, 1) 10 | 11 | test("toDate") { 12 | Moment().toDate() mustBe a[scala.scalajs.js.Date] 13 | } 14 | 15 | test("toISOString") { 16 | compatAssert(_.toISOString()) 17 | } 18 | 19 | test("fromNow") { 20 | compatAssert(_.fromNow()) 21 | } 22 | 23 | test("fromNow with suffix / without suffix") { 24 | compatAssert(_.fromNow(true)) 25 | compatAssert(_.fromNow(false)) 26 | } 27 | 28 | test("isValid()") { 29 | compatAssert(_.isValid()) 30 | } 31 | 32 | test("format()") { 33 | compatAssert(_.format()) 34 | } 35 | 36 | test("format(pattern: String)") { 37 | compatAssert(_.format("MM-DD-YYYY")) 38 | } 39 | 40 | test("startOf") { 41 | compatAssert(_.startOf("hour")) 42 | } 43 | 44 | test("endOf") { 45 | compatAssert(_.endOf("hour")) 46 | } 47 | 48 | test("calendar") { 49 | compatAssert(_.calendar()) 50 | compatAssert(_.calendar(Moment())) 51 | } 52 | 53 | test("isBefore") { 54 | compatAssert(_.isBefore(Moment(jsDate))) 55 | } 56 | 57 | test("isBefore with units") { 58 | compatAssert(_.isBefore(Moment(jsDate), Units.Year)) 59 | } 60 | 61 | test("isBetween") { 62 | compatAssert(_.isBetween(Moment(jsDate), Moment(jsDate))) 63 | } 64 | 65 | test("isAfter") { 66 | compatAssert(_.isAfter(Moment(jsDate))) 67 | } 68 | 69 | test("isAfter(date: Date, unit: String): Boolean") { 70 | compatAssert(_.isAfter(Moment(jsDate), Units.Year)) 71 | } 72 | 73 | test("isSame") { 74 | compatAssert(_.isSame(Moment(jsDate))) 75 | } 76 | 77 | test("isSame with units") { 78 | compatAssert(_.isSame(Moment(jsDate), Units.Year)) 79 | } 80 | 81 | test("isoWeekday") { 82 | compatAssert(_.isoWeekday()) 83 | } 84 | 85 | test("isoWeekday(newDay)") { 86 | compatAssert(_.isoWeekday(4)) 87 | } 88 | 89 | test("diff") { 90 | compatAssert(_.diff(Moment(jsDate))) 91 | } 92 | 93 | test("diff(unit)") { 94 | compatAssert(_.diff(Moment(jsDate), "year")) 95 | } 96 | 97 | test("diff(date: Date, unit: String, asFloat: Boolean)") { 98 | compatAssert(_.diff(Moment(jsDate), "year", asFloat = true)) 99 | } 100 | 101 | test("local") { 102 | compatAssert(_.local()) 103 | } 104 | 105 | test("utc") { 106 | compatAssert(_.utc()) 107 | } 108 | 109 | test("utcOffset") { 110 | compatAssert(_.utcOffset()) 111 | } 112 | 113 | test("utcOffset(newOffset: String)") { 114 | compatAssert(_.utcOffset("+02:00")) 115 | } 116 | 117 | test("utcOffset(newOffset: Int)") { 118 | compatAssert(_.utcOffset(90)) 119 | } 120 | 121 | test("unix") { 122 | compatAssert(_.unix()) 123 | } 124 | 125 | test("tz(tz: String): Date") { 126 | compatAssert(_.tz("Australia/Sydney")) 127 | } 128 | 129 | test("tz(): String") { 130 | compatAssert(_.tz("Australia/Sydney").tz()) 131 | } 132 | 133 | test("seconds(n: Int): Date") { 134 | compatAssert(_.seconds(30)) 135 | } 136 | 137 | test("minutes(n: Int): Date") { 138 | compatAssert(_.minutes(30)) 139 | } 140 | 141 | test("hours(n: Int): Date") { 142 | compatAssert(_.hours(1)) 143 | } 144 | 145 | test("millisecond(value: Double): Date") { 146 | compatAssert(_.millisecond(100)) 147 | } 148 | 149 | test("second(value: Double): Date") { 150 | compatAssert(_.second(40)) 151 | } 152 | 153 | test("minute(value: Double): Date") { 154 | compatAssert(_.minute(100)) 155 | } 156 | 157 | test("hour(value: Double): Date") { 158 | compatAssert(_.hour(4)) 159 | } 160 | 161 | test("day(value: Double): Date") { 162 | compatAssert(_.day(10)) 163 | } 164 | 165 | test("month(value: Double): Date") { 166 | compatAssert(_.month(5)) 167 | } 168 | 169 | test("year(value: Double): Date") { 170 | compatAssert(_.year(2009)) 171 | } 172 | 173 | test("date(value: Double): Date") { 174 | compatAssert(_.date(30)) 175 | } 176 | 177 | test("value(): Double") { 178 | Moment(jsDate).value() mustBe Moment(jsDate).value() 179 | } 180 | 181 | test("isDST(): Boolean") { 182 | Moment(jsDate).isDST() mustBe Moment(jsDate).isDST() 183 | } 184 | 185 | test("millisecond(): Int") { 186 | compatAssert(_.millisecond()) 187 | } 188 | 189 | test("second(): Int") { 190 | compatAssert(_.second()) 191 | } 192 | 193 | test("minute(): Int") { 194 | compatAssert(_.minute()) 195 | } 196 | 197 | test("hour(): Int") { 198 | compatAssert(_.hour()) 199 | } 200 | 201 | test("day(): Int") { 202 | compatAssert(_.day()) 203 | } 204 | 205 | test("month(): Int") { 206 | compatAssert(_.month()) 207 | } 208 | 209 | test("year(): Int") { 210 | compatAssert(_.year()) 211 | } 212 | 213 | test("date(): Int") { 214 | compatAssert(_.date()) 215 | } 216 | 217 | test("add(time: Int, unit: String)") { 218 | compatAssert(_.add(10, Units.Hour)) 219 | } 220 | 221 | test("add(time: Double, unit: String)") { 222 | compatAssert(_.add(10.5, Units.Year)) 223 | } 224 | 225 | test("add(millis: Int)") { 226 | compatAssert(_.add(100500)) 227 | } 228 | 229 | test("add(duration: Duration)") { 230 | compatAssert(_.add(Moment.duration("01:00:00"))) 231 | } 232 | 233 | test("subtract(time: Int, unit: String)") { 234 | compatAssert(_.subtract(10, Units.Year)) 235 | } 236 | 237 | test("subtract(time: Double, unit: String)") { 238 | compatAssert(_.subtract(10.5, Units.Second)) 239 | } 240 | 241 | test("subtract(millis: Int)") { 242 | compatAssert(_.subtract(100500)) 243 | } 244 | 245 | test("subtract(duration: Duration)") { 246 | compatAssert(_.subtract(Moment.duration("01:00:00"))) 247 | } 248 | 249 | private def compatAssert[T](t: moment.Date => T) = 250 | noException should be thrownBy t(Moment(jsDate)) 251 | 252 | } 253 | -------------------------------------------------------------------------------- /src/test/scala/compatibilty/DurationSpec.scala: -------------------------------------------------------------------------------- 1 | package compatibilty 2 | 3 | import moment.{Moment, Units} 4 | import org.scalatest.Assertion 5 | import org.scalatest.funsuite.AnyFunSuite 6 | import org.scalatest.matchers.must.Matchers 7 | 8 | class DurationSpec extends AnyFunSuite with Matchers { 9 | 10 | test("duration humanise without suffix") { 11 | Moment.duration(1).humanise() mustBe "a few seconds" 12 | Moment.duration(1, "year").humanise() mustBe "a year" 13 | Moment.duration("01:00:00").humanise() mustBe "an hour" 14 | } 15 | 16 | test("duration humanise with suffix") { 17 | Moment.duration(1).humanise(true) mustBe "in a few seconds" 18 | } 19 | 20 | test("millisecond(): Int") { 21 | compatAssert(_.milliseconds()) 22 | } 23 | 24 | test("second(): Int") { 25 | compatAssert(_.seconds()) 26 | } 27 | 28 | test("minute(): Int") { 29 | compatAssert(_.minutes()) 30 | } 31 | 32 | test("hour(): Int") { 33 | compatAssert(_.hours()) 34 | } 35 | 36 | test("day(): Int") { 37 | compatAssert(_.days()) 38 | } 39 | 40 | test("month(): Int") { 41 | compatAssert(_.months()) 42 | } 43 | 44 | test("year(): Int") { 45 | compatAssert(_.years()) 46 | } 47 | 48 | test("add(time: Int, unit: String)") { 49 | compatAssert(_.add(10, Units.Hour)) 50 | } 51 | 52 | test("add(time: Double, unit: String)") { 53 | compatAssert(_.add(10.5, Units.Year)) 54 | } 55 | 56 | test("add(millis: Int)") { 57 | compatAssert(_.add(100500)) 58 | } 59 | 60 | test("add(duration: Duration)") { 61 | compatAssert(_.add(Moment.duration("01:00:00"))) 62 | } 63 | 64 | test("subtract(time: Int, unit: String)") { 65 | compatAssert(_.subtract(10, Units.Year)) 66 | } 67 | 68 | test("subtract(time: Double, unit: String)") { 69 | compatAssert(_.subtract(10.5, Units.Second)) 70 | } 71 | 72 | test("subtract(millis: Int)") { 73 | compatAssert(_.subtract(100500)) 74 | } 75 | 76 | test("subtract(duration: Duration)") { 77 | compatAssert(_.subtract(Moment.duration("00:30:00"))) 78 | } 79 | 80 | private def compatAssert[T](t: moment.Duration => T): Assertion = 81 | noException should be thrownBy t(Moment.duration("01:00:00")) 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/test/scala/compatibilty/MomentSpec.scala: -------------------------------------------------------------------------------- 1 | package compatibilty 2 | 3 | import moment.{Moment, Units} 4 | import org.scalatest.Assertion 5 | import org.scalatest.funsuite.AnyFunSuite 6 | import org.scalatest.matchers.must.Matchers 7 | 8 | import scala.scalajs.js 9 | 10 | class MomentSpec extends AnyFunSuite with Matchers { 11 | 12 | test("isDate") { 13 | Moment.isDate() mustBe false 14 | } 15 | 16 | test("isDate(momentDate)") { 17 | Moment.isDate(new js.Date()) mustBe true 18 | } 19 | 20 | test("apply(): Date") { 21 | compatAssert(Moment()) 22 | } 23 | 24 | test("apply(any): Date") { 25 | compatAssert(js.Dynamic.literal( 26 | year = 2019, month = 3, day = 4, minutes = 50, hour = 15, seconds = 59, milliseconds = 999)) 27 | } 28 | 29 | test("apply(millis: Double)") { 30 | compatAssert(Moment(100500)) 31 | } 32 | 33 | test("apply(moment: Date): Date") { 34 | compatAssert(Moment(Moment())) 35 | } 36 | 37 | test("apply(date: js.Date): Date") { 38 | compatAssert(Moment(js.Date.UTC(2009, 1, 1))) 39 | } 40 | 41 | test("apply(string: String): Date") { 42 | compatAssert(Moment("2009-05-01")) 43 | } 44 | 45 | test("apply(string: String, format: String)") { 46 | compatAssert(Moment("2009-05-01", "YYYY-MM-DD")) 47 | } 48 | 49 | test("apply(string: String, format: String, locale: String): Date") { 50 | compatAssert(Moment("2009-05-01", "YYYY-MM-DD", "en")) 51 | } 52 | 53 | test("apply(string: String, format: String, strict: Boolean)") { 54 | compatAssert(Moment("2009-05-01", "YYYY-MM-DD", strict = true)) 55 | compatAssert(Moment("2009-05-01", "YYYY-MM-DD", strict = false)) 56 | } 57 | 58 | test("apply(string: String, format: String, locale: String, strict: Boolean): Date") { 59 | compatAssert(Moment("2009-05-01", "YYYY-MM-DD", "en", strict = true)) 60 | } 61 | 62 | test("utc(): Date") { 63 | compatAssert(Moment.utc()) 64 | } 65 | 66 | test("utc(millis: Double)") { 67 | compatAssert(Moment.utc(100500.0)) 68 | } 69 | 70 | test("utc(arr: js.Array[Int])") { 71 | compatAssert(Moment.utc(js.Array(2010, 1, 14, 15, 25, 50, 125))) 72 | } 73 | 74 | test("utc(string: String)") { 75 | compatAssert(Moment.utc("2013-02-04T22:44:30.652Z")) 76 | } 77 | 78 | test("utc(string: String, format: String)") { 79 | compatAssert(Moment.utc("2013-02-04T22:44:30.652Z")) 80 | } 81 | 82 | test("utc(string: String, formats: js.Array[String])") { 83 | compatAssert(Moment.utc("2013-02-04T22:44:30", js.Array("YYYY-MM-DD:HH:MM:SS"))) 84 | } 85 | 86 | test("utc(string: String, format: String, locale: String)") { 87 | compatAssert(Moment.utc("2013-02-04T22:44:30", "YYYY-MM-DD:HH:MM:SS", "de")) 88 | } 89 | 90 | test("utc(moment: Date): Date") { 91 | compatAssert(Moment.utc(Moment())) 92 | } 93 | 94 | test("utc(date: js.Date)") { 95 | compatAssert(Moment.utc(js.Date.UTC(2009, 1, 1))) 96 | } 97 | 98 | test("locale(s: String)") { 99 | compatAssert(Moment.locale("en")) 100 | } 101 | 102 | test("duration(millis: Int)") { 103 | compatAssert(Moment.duration(100500)) 104 | } 105 | 106 | test("duration(time: Int, unit: String)") { 107 | compatAssert(Moment.duration(100500, Units.Second)) 108 | } 109 | 110 | test("duration(time: String)") { 111 | compatAssert(Moment.duration("23:59:59")) 112 | } 113 | 114 | test("weekdaysShort()") { 115 | compatAssert(Moment.weekdaysShort()) 116 | } 117 | 118 | test("weekdaysShort(index: Int)") { 119 | compatAssert(Moment.weekdaysShort(2)) 120 | } 121 | 122 | test("tz(millis: Double, zone: String)") { 123 | compatAssert(Moment.tz(100500.0, "Australia/Sydney")) 124 | } 125 | 126 | test("tz(arr: js.Array[Int], zone: String)") { 127 | compatAssert(Moment.tz(js.Array(2010, 1, 14, 15, 25, 50, 125), "Australia/Sydney")) 128 | } 129 | 130 | test("tz(moment: Date, zone: String)") { 131 | compatAssert(Moment.tz(Moment(), "Australia/Sydney")) 132 | } 133 | 134 | test("tz(date: js.Date, zone: String)") { 135 | compatAssert(Moment.tz(js.Date.UTC(2009, 1, 1), "Australia/Sydney")) 136 | } 137 | 138 | test("tz(string: String, zone: String): Date") { 139 | compatAssert(Moment.tz("2013-02-04T22:44:30.652Z", "Australia/Sydney")) 140 | } 141 | 142 | test("tz(string: String, format: String, zone: String)") { 143 | compatAssert(Moment.tz("2013-02-04T22:44:30", "YYYY-MM-DD:HH:MM:SS", "Australia/Sydney")) 144 | } 145 | 146 | test("tz(string: String, format: String, locale: String, zone: String)") { 147 | compatAssert(Moment.tz("2013-02-04T22:44:30", "YYYY-MM-DD:HH:MM:SS", "en", "Australia/Sydney")) 148 | } 149 | 150 | test("tz(string: String, format: String, strict: Boolean, zone: String)") { 151 | compatAssert(Moment.tz("2013-02-04T22:44:30", "YYYY-MM-DD:HH:MM:SS", strict = true, "Australia/Sydney")) 152 | } 153 | 154 | test("tz(string: String, format: String, locale: String, strict: Boolean, zone: String)") { 155 | compatAssert(Moment.tz("2013-02-04T22:44:30", "YYYY-MM-DD:HH:MM:SS", "en", strict = true, "Australia/Sydney")) 156 | } 157 | 158 | test("tz") { 159 | compatAssert(Moment.tz) 160 | } 161 | 162 | private def compatAssert[T](t: => T): Assertion = 163 | noException should be thrownBy t 164 | } 165 | -------------------------------------------------------------------------------- /src/test/scala/compatibilty/TimezoneSpec.scala: -------------------------------------------------------------------------------- 1 | package compatibilty 2 | 3 | import moment.Moment 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatest.matchers.must.Matchers 6 | 7 | class TimezoneSpec extends AnyFunSuite with Matchers { 8 | 9 | test("names") { 10 | noException should be thrownBy Moment.tz.names() 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "0.10.10-SNAPSHOT" 2 | --------------------------------------------------------------------------------