Created
June 29, 2012 23:30
-
-
Save lucascs/3021384 to your computer and use it in GitHub Desktop.
Parser de datas em Scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
libraryDependencies ++= Seq( | |
"org.specs2" %% "specs2" % "1.11" % "test", | |
"joda-time" % "joda-time" % "2.1", | |
"org.joda" % "joda-convert" % "1.2" | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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