Slide 1

Slide 1 text

Minitime @pishen + - × ÷

Slide 2

Slide 2 text

please! give me a star

Slide 3

Slide 3 text

Datetime libraries for Java Joda Time Java Time since Java 8 Minitime

Slide 4

Slide 4 text

ZonedDateTime Basic Components in Java Time LocalDate LocalDateTime LocalTime 2019-08-11T15:19:27.289+08:00

Slide 5

Slide 5 text

Date Operations in Java Time LocalDate.of(2019,8,31).plusMonths(3) LocalDate.of(2019,8,31).plusWeeks(2) LocalDate.of(2019,8,31).plusYears(1) LocalDate.of(2019,8,31).plus(Period.ofMonths(2).plusDays(3)) LocalDate.of(2019,8,31).plusDays(4)

Slide 6

Slide 6 text

LocalDate(2019,8,31) + 4.days LocalDate(2019,8,31) + 3.months LocalDate(2019,8,31) + 2.weeks LocalDate(2019,8,31) + 1.year LocalDate(2019,8,31) + (2.months + 3.days) Date Operations in Minitime

Slide 7

Slide 7 text

Arithmetic Rules in Minitime LocalDate Period + = LocalDate LocalDate Period - = LocalDate Period Period + = Period Period Period - = Period LocalDate LocalDate - = Period Period Int * = Period

Slide 8

Slide 8 text

Arithmetic Rules in Minitime LocalTime Duration + = LocalTime LocalDateTime Period - = LocalDateTime ZonedDateTime Duration + = ZonedDateTime Duration Duration + = Duration LocalDateTime LocalDateTime - = Duration Duration Int * = Duration Duration Int / = Duration LocalTime LocalTime - = Duration ZonedDateTime Period - = ZonedDateTime and more...

Slide 9

Slide 9 text

Date Comparison in Java Time LocalDate.of(2019,8,13).isAfter(LocalDate.of(2019,8,12)) LocalDate.of(2019,8,13).isBefore(LocalDate.of(2019,8,14)) !LocalDate.of(2019,8,13).isBefore(LocalDate.of(2019,8,13)) !LocalDate.of(2019,8,13).isAfter(LocalDate.of(2019,8,13))

Slide 10

Slide 10 text

Date Comparison in Minitime LocalDate(2019,8,13) > LocalDate(2019,8,12) LocalDate(2019,8,13) < LocalDate(2019,8,14) LocalDate(2019,8,13) >= LocalDate(2019,8,13) LocalDate(2019,8,13) <= LocalDate(2019,8,13)

Slide 11

Slide 11 text

Date Ordering in Java Time Seq(date1, date2, date3).sorted Seq(date1, date2, date3).max Seq(date1, date2, date3).min ✘ ✘ ✘

Slide 12

Slide 12 text

Date Ordering in Minitime (Fixed in Scala 2.13) ✔ ✔ ✔ Seq(date1, date2, date3).sorted Seq(date1, date2, date3).max Seq(date1, date2, date3).min import minitime._

Slide 13

Slide 13 text

Ordered vs. Ordering Comparable Comparator Java Scala Ordered Ordering

Slide 14

Slide 14 text

scala.math.Ordering[T] trait Seq[A] { def sorted(implicit ord: Ordering[A]): Seq[A] } Seq(5,4,3,2,1).sorted implicit val intOrd: Ordering[Int] = ... (intOrd) (Included in Scala Standard Library)

Slide 15

Slide 15 text

scala.math.Ordering[T] Seq(date1,date2,date3).sorted( ) ? implicit val dateOrd: Ordering[LocalDate] = ???

Slide 16

Slide 16 text

scala.math.Ordering[T] trait Ordering[T] { def compare(x: T, y: T): Int } implicit val dateOrd = new Ordering[LocalDate] { } Seq(date1,date2,date3).sorted (Included in Minitime) Typeclass override def compare(x: LocalDate, y: LocalDate) = { x.compareTo(y) } (dateOrd)

Slide 17

Slide 17 text

minitime.Add[L, R] trait Add[L, R] { def apply(l: L, r: R): L } val add = new Add[LocalDate,Period] { override def apply(l: LocalDate, r: Period) = { l.plus(r) } } add.apply(LocalDate(2019,8,17), 3.days) // LocalDate(2019,8,20)

Slide 18

Slide 18 text

minitime.Add[L, R] trait Add[L, R] { def apply(l: L, r: R): L } val add = new Add[LocalDate,Period] { override def apply(l: LocalDate, r: Period) = { l.plus(r) } } add(LocalDate(2019,8,17), 3.days) // LocalDate(2019,8,20) 這啥?要幹嘛?

Slide 19

Slide 19 text

Implicit Classes LocalDate(2019,8,17) + 3.days implicit class Infix(l: LocalDate) { def +(r: Period) = l.plus(r) }

Slide 20

Slide 20 text

Implicit Classes new Infix(LocalDate(2019,8,17)) + 3.days implicit class Infix(l: LocalDate) { def +(r: Period) = l.plus(r) }

Slide 21

Slide 21 text

Implicit Classes implicit class Infix(l: LocalDateTime) { } LocalDateTime.now + 3.days LocalDateTime.now + 3.minutes def +(r: Period) = l.plus(r) def +(r: Duration) = l.plus(r)

Slide 22

Slide 22 text

Polymorphism? implicit class Infix(l: Temporal) { def +(r: TemporalAmount) = l.plus(r) } TemporalAmount Temporal Period Duration LocalDate LocalDateTime joda.time.LocalDate joda.time.Period ✘ ✘

Slide 23

Slide 23 text

Type Parameter implicit class Infix[L](l: L) { def +[R](r: R) = } ???

Slide 24

Slide 24 text

minitime.Add[L, R] implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = } ???

Slide 25

Slide 25 text

minitime.Add[L, R] implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = add(l,r) } implicit val ldp: Add[LocalDate,Period] = ... implicit val jda: Add[joda.time.LocalDate,Period] = ... LocalDate(2019,8,17) + 3.days new joda.time.LocalDate(2019,8,17) + 3.days

Slide 26

Slide 26 text

One Implicit Class to Rule Them All implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = add(l,r) }

Slide 27

Slide 27 text

One Implicit Class to Rule Them All implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = add(l,r) def -[R,C](r: R)(implicit sub: Subtract[L,R,C]) = sub(l,r) }

Slide 28

Slide 28 text

One Implicit Class to Rule Them All implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = add(l,r) def -[R,C](r: R)(implicit sub: Subtract[L,R,C]) = sub(l,r) def *(s: Int)(implicit mul: Multiply[L]) = mul(l,s) }

Slide 29

Slide 29 text

One Implicit Class to Rule Them All implicit class Infix[L](l: L) { def +[R](r: R)(implicit add: Add[L,R]) = add(l,r) def -[R,C](r: R)(implicit sub: Subtract[L,R,C]) = sub(l,r) def *(s: Int)(implicit mul: Multiply[L]) = mul(l,s) def /[R,C](r: R)(implicit div: Divide[L,R,C]) = div(l,r) }

Slide 30

Slide 30 text

Arithmetic Rules in Minitime LocalTime Duration + = LocalTime LocalDateTime Period - = LocalDateTime ZonedDateTime Duration + = ZonedDateTime Duration Duration + = Duration LocalDateTime LocalDateTime - = Duration Duration Int * = Duration Duration Int / = Duration LocalTime LocalTime - = Duration ZonedDateTime Period - = ZonedDateTime

Slide 31

Slide 31 text

Arithmetic Rules in Minitime implicit val a1: Add[LocalTime,Duration] LocalDateTime Period - = LocalDateTime ZonedDateTime Duration + = ZonedDateTime Duration Duration + = Duration LocalDateTime LocalDateTime - = Duration Duration Int * = Duration Duration Int / = Duration LocalTime LocalTime - = Duration ZonedDateTime Period - = ZonedDateTime

Slide 32

Slide 32 text

Arithmetic Rules in Minitime implicit val a1: Add[LocalTime,Duration] ZonedDateTime Duration + = ZonedDateTime Duration Duration + = Duration LocalDateTime LocalDateTime - = Duration Duration Int * = Duration Duration Int / = Duration LocalTime LocalTime - = Duration ZonedDateTime Period - = ZonedDateTime implicit val s1: Subtract[LocalDateTime,Period,LocalDateTime]

Slide 33

Slide 33 text

Arithmetic Rules in Minitime And everyone can add his own rules... implicit val a2: Add[ZonedDateTime,Duration] implicit val a3: Add[Duration,Duration] implicit val s2: Subtract[LocalDateTime,LocalDateTime,Duration implicit val m1: Multiply[Duration] implicit val d1: Divide[Duration,Int,Duration] implicit val s3: Subtract[LocalTime,LocalTime,Duration] implicit val s4: Subtract[ZonedDateTime,Period,ZonedDateTime] implicit val s1: Subtract[LocalDateTime,Period,LocalDateTime] implicit val a1: Add[LocalTime,Duration]

Slide 34

Slide 34 text

Reusing Typeclasses Add[L,R] Subtract[L,R,C] Multiply[L] Divide[L,R,C] Infix[L] TimeRange[T,S] Ordering[T]

Slide 35

Slide 35 text

minitime.TimeRange[T, S] // TimeRange( // 2019-08-23,2019-08-24,2019-08-25,2019-08-26,2019-08-27 // ) val dates: TimeRange[LocalDate,Period] = { } LocalDate(2019,8,23) to LocalDate(2019,8,27)

Slide 36

Slide 36 text

minitime.TimeRange[T, S] // TimeRange( // 2019-08-23,2019-08-25,2019-08-27 // ) val dates: TimeRange[LocalDate,Period] = { } LocalDate(2019,8,23) to LocalDate(2019,8,27) by 2.days

Slide 37

Slide 37 text

minitime.TimeRange[T, S] val dates: TimeRange[LocalDate,Period] = { } LocalDate(2019,8,23) to LocalDate(2019,8,27) by 2.days val dateSeq: Seq[LocalDate] = dates // Seq( // 2019-08-23,2019-08-25,2019-08-27 // )

Slide 38

Slide 38 text

Question 1 在明年的聖誕節之前,還有幾個13號星期五? val dates = (LocalDate.now to LocalDate(2020,12,25)) .filter(d => d.getDayOfWeek == FRIDAY && d.getDayOfMonth == 13) // Seq(2019-09-13, 2019-12-13, 2020-03-13, 2020-11-13)

Slide 39

Slide 39 text

Question 2 承上題,每個13號星期五彼此之間相隔幾天? 2019-09-13 2019-12-13 2020-03-13 2020-11-13 ? days ? days ? days

Slide 40

Slide 40 text

Question 2 承上題,每個13號星期五彼此之間相隔幾天? dates.zip(dates.tail).map { case (a, b) => b - a } // Seq(P91D, P91D, P245D) 2019-09-13 2019-12-13 2020-03-13 2020-11-13 91 days 91 days 245 days

Slide 41

Slide 41 text

Question 3 承上上題,有幾個13號星期五會出現在 下一個母親節 跟 下一個感恩節 之間? (五月的第二個星期日 ) (11月的第四個星期四) val mother = (LocalDate(2020,5,1) to LocalDate(2020,5,31)) .filter(_.getDayOfWeek == SUNDAY)(1) val turkey = (LocalDate(2019,11,1) to LocalDate(2019,11,30)) .filter(_.getDayOfWeek == THURSDAY)(3) dates.filter(d => d > turkey && d < mother) // Seq(2019-12-13, 2020-03-13)

Slide 42

Slide 42 text

Cross Compile to JavaScript Minitime using Scala.js

Slide 43

Slide 43 text

Give it a Try Issues and PRs are welcomed.

Slide 44

Slide 44 text

Than[K] Yo[U]