1

I am trying to create a udf to take two strings as parameters; one in DD-MM-YYYY format (e.g. "14-10-2019") and the other in float format (e.g. "0.000"). I want to convert the float-like string to an int and add it to the date object to get another date which I want to return as a string.

def getEndDate = udf{ (startDate: String, no_of_days : String) =>
  val num_days = no_of_days.trim.toInt //Converts the String value to Integer
  val date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(startDate) //Parses the string date to timestamp
  calObj.setTime(date) //Sets the calendar object instance
  calObj.add(Calendar.DAY_OF_MONTH, num_days) //Adds the number of days to the start date
  val endDate = calObj.getTime().toString //Gets end date in string format
  endDate
}

When trying to run this, I am getting the following error:

Caused by: java.lang.NumberFormatException: For input string: "0.000"

RJM
  • 11
  • 1
  • 3
  • 1
    Try to debug it. What are the values of `startDate` and `no_of_days` at the point when the exception is thrown? – cbley Nov 15 '19 at 07:18
  • It throws an error on the row itself. startDate = 14-10-2019T00:00:00. no_of_days = "0.000" – RJM Nov 15 '19 at 08:24
  • 1
    That's not what I had asked -- look at the actual values. Are the `"` quotes perhaps part of the `no_of_days` value? You would need to strip the quotes first. – cbley Nov 15 '19 at 08:28
  • No, the quotes are not part of the value. I also checked for leading/trailing spaces. The data seems to be clean. – RJM Nov 15 '19 at 08:32
  • 1
    Show the complete stacktrace please, where exactly does the exception happen? Unit test your function in isolation, does it work for the inputs you mention. If it does, you're probably not getting the inputs you think you do. – cbley Nov 15 '19 at 09:01
  • `no_of_days.replaceFirst("\\..*$", "").toInt` should work, also in case of a decimal _comma_. – Joop Eggen Nov 15 '19 at 13:28
  • I am using Databricks. I tried every possible option, include splitting the float-like string and the replaceFirst, but I encountered the same error message every time. Finally, I detached the cluster from my notebook and re-attached it, and the same piece of code ran without throwing any exceptions. – RJM Nov 18 '19 at 08:36

2 Answers2

1

Strings like "0.0000" can't be parsed directly to integer. What you could try instead is to use first toDouble and then toInt:

no_of_days.trim.toDouble.toInt

It will round value down. If you want to round value to closest maybe you should consider using round:

no_of_days.trim.toDouble.round

Another issue with your code is, that you shouldn't use SimpleDateFormat since it's outdated. You should use LocalDate and DateTimeFormatter instead:

val date = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("dd-MM-
yyyy")) 
date.plusDays(num_days)
user2342558
  • 5,567
  • 5
  • 33
  • 54
Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
  • Hi, I tried converting it to double and then to int, but it is still giving the same error. Just to clarify, the "0.000" will always have a whole number before the decimal point, so I even tried splitting the string on '.' and grabbing the digits in front of the decimal point and then converting it to int, but still same issue. – RJM Nov 15 '19 at 06:35
  • And you always have same exception? `Caused by: java.lang.NumberFormatException: For input string: "0.000"` ? – Krzysztof Atłasik Nov 15 '19 at 07:06
  • Yes, the exact same message. – RJM Nov 15 '19 at 07:08
0

I wouldn't recommend doing this but here's some examples which solve your problem.

scala> "0.00".toDouble.toInt
res0: Int = 0

scala> "2.45".toDouble.toInt
res1: Int = 2

scala> "2.5".toDouble.toInt
res2: Int = 2

scala> "2.6".toDouble.toInt
res3: Int = 2

scala> "-1".toDouble.toInt
res4: Int = -1

scala> "-1.5".toDouble.toInt
res5: Int = -1
Rhys Bradbury
  • 1,699
  • 13
  • 24
  • 1
    Thank you. I tried most of them, but they generated the same exception every time. Re-attaching the cluster to the Databricks notebook solved this problem. – RJM Nov 18 '19 at 08:38