aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/com/drivergrp/core/time.scala
blob: 645c991c0dd0e43f929615d9bd125a3c53e1a3ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.drivergrp.core

import java.text.SimpleDateFormat
import java.util.{Calendar, Date, GregorianCalendar}

import scala.concurrent.duration.Duration

object time {

  // The most useful time units
  val Second = 1000L
  val Seconds = Second
  val Minute = 60 * Seconds
  val Minutes = Minute
  val Hour = 60 * Minutes
  val Hours = Hour
  val Day = 24 * Hours
  val Days = Day
  val Week = 7 * Days
  val Weeks = Week


  case class Time(millis: Long) extends AnyVal {

    def isBefore(anotherTime: Time): Boolean = millis < anotherTime.millis

    def isAfter(anotherTime: Time): Boolean = millis > anotherTime.millis

    def advanceBy(duration: Duration): Time = Time(millis + duration.length)
  }

  case class TimeRange(start: Time, end: Time)

  implicit def timeOrdering: Ordering[Time] = Ordering.by(_.millis)


  def startOfMonth(time: Time) = {
    make(new GregorianCalendar()) { cal =>
      cal.setTime(new Date(time.millis))
      cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH))
      Time(cal.getTime.getTime)
    }
  }

  def textualDate(time: Time): String =
    new SimpleDateFormat("MMMM d, yyyy").format(new Date(time.millis))

  def textualTime(time: Time): String =
    new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a").format(new Date(time.millis))


  object provider {

    /**
      * Time providers are supplying code with current times
      * and are extremely useful for testing to check how system is going
      * to behave at specific moments in time.
      *
      * All the calls to receive current time must be made using time
      * provider injected to the caller.
      */

    trait TimeModule {
      def time: TimeProvider
    }

    trait TimeProvider {
      def currentTime(): Time
    }

    final class SystemTimeProvider extends TimeProvider {
      def currentTime() = Time(System.currentTimeMillis())
    }

    final class SpecificTimeProvider(time: Time) extends TimeProvider {
      def currentTime() = time
    }
  }
}