Dates and times in Scala
Working with dates is a key component of working with data but how do you work with them in Scala?
If you try use a date in Scala it will end up being a string-type similar to any other string.
val dateString = "2021-08-20"
>> dateString: String = 2021-08-20val otherString = "Hello World"
>> otherString: String = Hello World
Scala has no native date-time libraries but because it’s a JVM based language Java libraries can be used in Scala. This article has succinct comparison between to Scala and Java.
Therefore, to use dates as a scalar in Scala there are 5 basic steps:
1) Choose the date library you want
2) Tell Java the format of your dates
3) Parse string into a date
4) Manipulate as you wish
5) Convert back to string or integer (optional)
1) Choose the date library you want
If Scala can access Java libraries, which ones are we going to use? And the answer to that is, as always, it depends.
Let’s you have a date and time like this:
“2021–08–20 16:09:38”
Then you need to
import java.time.LocalDateTime
If you have just a date
“2021–08–20”
Then you need to use
import java.time.LocalDate
2) Tell Java the format of your dates
Dates (and times) are displayed in various forms and like any good coding language, Java is not going to assume which one you’re using. For this you will need the DateTimeFormatter library
import java.time.format.DateTimeFormatterval dateTimeString = "2020-08-20 05:22:45"
val formatterDateTime = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")val dateString = "2020/08/20"
val formatterDate = DateTimeFormatter.ofPattern("yyyy/MM/dd")val dateString2 = "20 Aug 21"
val formatterDate2 = DateTimeFormatter.ofPattern("dd MMM yy")
3) Parse string into a date
Now you have a string and formatter you need to transform it into a date that can be manipulated.
val dateTimeStringDate = LocalDateTime.parse(dateTimeString, formatterDateTime)
>> dateTimeStringDate: java.time.LocalDateTime = 2020-08-20T05:22:45val dateStringDate = LocalDate.parse(dateString, formatterDate)
>> dateStringDate: java.time.LocalDate = 2020-08-20val dateStringDate2 = LocalDate.parse(dateString2, formatterDate2)
>> dateStringDate2: java.time.LocalDate = 2021-08-20
A important point with the DateFormatter is how you define the date formatter especially when differentiating between months (capital M) and minutes (lower case m) as if you get it wrong, you’ll most likely get an error.
val dateStringDate = LocalDate.parse(dateString,
DateTimeFormatter.ofPattern(“yyyy/mm/dd”)) //Notice lower case 'm'>>java.time.format.DateTimeParseException: Text '2020/08/20' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {Year=2020, DayOfMonth=20, MinuteOfHour=8},ISO of type java.time.format.Parsed
4) Manipulate as you wish
The Java LocalDate and LocalDateTime have various way to manipulate, you can see the full list here (LocalDate) and here (LocalDateTime)
val dateTimeNextHour = dateTimeStringDate.plusHours(8)
>> dateTimeNextHour: java.time.LocalDateTime = 2020-08-20T13:22:45val dateTimeGetDayWeek = dateTimeStringDate.getDayOfWeek()
>> dateTimeGetDayWeek: java.time.DayOfWeek = THURSDAYval dateNextMonth = dateStringDate.plusMonths(1)
>> dateNextMonth: java.time.LocalDate = 2020-09-20val date3PrevWeek = dateStringDate.minusWeek(3)
>> date3PrevWeek: java.time.LocalDate = 2020-07-30
5) Convert back to string or integer (optional)
The last, optional, step is to convert this back to a string or integer to use in further processing. Maybe you want this to be a filter condition for a dataframe or for it to form part of a path for importing. Either way you’ll need a string or integer and not a Date type.
val dateNextMonthString = dateNextMonth.toString()
>> dateNextMonthString: String = 2020-09-20val date3PrevWeekMonthInt = date3PrevWeek.getMonthValue()
>> date3PrevWeekMonthInt: Int = 7
Days of the week are a bit more complicated
import java.util.Localeimport java.time.format.TextStyle;val doWInt = dateTimeGetDayWeek.getValue()
>> doWInt: Int = 4val dowString = dateTimeGetDayWeek. getDisplayName (TextStyle.FULL, Locale.getDefault())
>> dowString: String = Thursday
Hope you’ve found this helpful :)