Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the exact first date and time of last month?

Tags:

java

datetime

I wish to get the exact date of first day of last month at 00:00:00Z.
So, here is my current solution:

public static String getStartingDateAndTimeOfLastMonth() {
    int dayOfCurrentMonth = ZonedDateTime.now().getDayOfMonth();
    return ZonedDateTime.now()
                        .minusDays(dayOfCurrentMonth - 1)
                        .minusMonths(1)
                        .format(DateTimeFormatter.ISO_INSTANT);
}

When i call the moethod:

String startDate = CustomUtilsFunctions.getStartingDateAndTimeOfLastMonth();
System.out.println("startDate: " + startDate);

The output of current solution is:

startDate: 2021-05-01T07:22:10.389Z

As you can see, the time of the output is 07:22:10.389Z but, I don't know the easiest way to turn it to 00:00:00:000Z

So the desired output for is:

startDate: 2021-05-01T00:00:00.000Z

Point: I know, i can extract the hour, minutes and seconds and millis and then use the minus(), but I believe there must be an easier solution.

like image 648
Jeff Avatar asked Jun 10 '21 07:06

Jeff


People also ask

How do I find the first and last date of the current month?

To get the first and last day of the current month, use the getFullYear() and getMonth() methods to get the current year and month and pass them to the Date() constructor to get an object representing the two dates. Copied! const now = new Date(); const firstDay = new Date(now.

How do I get the first and last date of a month in Excel?

EOMONTH returns the last day of a month from a date. Here, we use the EOMONTH function to go to the last day of the previous month. Then, we add 1 to get the first day of the current month. To perform the previous example with the EOMONTH function, we need to use the formula =EOMONTH(A2,-1)+1 in cell B2.


Video Answer


2 Answers

Instead of using today as base, you could use a java.time.YearMonth (like this month) and subtract one month to get the last one. Then take the start of its first day. Do all that in UTC and then format as desired:

public static String getStartingDateAndTimeOfLastMonth() {
    // get the current month and subtract one to get the last
    YearMonth lastMonth = YearMonth.now().minusMonths(1);
    // then return its first day
    return lastMonth.atDay(1)                
                    // at the beginning of the day in UTC
                    .atStartOfDay(ZoneOffset.UTC)
                    // formatted as desired
                    .format(
                        DateTimeFormatter.ofPattern(
                            "uuuu-MM-dd'T'HH:mm:ss.SSSX",
                            Locale.ENGLISH
                        )
                    );
}

This outputs today (10th of June, 2021):

2021-05-01T00:00:00.000Z

Note: The default format of ZonedDateTime omits seconds and fraction-of-second if they are zero.
If you are fine with 2021-05-01T00:00Z, you can replace

    .format(
        DateTimeFormatter.ofPattern(
            "uuuu-MM-dd'T'HH:mm:ss.SSSX",
            Locale.ENGLISH
        )
    );

with simply .toString();.

like image 89
deHaar Avatar answered Nov 14 '22 22:11

deHaar


You could first create the desired day and then use it together with a set time to compose DateTime. Depending on your use case, you could use LocalDateTime or ZonedDateTime.

LocalDate day = LocalDate.now()
        .minusMonths(1)
        .withDayOfMonth(1);

ZonedDateTime target = ZonedDateTime.of(day, LocalTime.MIDNIGHT, ZoneId.systemDefault());

System.out.println(target);

Another option would be to use turncatedTo (as @Thomas mentioned in comment)

ZonedDateTime target = ZonedDateTime.now()
        .minusMonths(1)
        .withDayOfMonth(1)
        .truncatedTo(ChronoUnit.DAYS)
        .withZoneSameLocal(ZoneId.of("UTC")); // optional depending on your case
like image 24
Marcin Kunert Avatar answered Nov 14 '22 21:11

Marcin Kunert