jeudi 11 juin 2020

Implement else-if scala statement in a better way

I work on a function in Scala, that gets a start date, due date and a time zone information as parameters. The function has to return the quarter label, looking like the following:

2020 Q2

There are different cases that can happen:

  • due date is null, calculate quarterly label from start date
  • due date starts with year 9999, calculate quarterly label from start date
  • start date is null, calculate quarterly label from due date
  • when both start and due date is available, they should be the same, return that quarterly label
  • time zone info can be null, or both dates can be null, do nothing in these cases

I started the implementation - ignoring some requirements for now -, and ended up having like million if statements, and they are not even working on a way I want it to.

It calculates the quarter and everything, when both start date and due date is available, together with the time zone info. It skips when time zone is not available (correctly), but it doesn't work when start or due date is missing.

The code:

import java.time.{LocalDateTime,ZoneId}
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit._
import java.time.temporal.IsoFields

object someObject extends Serializable {

  def isEmpty(x: String): Boolean = x == null || Option(x.trim).forall(_.isEmpty)

  def quarterlyFilter(startDate: String, dueDate: String, timeZone: String): String = {

      val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
      val calculatorTZ = ZoneId.of("GMT+4")

    try {
          if(isEmpty(dueDate) == true || dueDate.startsWith("9999")) {
              val start = LocalDateTime.parse(startDate, formatter)
              val incomingTZ = ZoneId.of(timeZone)
              val incomingStart = start.atZone(incomingTZ)

              val calculatedStartDate = incomingStart.withZoneSameInstant(calculatorTZ).toLocalDate

              val quarter = calculatedStartDate.get(IsoFields.QUARTER_OF_YEAR)
              val year = calculatedStartDate.getYear
            println("only start")
              year + " " + quarter

          } else if(isEmpty(startDate) == true) {
            val due = LocalDateTime.parse(dueDate, formatter)

            val incomingTZ = ZoneId.of(timeZone)
            val incomingDue = due.atZone(incomingTZ)

            val calculatedDueDate = incomingDue.withZoneSameInstant(calculatorTZ).toLocalDate

            val quarter = calculatedDueDate.get(IsoFields.QUARTER_OF_YEAR)
            val year = calculatedDueDate.getYear
            println("only due")

            year + " " + quarter
          } else {
            val start = LocalDateTime.parse(startDate, formatter)
            val due = LocalDateTime.parse(dueDate, formatter)

            val incomingTZ = ZoneId.of(timeZone)
            val incomingStart = start.atZone(incomingTZ)
            val incomingDue = due.atZone(incomingTZ)

            val calculatedStartDate = incomingStart.withZoneSameInstant(calculatorTZ).toLocalDate
            val calculatedDueDate = incomingDue.withZoneSameInstant(calculatorTZ).toLocalDate

            val startQuarter = calculatedStartDate.get(IsoFields.QUARTER_OF_YEAR)
            val startYear = calculatedStartDate.getYear
            val dueQuarter = calculatedDueDate.get(IsoFields.QUARTER_OF_YEAR)
            val dueYear = calculatedDueDate.getYear
            println("both")
            startYear + " " + startQuarter + " vs " + dueYear + " " + dueQuarter
          }
      } catch {
            case e: java.time.zone.ZoneRulesException => {
              println("no timeZone info")
              null
            }
          }
       }
  def checkQuarter: (String,String,String) => String = quarterlyFilter
  val getQuarterInfo = udf(checkQuarter)

}

When I run this with the following test data:

val startDate = "null"
val currentDate = "2018-09-30 21:59:59"
val timeZone = "Europe/Copenhagen"

someObject.quarterlyFilter(startDate, currentDate, timeZone)

I get this error, even though that parsing shouldn't even be reached..

java.time.format.DateTimeParseException

Can you help me making this function better, and simpler? Thanks in advance!

Aucun commentaire:

Enregistrer un commentaire