Skip to content

Instantly share code, notes, and snippets.

@lucascs
Created June 29, 2012 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucascs/3021384 to your computer and use it in GitHub Desktop.
Save lucascs/3021384 to your computer and use it in GitHub Desktop.
Parser de datas em Scala
libraryDependencies ++= Seq(
"org.specs2" %% "specs2" % "1.11" % "test",
"joda-time" % "joda-time" % "2.1",
"org.joda" % "joda-convert" % "1.2"
)
package me.cavalcanti.lucas
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormatter
import org.joda.time.format.DateTimeFormat
import scala.util.parsing.combinator.JavaTokenParsers
import org.joda.time.Period
class CalendarParser extends JavaTokenParsers {
def dd:Parser[Int] = "0[1-9]|[1-2][0-9]|3[0-1]".r ^^ (_.toInt)
def MM:Parser[Int] = "0[1-9]|1[012]".r ^^ (_.toInt)
def yyyy:Parser[Int] = "\\d{4}".r ^^ (_.toInt)
def / :Parser[String] = "[/-]".r
def diaDaSemana:Parser[Int] = (
("segunda" | "terça" | "quarta" | "quinta" | "sexta") <~ opt("-feira")
| "sábado" | "domingo"
) ^^ {dia => Seq("domingo", "segunda", "terça", "quarta", "quinta", "sexta", "sabado").indexOf(dia)}
def data:Parser[LocalDate] = (
(dd <~ /) ~ (MM <~ /) ~ yyyy ^^ {case dia ~ mes ~ ano => new LocalDate(ano, mes, dia)}
| (yyyy <~ /) ~ (MM <~ /) ~ dd ^^ {case ano ~ mes ~ dia => new LocalDate(ano, mes, dia)}
| (MM <~ /) ~ (dd <~ /) ~ yyyy ^^ {case mes ~ dia ~ ano => new LocalDate(ano, mes, dia)}
| "ontem" ^^ {x => new LocalDate().minusDays(1)}
| opt("pr[óo]xim[ao]".r) ~ diaDaSemana ^^ {
case Some(_) ~ dia => new LocalDate().withDayOfWeek(dia).withWeekOfWeekyear(new LocalDate().getWeekOfWeekyear() + 1)
case None ~ dia => new LocalDate().withDayOfWeek(dia)
}
)
def periodo:Parser[Period] = data ~ "até" ~ data ^^ { case inicio ~ _ ~ fim => new Period(inicio, fim)}
def parse(text:String):LocalDate = {
parseAll(data, text) match {
case Success(date, _) => date
case Failure(msg, in) => throw new IllegalArgumentException("a data é invalida: \n" + msg)
}
}
}
package me.cavalcanti.lucas
import org.specs2.mutable._
import org.joda.time.LocalDate
class CalendarParserSpec extends Specification {
val parser = new CalendarParser
import parser._
"CalendarParser" should {
"parse datas normais" in {
parse("20/06/2012") must_== new LocalDate(2012, 6, 20)
parse("20-06-2012") must_== new LocalDate(2012, 6, 20)
parse("2012-06-20") must_== new LocalDate(2012, 6, 20)
parse("06-20-2012") must_== new LocalDate(2012, 6, 20)
parse("ontem") must_== new LocalDate(2012, 6, 29)
parse("próxima quinta") must_== new LocalDate(2012, 7, 5)
parse("próxima quinta-feira") must_== new LocalDate(2012, 7, 5)
parse("quinta-feira") must_== new LocalDate(2012, 6, 28)
}
}
}
package me.cavalcanti.lucas
import scala.util.parsing.combinator.JavaTokenParsers
class JSONParser extends JavaTokenParsers {
def texto:Parser[String] =
stringLiteral ^^ (_.replaceAll("^\"|\"$", ""))
def valor:Parser[Any] = (
floatingPointNumber ^^ (_.toDouble)
| texto
| "true" ^^ (x => true)
| "false" ^^ (x => false)
| "null" ^^ (x => null)
| json
| array
)
def array:Parser[List[Any]] = "[" ~> repsep(valor, ",") <~ "]"
def entrada:Parser[(String, Any)] = texto ~ ":" ~ valor ^^ {
case chave ~ ":" ~ valor => chave -> valor
}
def json:Parser[Map[String,Any]] = (
"{" ~> repsep(entrada, ",") <~ "}" ^^ {par => Map(par:_*)}
)
def parse(text:String):Map[String,Any] = {
parseAll(json, text).get
}
}
package me.cavalcanti.lucas
import org.specs2.mutable.Specification
class JSONParserSpec extends Specification {
val parser = new JSONParser
import parser._
"JSONParser" should {
"parse tudo" in {
parse("{}") must_== Map()
parse("{\"a\": 1}") must_== Map("a" -> 1)
parse("""
{"a": 1,
"b": "abc"}
""") must_== Map("a" -> 1, "b" -> "abc")
parse("""
{"a": 1,
"b": "abc",
"c": { "x": "y" },
"d": true,
"e": [ 1, 2 ]
}
""") must_== Map(
"a" -> 1,
"b" -> "abc",
"c" -> Map("x" -> "y"),
"d" -> true,
"e" -> List(1,2))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment