How do I validate a timestamp in scala? - scala

my application takes in a string like this "2002-10-15 10:55:01.000000". I need to validate inside scala script that the string is a valid for a db2 timestamp.

In general (I'd guess) you would do it moslty the same way as in java with either java.text.DateFormat or joda.time.DateTimeFormat (see Joda time).
A simple example:
import java.text.SimpleDateFormat
import java.util.Date
import scala.util.Try
val date = "2002-10-15 10:55:01.000000"
val formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSS")
val test = Try[Date](formatter.parse(date))
would give you:
test: scala.util.Try[java.util.Date] = Success(Tue Oct 15 10:55:01 CEST 2002)
Then you could match:
test match {
case Success(date) => // ok
case Failure(exception) => // not ok
}

You should use SimpleDateFormat of java to do that in scala :
object DateParser {
def isValid(f : String, d : String) = {
try {
val format = new java.text.SimpleDateFormat(f)
format.parse(d)
}catch(java.text.ParseException e) {
false
}
}
def main(args : Array[String]) {
val format = "yyyy-MM-dd k:m:s"
println(isValid(format,"2002-10-15 10:55:01.000000"))
println(isValid(format,"2002-10-1510:55:01.000000"))
}
}

Related

json4s always escapes unicode character €

I try pretty-writing a JString containing a € character with json4s as follows:
import org.joda.time.format.ISODateTimeFormat
import org.joda.time.{DateTime, DateTimeZone}
import org.json4s.native.Serialization.writePretty
import org.json4s.{DateFormat, DefaultFormats, Formats, JString}
import java.util.{Date, TimeZone}
object Json4sEncodingTest {
val formats = new Formats {
val dateFormat: DateFormat = new DateFormat {
override def parse(s: String): Option[Date] =
try {
Option(
DateTime
.parse(s, ISODateTimeFormat.dateTimeParser().withZoneUTC())
.withZone(DateTimeZone.forID(timezone.getID))
.toDate
)
} catch {
case e: IllegalArgumentException => None
}
override def format(d: Date): String = DefaultFormats.lossless.dateFormat.format(d)
override def timezone: TimeZone = DefaultFormats.lossless.dateFormat.timezone
}
override def alwaysEscapeUnicode: Boolean = false
}
def main(args: Array[String]): Unit = {
println(writePretty(JString("2€"))(formats))
}
}
This results in:
"2\u20ac"
My expected result would be:
"2€"
I found that in org.json4s.ParserUtil.quote characters between \u2000 and \u2100 are always escaped.
Question: Why is this the case?
json4s version: 3.7.0-M7
scala version: 2.12.11
As elaborated in this github issue, it is impossible currently to do this using json4s native. The code that checks if to escape or not is:
(c >= '\u0000' && c <= '\u001f') || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')
while € doesn't satisfy this condition. One possible solution (well, sort of solution) is using jackson instead of native. Then this will work:
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonAST.JString
println(pretty(render(JString("2€"))))
Code run at Scastie.

Scala Function to return True/False when a date is present in a list

I am trying to create a function where I would to pass a date as a String and would like to check if its previous date is present in a list that is passed as second parameter to the function. If yes then it should return a boolean.
def fn1(date: String, days: Seq[String]): Boolean = {
....
....
}
Also, I need a similar function that extracts the day from the previous day of the input parameter and then looks it up in a list. This function also returns a boolean.
def fn2(date: String, days: Seq[String]): Boolean = {
....
....
}
How can I implement this in Scala?
Your question is confused and confusing. I don't understand the difference between fn1() and fn2().
Still, maybe this will help.
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
def fn(date: String, days: Seq[String]): Boolean = {
val dtFormat = DateTimeFormatter.ofPattern("<expected format here>")
days.contains(LocalDateTime.parse(date, dtFormat)
.minusDays(1)
.format(dtFormat))
}
First of all, don't pass dates around as Strings, use java.time.LocalDate.
def fn1(date: LocalDate, days: Seq[LocalDate]): Boolean =
days.contains(date.minusDays(1))
I think this solution can solve your problem. Based on your date format just change the split("-") delimiter.
import java.text.SimpleDateFormat
import java.util.Calendar
object Driver{
def getPreviousDate(date:String):String={
val cal=Calendar.getInstance()
val dateArr=date.split("-")
val day=dateArr(0).trim.toInt
val month=dateArr(1).trim.toInt
val year=dateArr(2).trim.toInt
cal.set(Calendar.YEAR, year)
cal.set(Calendar.MONTH, month-1)
cal.set(Calendar.DAY_OF_MONTH, day-1)
val sdf=new SimpleDateFormat("dd-MM-yyyy")
sdf.format(cal.getTime)
}
def fn1(date: String, days: Seq[String]): Boolean = {
val prevDate=getPreviousDate(date)
days.contains(prevDate)
}
def fn2(date: String, days: Seq[String]): Boolean = {
val previousDate=getPreviousDate(date)
val previousDay=previousDate.split("-")(0).trim.toInt
val daysList=days.map(day=>day.split("-")(0).trim.toInt)
daysList.contains(previousDay)
}
def main(arr:Array[String]) {
val days=Seq("10-11-2018","11-11-2018","12-11-2018","13-11-2018")
val date="15-11-2018"
val status=fn1(date,days)
println(status)
val status2=fn1(date,days)
println(status2)
}
}
This is the working code, thanks to all for your help.
def isHoliday(date: String,
days: Seq[String],
holidays: List[String]): Boolean = {
val dtFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val dayFormat = DateTimeFormatter.ofPattern("EEEE")
days.contains(LocalDate.parse(date, dtFormat).minusDays(1).format(dayFormat)) ||
holidays.contains(LocalDate.parse(date, dtFormat).minusDays(1).format(dtFormat))
}
** need to change the string dates to LocalDate.

Date/Time formatting Scala

I'm trying to assert date and time displayed on the page
Problem is it's returning value of "2017-03-11T09:00" instead of "2017-03-11 09:00:00" and I'm confused why as the pattern = yyyy-MM-dd HH:mm:ss
Any ideas?
def getDate :String = {
val timeStamp = find(xpath("//*[#id=\"content\"]/article/div/div/table/tbody/tr[5]/td/div/p[4]")).get.underlying.getText
val stripDate: Array[String] = timeStamp.split("Timestamp:\n")
stripDate(1)
}
def datePattern(date: String): LocalDateTime = {
val pattern: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val result = LocalDateTime.parse(date, pattern)
result
}
def checkDatePattern() = datePattern(getDate).toString shouldBe getDate
The DateTimeFormatter only gets used for the parse operation. It doesn't influence the result of toString. If you want to convert your LocalDateTime to a String in a certain format you have to call
date.format(pattern)
I've managed to get the result I wanted by just deleting some parts of the code. As long as the date is in displayed in the correct format, the test passes if it's displayed in an incorrect format it fails, which is good enough for me. Thanks for your input. CASE CLOSED
def getDate :String = {
val timeStamp = find(xpath("//*[#id=\"content\"]/article/div/div/table/tbody/tr[5]/td/div/p[4]")).get.underlying.getText
val stripDate: Array[String] = timeStamp.split("Timestamp:\n")
stripDate(1)
}
def datePattern(date: String): LocalDateTime = {
val pattern: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
LocalDateTime.parse(date, pattern)
}
def checkDatePattern() = datePattern(getDate)

How can I cast a string to a date in Scala so I can filter in in SparkSQL?

I want to be able to filter on a date just like you would in normal SQL. Is that possible? I'm running into an issue on how to convert the string from the text file into a date.
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.spark.sql._
import org.apache.log4j._
import java.text._
//import java.util.Date
import java.sql.Date
object BayAreaBikeAnalysis {
case class Station(ID:Int, name:String, lat:Double, longitude:Double, dockCount:Int, city:String, installationDate:Date)
case class Status(station_id:Int, bikesAvailable:Int, docksAvailable:Int, time:String)
val dateFormat = new SimpleDateFormat("yyyy-MM-dd")
def extractStations(line: String): Station = {
val fields = line.split(",",-1)
val station:Station = Station(fields(0).toInt, fields(1), fields(2).toDouble, fields(3).toDouble, fields(4).toInt, fields(5), dateFormat.parse(fields(6)))
return station
}
def extractStatus(line: String): Status = {
val fields = line.split(",",-1)
val status:Status = Status(fields(0).toInt, fields(1).toInt, fields(2).toInt, fields(3))
return status
}
def main(args: Array[String]) {
// Set the log level to only print errors
//Logger.getLogger("org").setLevel(Level.ERROR)
// Use new SparkSession interface in Spark 2.0
val spark = SparkSession
.builder
.appName("BayAreaBikeAnalysis")
.master("local[*]")
.config("spark.sql.warehouse.dir", "file:///C:/temp")
.getOrCreate()
//Load files into data sets
import spark.implicits._
val stationLines = spark.sparkContext.textFile("Data/station.csv")
val stations = stationLines.map(extractStations).toDS().cache()
val statusLines = spark.sparkContext.textFile("Data/status.csv")
val statuses = statusLines.map(extractStatus).toDS().cache()
//people.select("name").show()
stations.select("installationDate").show()
spark.stop()
}
}
Obviously fields(6).toDate() doesn't compile but I'm not sure what to use.
I think this post is what you are looking for.
Also here you'll find a good tutorial for string parse to date.
Hope this helps!
Following are the ways u can convert string to date in scala.
(1) In case of java.util.date :-
val date= new SimpleDateFormat("yyyy-MM-dd")
date.parse("2017-09-28")
(2) In case of joda's dateTime:-
DateTime.parse("09-28-2017")
Here is a helping function that takes on a string representing a date and transforms it into a Timestamp
import java.sql.Timestamp
import java.util.TimeZone
import java.text.{DateFormat, SimpleDateFormat}
def getTimeStamp(timeStr: String): Timestamp = {
val dateFormat: DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
val date: Option[Timestamp] = {
try {
Some(new Timestamp(dateFormat.parse(timeStr).getTime))
} catch {
case _: Exception => Some(Timestamp.valueOf("19700101'T'000000"))
}
}
date.getOrElse(Timestamp.valueOf(timeStr))
}
Obviously, you will need to change your input date format from "yyyy-MM-dd'T'HH:mm:ss" into whatever format you have the date string.
Hope this helps.

Marshalling java.util.Date with SprayJson

I am new to Scala and Akka.
I have the following case class:
case class Demo(userId: String, date: java.util.Date, message: String) extends BusinessModel
I have to send List[Demo] in Json format as response to a get request but I am facing problem in the following code due to Date:
implicit val demoFormat: RootJsonFormat[Demo] = jsonFormat3(Demo)
I would be grateful if you may kindly help me out
You need to provide a format for java.util.Date, since spray doesn't have one by default.
A quick google search leads to https://gist.github.com/owainlewis/ba6e6ed3eb64fd5d83e7 :
import java.text._
import java.util._
import scala.util.Try
import spray.json._
object DateMarshalling {
implicit object DateFormat extends JsonFormat[Date] {
def write(date: Date) = JsString(dateToIsoString(date))
def read(json: JsValue) = json match {
case JsString(rawDate) =>
parseIsoDateString(rawDate)
.fold(deserializationError(s"Expected ISO Date format, got $rawDate"))(identity)
case error => deserializationError(s"Expected JsString, got $error")
}
}
private val localIsoDateFormatter = new ThreadLocal[SimpleDateFormat] {
override def initialValue() = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
}
private def dateToIsoString(date: Date) =
localIsoDateFormatter.get().format(date)
private def parseIsoDateString(date: String): Option[Date] =
Try{ localIsoDateFormatter.get().parse(date) }.toOption
}
Import DateMarshalling._ in piece code where you have wrote implicit val demoFormat: RootJsonFormat[Demo] = jsonFormat3(Demo) and it should be ok now :)