0

this is my first question on stack overflow. I have a date as input and output should be last date of the month that falls in.

for example

Input string "01/15/2023" should output "01/31/2023" or "02/10/2021" should output "02/28/2021" 0r

"02/10/2024" should output "02/29/2024" (Incase of leap year) etc all such rules applicable.

I have tried below code through online search of a java , but I am getting error which I am not able to figure it out, please do help me out.

val endDate: ZonedDateTime = ZonedDateTime.parse("2023-01-15")
       println("1A. Last day of the current month: "+endDate.toLocalDateTime().with(TemporalAdjusters.lastDayOfMonth())

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Gopichand
  • 1
  • 2
  • 2
    https://stackoverflow.com/questions/9397203/last-day-of-month-calculation https://stackoverflow.com/questions/13624442/getting-last-day-of-the-month-in-a-given-string-date https://stackoverflow.com/questions/19488658/get-last-day-of-month https://stackoverflow.com/questions/41697143/how-to-get-last-day-of-the-month-for-the-given-date https://stackoverflow.com/questions/34076518/calendar-get-last-day-of-previous-month – Dmytro Mitin Jan 25 '23 at 06:47
  • Your idea is right. Use `LocalDate` for a date. A `ZonedDateTime` would have required that you have got time of day and time zone, so is the wrong class here. Other than that your code should work. – Ole V.V. Jan 25 '23 at 07:16

2 Answers2

2

Trying to parse dates in a ZonedDateTime will not work like that because you are lacking the time zone information. I will use a LocalDate, which more closely models the input, and leave the conversion from LocalDate to ZonedDateTime as a separate problem.

Regardless, you can use the with method on both types and pass java.time.TemporalAdjusters.lastDayOfMonth as in the following example:

import java.time.temporal.TemporalAdjusters

def t(date: String): java.time.LocalDate =
    java.time.LocalDate.parse(date, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"))

val tests = Map(
  t("2023-01-15") -> t("2023-01-31"),
  t("2023-09-15") -> t("2023-09-30"),
  t("2024-02-14") -> t("2024-02-29"),
  t("2023-02-14") -> t("2023-02-28"),
)

for ((input, expected) <- tests) {
  val actual = input.`with`(TemporalAdjusters.lastDayOfMonth())
  assert(actual == expected, s"$actual did not equal $expected for input $input")
}

Notice I had to put the call to with between backticks because with is also a keyword in Scala.

You can play around with this code here on Scastie.

You can read more about with here on its JavaDoc, which also points to how to use it together with TemporalAdjusters.

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
0
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters

val formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")

val date = LocalDate.parse("02/10/2021", formatter)

val endDate = date.`with`(TemporalAdjusters.lastDayOfMonth())

println(s"last date of month = ${endDate.format(formatter)}")
sarveshseri
  • 13,738
  • 28
  • 47