Getting last day of the month in a given string date
Asked Answered
T

17

81

My input string date is as below:

String date = "1/13/2012";

I am getting the month as below:

SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date convertedDate = dateFormat.parse(date);
String month = new SimpleDateFormat("MM").format(convertedDate);

But how do I get the last calendar day of the month in a given String date?

E.g.: for a String "1/13/2012" the output must be "1/31/2012".

Tsuda answered 29/11, 2012 at 11:10 Comment(2)
FYI, the java.util.Date and SimpleDateFormat classes are now legacy, supplanted by the java.time classes. See Answers such as the one by Zeeshan and the one by Krishna for examples of using LocalDate and other modern date-time classes.Darindaring
Or this.Deputation
D
201

Java 8 and above.

By using convertedDate.getMonth().length(convertedDate.isLeapYear()) where convertedDate is an instance of LocalDate.

String date = "1/13/2012";
LocalDate convertedDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("M/d/yyyy"));
convertedDate = convertedDate.withDayOfMonth(
                                convertedDate.getMonth().length(convertedDate.isLeapYear()));

Java 7 and below.

By using getActualMaximum method of java.util.Calendar:

String date = "1/13/2012";
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date convertedDate = dateFormat.parse(date);
Calendar c = Calendar.getInstance();
c.setTime(convertedDate);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
Deputation answered 29/11, 2012 at 11:13 Comment(3)
How to use this given "1/13/2012"?Tsuda
Call setTime on Calendar.Deputation
The solution for Java 8 using TemporalAdjusters.lastDayOfMonth() suggested in https://mcmap.net/q/258006/-getting-last-day-of-the-month-in-a-given-string-date is simpler.Insulation
H
32

This looks like your needs:

http://obscuredclarity.blogspot.de/2010/08/get-last-day-of-month-date-object-in.html

code:

import java.text.DateFormat;  
import java.text.DateFormat;  
import java.text.SimpleDateFormat;  
import java.util.Calendar;  
import java.util.Date;  

//Java 1.4+ Compatible  
//  
// The following example code demonstrates how to get  
// a Date object representing the last day of the month  
// relative to a given Date object.  

public class GetLastDayOfMonth {  

    public static void main(String[] args) {  

        Date today = new Date();  

        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(today);  

        calendar.add(Calendar.MONTH, 1);  
        calendar.set(Calendar.DAY_OF_MONTH, 1);  
        calendar.add(Calendar.DATE, -1);  

        Date lastDayOfMonth = calendar.getTime();  

        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
        System.out.println("Today            : " + sdf.format(today));  
        System.out.println("Last Day of Month: " + sdf.format(lastDayOfMonth));  
    }  

} 

Output:

Today            : 2010-08-03  
Last Day of Month: 2010-08-31  
Hoofbound answered 29/11, 2012 at 11:16 Comment(3)
FYI, the terribly troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes built into Java 8 and later. See Tutorial by Oracle.Darindaring
what is that calendar.add(Calendar.DATE, -1); ?Bastion
@Bastion It’s one of very many peculiarities with the outdated Calendar class that caused that class to be abandoned nearly 10 years ago now. As the other comment suggests, forget about that class and use java..time instead.Catenane
G
29

By using java 8 java.time.LocalDate

String date = "1/13/2012";
LocalDate lastDayOfMonth = LocalDate.parse(date, DateTimeFormatter.ofPattern("M/dd/yyyy"))
       .with(TemporalAdjusters.lastDayOfMonth());
Guttering answered 19/11, 2016 at 4:56 Comment(2)
Actually I used TemporalAdjusters.lastDayOfMonth()Guttering
I see now. How about adding some discussion or explanation too to make a better Answer? For example, mention the TemporalAdjuster interface and the TemporalAdjusters class for implementations. Stack Overflow is intended to be more than a snippet-library. And, thanks for contributing.Darindaring
D
13

tl;dr

YearMonth                            // Represent the year and month, without a date and without a time zone.
.from(                               // Extract the year and month from a `LocalDate` (a year-month-day). 
    LocalDate                        // Represent a date without a time-of-day and without a time zone.
    .parse(                          // Get a date from an input string.        
        "1/13/2012" ,                // Poor choice of format for a date. Educate the source of your data about the standard ISO 8601 formats to be used when exchanging date-time values as text.
        DateTimeFormatter            // Specify a formatting pattern by which to parse the input string.
        .ofPattern( "M/d/uuuu" )     // Match the pattern of your input.
    )                                // Returns a `LocalDate` object.
)                                    // Returns a `YearMonth` object.
.atEndOfMonth()                      // Determines the last day of the month for that particular year-month, and returns a `LocalDate` object.
.toString()                          // Generate text representing the value of that `LocalDate` object using standard ISO 8601 format.

See this code run live at IdeOne.com.

2012-01-31

YearMonth

The YearMonth class makes this easy. The atEndOfMonth method returns a LocalDate. Leap year in February is accounted for.

First define a formatting pattern to match your string input.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu" ) ;

Use that formatter to get a LocalDate from the string input.

String s = "1/13/2012" ;
LocalDate ld = LocalDate.parse( "1/13/2012" , f ) ;

Then extract a YearMonth object.

YearMonth ym = YearMonth.from( ld ) ;

Ask that YearMonth to determine the last day of its month in that year, accounting for Leap Year in February.

LocalDate endOfMonth = ym.atEndOfMonth() ;

Generate text representing that date, in standard ISO 8601 format.

String output = endOfMonth.toString() ;  

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Darindaring answered 7/1, 2019 at 19:24 Comment(3)
Just a detail here, compared to LocalDate.with, it requires to instantiate a YearMonth from the LocalDate then rebuild the LocalDate at the end of the month, so it create one more instance.Geosynclinal
@Geosynclinal I don’t understand your comment. All of the java.time classes use immutable objects, as part of their design to be thread-safe and to act as value objects. LocalDate::with always provides a new instance, just like LocalDate::plus, LocalDate::minus, and so on. Also, with modern JVMs, there is no need to be shy about creating objects.Darindaring
Just count the number of instance created to get the last day. Using LocalDate.with only requires one new instance, using your solution requires on more, the YearMonth used. It is just a detail.Geosynclinal
C
10

Java 8 and above:

import java.time.LocalDate;
import java.time.Year;

static int lastDayOfMonth(int Y, int M) {
    return LocalDate.of(Y, M, 1).getMonth().length(Year.of(Y).isLeap());
}

subject to Basil Bourque's comment

import java.time.YearMonth;

int lastDayOfMonth = YearMonth.of(Y, M).lengthOfMonth();
Catamnesis answered 7/1, 2019 at 12:33 Comment(3)
The Question requires parsing a string. You did not address that here.Darindaring
This code could be simplified by using YearMonth::lengthOfMonthDarindaring
By convention, Java variables are named with first letter being lowercase.Darindaring
D
7

With Java 8 DateTime / LocalDateTime :

String dateString = "01/13/2012";
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.US); 
LocalDate date = LocalDate.parse(dateString, dateFormat);       
ValueRange range = date.range(ChronoField.DAY_OF_MONTH);
Long max = range.getMaximum();
LocalDate newDate = date.withDayOfMonth(max.intValue());
System.out.println(newDate); 

OR

String dateString = "01/13/2012";
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.US); 
LocalDate date = LocalDate.parse(dateString, dateFormat);
LocalDate newDate = date.withDayOfMonth(date.getMonth().length(date.isLeapYear()));
System.out.println(newDate);

Output:

2012-01-31

LocalDateTime should be used instead of LocalDate if you have time information in your date string . I.E. 2015/07/22 16:49

Declarer answered 30/7, 2015 at 9:39 Comment(4)
Indeed very informative, alternatively finding the maximum day of the month can also be done using the following code. LocalDate.now().getMonth().maxLength()Hydrated
Another variation is the YearMonth class. LocalDate endOfMonth = YearMonth.from( myLocalDate ).atEndOfMonth() ;Darindaring
This date.withDayOfMonth(date.getMonth().maxLength()) will fail for February. See accepted and updated answer for solution.Deputation
@AleksandrM Thanks for pointing this out. I have updated my answer taking hint from your's.Declarer
S
3

The simplest way is to construt a new GregorianCalendar instance, see below:

Calendar cal = new GregorianCalendar(2013, 5, 0);
Date date = cal.getTime();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("Date : " + sdf.format(date));

Output:

Date : 2013-05-31

Attention:

month the value used to set the MONTH calendar field in the calendar. Month value is 0-based e.g. 0 for January.

Schwitzer answered 9/8, 2013 at 5:35 Comment(0)
C
1

You can use the following code to get last day of the month

public static String getLastDayOfTheMonth(String date) {
        String lastDayOfTheMonth = "";

        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
        try{
        java.util.Date dt= formatter.parse(date);
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dt);  

        calendar.add(Calendar.MONTH, 1);  
        calendar.set(Calendar.DAY_OF_MONTH, 1);  
        calendar.add(Calendar.DATE, -1);  

        java.util.Date lastDay = calendar.getTime();  

        lastDayOfTheMonth = formatter.format(lastDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return lastDayOfTheMonth;
    }
Clotildecloture answered 29/6, 2016 at 13:30 Comment(0)
P
1
            String givenStringDate ="07/16/2020";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        java.util.Date convertedUtillDate;
            /*
             * If your output requirement is in LocalDate format use below snippet
             * 
             */
            LocalDate localDate =LocalDate.parse(givenStringDate, formatter);
            LocalDate localDateLastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());

            /*
             * If your output requirement is in Calendar format use below snippet
             * 
             */
            convertedUtillDate = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Calendar calendarLastDayOfMonth = Calendar.getInstance();
            calendarLastDayOfMonth.setTime(convertedUtillDate);
            int lastDate = calendarLastDayOfMonth.getActualMaximum(Calendar.DATE);
            calendarLastDayOfMonth.set(Calendar.DATE, lastDate);

Tested in Java 1.8. I hope this will help some one.

Purdah answered 26/5, 2020 at 12:16 Comment(0)
S
1

I think the most simple and fastest way is

public static int getLastDayOf(int month, int year) {
    switch (month) {
        case Calendar.APRIL:
        case Calendar.JUNE:
        case Calendar.SEPTEMBER:
        case Calendar.NOVEMBER:
            return 30;
        case Calendar.FEBRUARY:
            if (year % 4 == 0) {
                return 29;
            }
            return 28;
        default:
            return 31;
    }
}

Since these values are constant universally!

Sacttler answered 12/6, 2021 at 4:52 Comment(1)
Not recommended. (1) Don’t use Calendar, it’s a long outdated and confusingly designed class. (2) Don’t implement your own date logic. It’s error-prone and much better left to the standard library, in this case to either the LocalDate or the YearMonth class. Also your code is not correct.Catenane
A
1

In the following code I am generating the current Date using the now method. And then I am using TemporalAdjusters to get the final date of the month. I can also pass a custom date to get the work done.

LocalDate localDate = LocalDate.now(ZoneId.systemDefault());
LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());
Adder answered 1/8, 2023 at 9:3 Comment(0)
S
0

You can make use of the plusMonths and minusDays methods in Java 8:

// Parse your date into a LocalDate
LocalDate parsed = LocalDate.parse("1/13/2012", DateTimeFormatter.ofPattern("M/d/yyyy"));

// We only care about its year and month, set the date to first date of that month
LocalDate localDate = LocalDate.of(parsed.getYear(), parsed.getMonth(), 1);

// Add one month, subtract one day 
System.out.println(localDate.plusMonths(1).minusDays(1)); // 2012-01-31
Sonorous answered 25/11, 2018 at 17:48 Comment(1)
The existing similar Answer is simpler than this.Darindaring
S
-1

Use GregorianCalendar. Set the date of the object, and then use getActualMaximum(Calendar.DAY_IN_MONTH).

http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#getActualMaximum%28int%29 (but it was the same in Java 1.4)

Storz answered 29/11, 2012 at 11:13 Comment(1)
How to use this given "1/13/2012"?Tsuda
M
-1
public static String getLastDayOfMonth(int year, int month) throws Exception{
    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    Date date = sdf.parse(year+"-"+(month<10?("0"+month):month)+"-01");

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);

    calendar.add(Calendar.MONTH, 1);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    calendar.add(Calendar.DATE, -1);

    Date lastDayOfMonth = calendar.getTime();

    return sdf.format(lastDayOfMonth);
}
public static void main(String[] args) throws Exception{
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 1));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 3));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 4));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 5));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 6));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 7));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 8));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 9));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 10));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 11));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 12));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2018, 1));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2018, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2018, 3));

    System.out.println("Last Day of Month: " + getLastDayOfMonth(2010, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2011, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2012, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2013, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2014, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2015, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2016, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2017, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2018, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2019, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2020, 2));
    System.out.println("Last Day of Month: " + getLastDayOfMonth(2021, 2));
}

output:

Last Day of Month: 2017-01-31
Last Day of Month: 2017-02-28
Last Day of Month: 2017-03-31
Last Day of Month: 2017-04-30
Last Day of Month: 2017-05-31
Last Day of Month: 2017-06-30
Last Day of Month: 2017-07-31
Last Day of Month: 2017-08-31
Last Day of Month: 2017-09-30
Last Day of Month: 2017-10-31
Last Day of Month: 2017-11-30
Last Day of Month: 2017-12-31
Last Day of Month: 2018-01-31
Last Day of Month: 2018-02-28
Last Day of Month: 2018-03-31
Last Day of Month: 2010-02-28
Last Day of Month: 2011-02-28
Last Day of Month: 2012-02-29
Last Day of Month: 2013-02-28
Last Day of Month: 2014-02-28
Last Day of Month: 2015-02-28
Last Day of Month: 2016-02-29
Last Day of Month: 2017-02-28
Last Day of Month: 2018-02-28
Last Day of Month: 2019-02-28
Last Day of Month: 2020-02-29
Last Day of Month: 2021-02-28

Mu answered 31/10, 2017 at 5:57 Comment(1)
This code uses troublesome old date-time classes that have been legacy for years, supplanted by the java.time classes. This Answer is ill-advised.Darindaring
B
-1

Finally I found the solution is Tested and works

public static Date toDate(String date, String DATE_FORMAT) {
    Date dt = null;
    try {
        String[] d = date.split(" ");
        String[] f = DATE_FORMAT.split(" ");
        if (d.length > 1) {
            if(f.length > 1) {
                DateFormat df = new SimpleDateFormat(DATE_FORMAT);
                df.setLenient(false);
                dt = df.parse(date);
            }
            else
            {
                DateFormat df = new SimpleDateFormat(f[0]);
                df.setLenient(false);
                dt = df.parse(date);
            }
        } else {
            DateFormat df = new SimpleDateFormat(f[0]);
            df.setLenient(false);
            dt = df.parse(date);
        }
        return dt;
    } catch (ParseException e) {

        return null;
    }
}

private SimpleDateFormat dateFormatter;
dateFormatter = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
String StartDate = "05/01/2021";
Calendar endDate = new GregorianCalendar();
Date convertedDate = toDate(StartDate, "MM/dd/yyyy");
endDate.setTime(convertedDate);
endDate.set(Calendar.DAY_OF_MONTH, 1);
endDate.add(Calendar.MONTH, 1);
endDate.add(Calendar.DATE, -1);
String EndDate = dateFormatter.format(endDate.getTime());

OutOut: 05/31/2021

Banebrudge answered 13/10, 2021 at 9:42 Comment(7)
Please don’t teach the young ones to use the long outdated and notoriously troublesome SimpleDateFormat class. At least not as the first option. And not without any reservation. We have so much better in java.time, the modern Java date and time API, and its DateTimeFormatter.Catenane
Also this is 37 lines of code where some of the other answers have 3 to 10 lines of code, and you are not explaining anything that we might gain from your longer code.Catenane
so where is your New and Smart updated answer to this question?Banebrudge
Updated, modern and smart answers are here, here, here, here and here. Plus the accepted answer. No need for me to repeat what they already say.Catenane
(My answer to a similar question is here, but not the same question.)Catenane
None of Answer by you... very funny... except last one amd i don see any solution here... so far i guess, people needs codes of solutions not Article... Don mind pls...Banebrudge
I preach the exact opposite. People who need code should not go to Stack Overflow. Stack Overflow is the place for people who want to learn (we all should, I do). And no one needs your 37 lines of code. It uses outdated classes, we don't know what it does, presumably something that has already been obtained in 10 good lines or lesd.Catenane
L
-2

Works fine for me with this

    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone());
    cal.set(Calendar.MONTH, month-1);  
    cal.set(Calendar.YEAR, year);  
    cal.add(Calendar.DATE, -1);  
    cal.set(Calendar.DAY_OF_MONTH, 
    cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal.getTimeInMillis();
Languishment answered 29/9, 2017 at 12:13 Comment(1)
FYI, the troublesome Calendar class is now legacy, supplanted by the java.time classes. See the correct Answer by Sheehan and its Comments.Darindaring
V
-3

I use this one-liner on my JasperServer Reports:

new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyy-MM-dd").parse(new java.util.Date().format('yyyy') + "-" + (new Integer (new SimpleDateFormat("MM").format(new Date()))+1) + "-01")-1)

Doesn't look nice but works for me. Basically it's adding 1 to the current month, get the first day of that month and subtract one day.

Vaca answered 27/2, 2015 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.