在给定的字符串日期中获取月份的最后一天


69

我的输入字符串日期如下:

String date = "1/13/2012";

我得到的月份如下:

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

但是,如何获取给定String日期中月份的最后一个日历日?

例如:对于字符串"1/13/2012",输出必须为"1/31/2012"


1
仅供参考,java.util.DateSimpleDateFormat类现在已被遗留,由java.time类取代。有关使用示例和其他现代日期时间类的信息,请参见答案,例如Zeeshan的答案和Krishna的答案LocalDate
罗勒·布尔克

1
还是这个
Aleksandr M'17年

Answers:


166

Java 8及更高版本。

通过使用convertedDate.getMonth().length(convertedDate.isLeapYear())whereconvertedDate是的实例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及更低版本。

通过使用以下getActualMaximum方法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));

如何使用给定的“ 2012年1月13日”?
Vicky,2012年

呼叫setTime日历。
Aleksandr M

2
stackoverflow.com/a/40689365/466862中TemporalAdjusters.lastDayOfMonth()建议的使用Java 8的解决方案更为简单。
Mark Rotteveel '19年

28

这看起来像您的需求:

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

码:

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));  
    }  

} 

输出:

Today            : 2010-08-03  
Last Day of Month: 2010-08-31  

1
仅供参考,非常麻烦旧日期,时间类,如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在的遗产,由取代java.time内置到Java 8和更高等级。请参见Oracle教程
罗勒·布尔克

13

通过使用Java 8 java.time.LocalDate

String date = "1/13/2012";
LocalDate lastDayOfMonth = LocalDate.parse(date, DateTimeFormatter.ofPattern("M/dd/yyyy"))
       .with(TemporalAdjusters.lastDayOfMonth());

实际上,我使用了TemporalAdjusters.lastDayOfMonth()
Gaurav Krishna

我现在明白了。如何也添加一些讨论或解释以做出更好的答案呢?例如,提及实现的TemporalAdjuster接口和TemporalAdjusters类。堆栈溢出的目的不只是一个片段库。并且,感谢您的贡献。
罗勒·布尔克

7

使用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); 

要么

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);

输出:

2012-01-31

LocalDateTime应该使用,而不是LocalDate如果日期字符串中包含时间信息。IE浏览器2015/07/22 16:49


2
确实非常有用,也可以使用以下代码来查找月份中的最大日期。 LocalDate.now().getMonth().maxLength()
哈里哈兰2015年

1
另一个变化是YearMonth类。LocalDate endOfMonth = YearMonth.from( myLocalDate ).atEndOfMonth() ;
罗勒·布尔克

date.withDayOfMonth(date.getMonth().maxLength())将在二月份失败。请参阅已接受和更新的答案以获取解决方案。
Aleksandr M

@AleksandrM感谢您指出这一点。我更新了我的答案,从您的提示中得到提示。
Zeeshan

5

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.ofPattern( "M/d/uuuu" )   // Specify a formatting pattern by which to parse the input string.
    )                                               // 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.

看到此代码在IdeOne.com上实时运行

2012-01-31

YearMonth

YearMonth班让一切变得简单。该atEndOfMonth方法返回一个LocalDate。February年二月占。

首先定义一个格式化模式以匹配您的字符串输入。

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

使用该格式化程序LocalDate从字符串输入中获取a 。

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

然后提取一个YearMonth对象。

YearMonth ym = YearMonth.from( ld ) ;

要求YearMonth确定该年中该月的最后一天,以2月为Year年。

LocalDate endOfMonth = ym.atEndOfMonth() ;

以标准ISO 8601格式生成表示该日期的文本。

String output = endOfMonth.toString() ;  

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,也不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


与相比LocalDate.with,这里只是一个细节,它需要从实例化一个实例YearMonthLocalDate然后LocalDate在月底重建,因此它又创建了一个实例。
AxelH,

@AxelH我不明白您的评论。所有java.time类都使用不可变对象,这是其设计的一部分,以确保线程安全并充当值对象。LocalDate::with总是提供一个新实例,就像LocalDate::plusLocalDate::minus等等。同样,对于现代JVM,也不必害羞于创建对象。
罗勒·布尔克

只需计算创建的实例数即可获得最后一天。使用LocalDate.with仅需要一个新实例,而使用您的解决方案则需要更多实例 YearMonth。这只是一个细节。
AxelH

5

Java 8及更高版本:

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());
}

以Basil Bourque的评论为准

import java.time.YearMonth;

int lastDayOfMonth = YearMonth.of(Y, M).lengthOfMonth();

问题需要解析一个字符串。您没有在这里解决。
罗勒·布尔克


按照约定,Java变量以首字母小写命名。
罗勒·布尔克

3

最简单的方法是构造一个新GregorianCalendar实例,请参见下文:

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));

输出:

Date : 2013-05-31

注意:

month用于设置日历中MONTH日历字段的值。月值从0开始,例如1月为0。


1

您可以使用以下代码获取每月的最后一天

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;
    }

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);

在Java 1.8中测试。我希望这会有所帮助。



-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));
}

输出:

一个月的最后一天:2017-01-31一个月的
最后一天:2017-02-28一个月的
最后一天:2017-03-31一个月的
最后一天:2017-04-30一个月的
最后一天:2017-05-31
一个月的最后一天:2017-06-30一个月的
最后一天:2017-07-31一个月的
最后一天:2017-08-31一个月的
最后一天:2017-09-30一个月的
最后一天:2017-10-31
一个月的最后一天:2017-11-30一个月的
最后一天:2017-12-31一个月的最后一天:2018-01-31
一个月的最后一天:2016-02-29一个月的 最后一天:2017-02-28一个月的 最后一天:2018-02-28一个月的最后一天:2019-02-28一个月的 最后一天:2020-02-29一个月的最后一天:2021-02-28
当月最后一天:2018年2月28日
当月最后一天:2018年3月31日
一个月的最后一天:2010-02-28一个月的
最后一天:2011-02-28一个月的
最后一天:2012-02-29一个月的
最后一天:2013-02-28
一个月的最后一天:2014-02-28一个月的
最后一天:2015-02-28一个月的







这段代码使用了麻烦的旧日期时间类,这些类已经被遗留了很多年,被java.time类取代。这个答案是不明智的。
罗勒·布尔克

-1

您可以在Java 8中使用plusMonthsminusDays方法:

// 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

1
现有的类似的答案是比这更简单。
罗勒·布尔克

@BasilBourque我不认为这比较简单。我声称这是不同的。
Koray Tugay

-2

为此我工作正常

    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();

仅供参考,麻烦的Calendar类现在已被遗留,由java.time类取代。请参阅Sheehan正确答案及其评论。
罗勒·布尔克

-3

我在JasperServer报告中使用了这种单行代码:

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)

看起来不太好,但对我有用。基本上是在当月加1,得到该月的第一天,然后减去一天。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.