0

Could someone please help me in finding from datepicker first and last day of previous month. Achieved to pickup current date and 1st of current month, with following:

// Choose today's date
    String today =  LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM-YYYY"));
    driver.findElement(By.xpath("//*[@id=\"viewPeriodStart\"]")).clear();
    driver.findElement(By.xpath("//*[@id=\"viewPeriodStart\"]")).sendKeys(today);
    //Choose first of a month
    String firstDayinMOnth = LocalDate.now().format(DateTimeFormatter.ofPattern("01/MM-YYYY"));
    driver.findElement(By.xpath("//*[@id=\"viewPeriodEnd\"]")).clear();
    driver.findElement(By.xpath("//*[@id=\"viewPeriodEnd\"]")).sendKeys(firstDayinMOnth + Keys.ENTER);
    Thread.sleep(8000);
    driver.findElement(By.xpath("//*[@id=\"calenderShowHide\"]/div/input[3]")).click();

But have no idea how to create 1st and last of previous month. Thank you in advance

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Zoran
  • 491
  • 7
  • 22
  • Possible duplicate of [How to get the first date and last date of the previous month? (Java)](https://stackoverflow.com/questions/10828398/how-to-get-the-first-date-and-last-date-of-the-previous-month-java). I know the first answer uses the long outdated `Calendar` class (discouraged), but [this answer](https://stackoverflow.com/a/25601193/5772882) uses `java.time` like you do. – Ole V.V. Feb 07 '18 at 09:52
  • You don’t want uppercase `YYYY` in your format pattern string. It’s for week-based year, only useful with week numbers. Instead use either lowercase `yyyy`or `uuuu`. – Ole V.V. Feb 07 '18 at 09:55

2 Answers2

2

Solved, after a bit of Googling & checking:

String lastDay = LocalDate.now().withDayOfMonth(1).minusDays(1).format(DateTimeFormatter.ofPattern("dd/MM-YYYY"));
String firstDay = LocalDate.now().withDayOfMonth(1).minusDays(1).withDayOfMonth(1).format(DateTimeFormatter.ofPattern("dd/MM-YYYY"));
Zoran
  • 491
  • 7
  • 22
  • Glad you solved it. It can be done a bit simpler and in a more natural way, see the linked question. – Ole V.V. Feb 07 '18 at 09:56
1

These points were not what you asked, but I believe they are still helpful suggestions for you.

  1. Consider half-open intervals.
  2. Read LocalDate.now() only once for consistency.
  3. Give your desired time zone.
  4. Don’t use uppercase YYYY in your format pattern string.

Half-open: It’s natural to think of the days of a month as being from the first of the month to the last day of the month inclusive. However, a standard handling would go from the first of the month inclusive to the first of the next month exclusive. It’s still the same days, only a different representation. Particularly when you handle successive months this gives simplicity and prevents errors: when you have the first of this month, you don’t also need the last of the previous month. And there’s no way you could make a gap between the two periods by mistake.

Read today’s date only once. If your code happens to run across midnight, you may accept that you cannot control whether it uses the date from before 0:00 or the date after, but you want to make sure it doesn’t use both for the different date calculations, or you risk inconsistent dates, like all the dates belonging to the same month rather than last month and this month.

Give a time zone: It is never the same date in all time zones on Earth. So a time zone is needed for determining today’s date or just current month. Make that explicit. Even if you want ZoneId.systemDefault(), write that to force yourself into making a conscious decision and to tell the reader that you have done so.

    LocalDate today = LocalDate.now(ZoneId.of("Europe/Belgrade"));
    LocalDate firstDayOfCurrentMonth = today.withDayOfMonth(1);
    LocalDate lastDayOfCurrentMonth = today.with(TemporalAdjusters.lastDayOfMonth());
    YearMonth lastMonth = YearMonth.of(today.getYear(), today.getMonth())
                            .minusMonths(1);
    LocalDate firstDayOfLastMonth = lastMonth.atDay(1);
    LocalDate lastDayOfLastMonth = lastMonth.atEndOfMonth();

A YearMonth is a month in the calendar like April 1940 or February 2018. A year and a month. I am deliberately being a bit inconsistent in the code. In production code you would probably want to handle either this and last month through YearMonth objects or none of them. But I am showing you both options so you can make your pick. Use YearMonth.now(ZoneId) if you want current month.

Final point: YYYY in the format pattern string. Here’s a correct version of your formatter:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM-uuuu");

If instead of today I run my code next January and use a formatter with uppercase YYYY, I get the previous month as 01/12-2018 through 31/12-2019. It should have been 31/12-2018, but that date belongs to week 1 of 2019, which is what YYYY gives you. Instead use uuuu or lowercase yyyy.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161