Pure Scala date api (no third party dep!)


Scalendar is a pure Scala date api that interoperates quite nicely with java.util.Calendar and java.util.Date. Ideas evolved from my blog.


  • Immutability
  • Interoperability
  • Easy date traversal
  • Easy date arithmetic


// Everything in single import
import scalendar._

val now = Scalendar.now

// Normalcy
// 3 is March
// Include these enumerations if you get confused
// ie: What day is Sunday? 0, 1, 7? Use Day.Sunday
import Month._
import Day._

val april = Scalendar(year = 2012,
                      month = April,
                      day = 1)

val wed = now.day.inWeek(Wednesday)

Date Arithmetic

Adding to a time could not be easier.

val tomorrow = Scalendar.now + 1.day

val far = tomorrow + 3.months - 4.weeks

val away = far + 5.years + 14.months - 5667.days

Obtaining fields

Scalendar API provides a very uniform way to access calendar fields. Every field has a name that tries to create an English name for the field, and a value, which is its numeric value:

val now = Scalendar.now

// etc

TimeZone Support

Given a Scalendar object, one can easily finding the TimeZone associated with it. All TimeZone related operations are acquired from the tz field.

val tz = now.tz

val pst = now.tz("PST")

// Find the offset (in millis) from UTC

// Find the offset (in millis) from another TZ

Time Converions / Periods

The Scalendar library now supports periods of time, and easy time conversions. The programmer should never have to write silly mathematical conversions.

val period = 4.weeks + 30.hours - 8.minutes

println(period.into.seconds) // Going to be big!
println(period.into.days) // A lot smaller

println("Whoa, that timespan you mentioned is actually %d hours" format(period.into.hours))

val future = Scalendar.now + period

You get the idea.

Creating Durations

Creating a meaningful duration of time very simple to create with the to dsl word.

val duration = Scalendar.now to Scalendar.now + 1.week

// Determining delta
// etc

Traversing a Duration

There are two ways to traverse a duration:

  1. The traverse method
  2. The by dsl word

The following code will illustrate their use:

// by will return a list of durations, which
// can be operated on as a List
// This only returns MWF
val mwf = duration by 1.day filter(_.day.name match {
  case "Monday" | "Wednesday" | "Friday" => true
  case _ => false

// traverse returns by traversal
val html =
  duration.traverse(1.week) { weekDur =>
      weekDur.traverse(1.day) { dayDur =>
        <td>{ dayDur.day.value.toString }</td>


View more examples of how to use the library in the test source file.


  • scala (Cross compiled / published)
    • 2.12.1
    • 2.11.8
    • 2.11.0
    • 2.10.3


Installing the library as a dependency is easy using maven or sbt. In sbt,

libraryDependencies += "com.github.philcali" %% "scalendar" % "0.1.5"

Example Program

I have included a sample program, which includes parsing data from a log file, and checking its date.

import scalendar._

// Log time pattern
implicit val pattern = Pattern("M/d/yyy")

val tomorrow = Scalendar.now + 1.day

// Day duration from yesterday's run 
val dayIn = (Scalendar.now - 1.day) to Scalendar.now

// open csv
import scala.io.Source.{ fromFile => open }

// Prints out log entry
for(line <- open("test.log").getLines;
  val split = line.split(",");
  val time = split(3);
  if (time isIn dayIn) {

println("Expect the next run on %d" format(pattern.format(tomorrow)))