All Downloads are FREE. Search and download functionalities are using the official Maven repository.

wen.instances.datetime.TimeInstances.scala Maven / Gradle / Ivy

The newest version!
package wen.instances.datetime

import cats.implicits._
import cats.{Order, Show}
import wen.datetime.Offset.{OffsetType, UTCMinus, UTCPlus}
import wen.datetime.{Offset, Time, ZoneTime}
import wen.types._

object TimeInstances extends TimeInstances

trait TimeInstances {

  implicit val timeOrderInstance: Order[Time] = new Order[Time] {
    override def compare(x: Time, y: Time): Int = {
      lazy val timeToInt: Time => Int = { t =>
        val minutes = t.hour.hour.value * 60 + t.minute.minute.value
        val seconds = minutes * 60 + t.second.second.value
        seconds * 1000 + t.millisecond.millisecond.value
      }

      Order[Int].compare(timeToInt(x), timeToInt(y))
    }
  }

  implicit val zoneTimeOrderInstance: Order[ZoneTime] = new Order[ZoneTime] {
    override def compare(x: ZoneTime, y: ZoneTime): Int = {
      lazy val offsetOperation: OffsetType => (Int => Int => Int) = {
        case UTCMinus => {a: Int => { b: Int => a - b }}
        case UTCPlus => {a: Int => { b: Int => a + b }}
      }
      lazy val zoneTimeToInt: ZoneTime => Int = {
        case ZoneTime(Time(Hour(h), Minute(m), Second(s), Millisecond(ms)), Offset(ot, Hour(oh), Minute(om))) =>
          val minutes = offsetOperation(ot)(h.value * 60 + m.value)(oh.value * 60 + om.value)
          val seconds = minutes * 60 + s.value
          seconds * 1000 + ms.value
      }

      Order[Int].compare(zoneTimeToInt(x), zoneTimeToInt(y))
    }
  }

  implicit val offsetOrderInstance: Order[Offset] = new Order[Offset] {
    override def compare(x: Offset, y: Offset): Int = {
      (x, y) match {
        case (Offset(_, Hour(h1), Minute(m1)), Offset(_, Hour(h2), Minute(m2)))
          if h1.value === 0 && m1.value === 0 && h2.value === 0 && m2.value === 0 => 0
        case (Offset(UTCPlus, _, _), Offset(UTCMinus, _, _)) => 1
        case (Offset(UTCMinus, _, _), Offset(UTCPlus, _, _)) => -1
        case (Offset(UTCPlus, h1, m1), Offset(UTCPlus, h2, m2)) =>
          Time(h1, m1) compare Time(h2, m2)
        case (Offset(UTCMinus, h1, m1), Offset(UTCMinus, h2, m2)) =>
          (Time(h1, m1) compare Time(h2, m2)) * -1
      }
    }
  }

  implicit val timeShowInstance: Show[Time] = new Show[Time] {
    override def show(t: Time): String =
      t match {
        case Time(Hour(h), Minute(m), Second(s), Millisecond(ms)) =>
          f"${h.value}%02d:${m.value}%02d:${s.value}%02d.${ms.value}"
      }

  }

  implicit val zoneTimeShowInstance: Show[ZoneTime] = new Show[ZoneTime] {
    override def show(t: ZoneTime): String =
      t match {
        case ZoneTime(time, offset) =>
          s"${time.show} ${offset.show}"
      }
  }

  implicit val offsetShowInstance: Show[Offset] = new Show[Offset] {
    override def show(t: Offset): String =
      t match {
        case Offset(_, Hour(h), Minute(m)) if h.value === 0 && m.value === 0 => "+00:00"
        case Offset(t, Hour(h), Minute(m)) => f"${OffsetType.symbol(t)}${h.value}%02d:${m.value}%02d"
      }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy