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

Posted

技术标签:

【中文标题】在给定的字符串日期中获取该月的最后一天【英文标题】:Getting last day of the month in a given string date 【发布时间】:2012-11-17 10:44:22 【问题描述】:

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

String date = "1/13/2012";

我得到的月份如下:

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

但是如何在给定的字符串日期中获取该月的最后一个日历日?

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

【问题讨论】:

仅供参考,java.util.DateSimpleDateFormat 类现在是遗留的,被 java.time 类所取代。有关使用 LocalDate 和其他现代日期时间类的示例,请参阅诸如 the one by Zeeshan 和 the one by Krishna 之类的答案。 或this。 【参考方案1】:

Java 8 及更高版本。

通过使用convertedDate.getMonth().length(convertedDate.isLeapYear()),其中convertedDateLocalDate 的一个实例。

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 及以下。

通过使用java.util.CalendargetActualMaximum方法:

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

【讨论】:

如何使用这个给定的“1/13/2012”? 在日历上致电setTime 在***.com/a/40689365/466862 中建议的使用TemporalAdjusters.lastDayOfMonth() 的Java 8 解决方案更简单。【参考方案2】:

这看起来像您的需求:

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  

【讨论】:

仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle。【参考方案3】:

通过使用 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() 我现在明白了。是否也添加一些讨论或解释以做出更好的答案?例如,提到TemporalAdjuster 接口和TemporalAdjusters 类的实现。 Stack Overflow 不仅仅是一个 sn-p 库。并且,感谢您的贡献。【参考方案4】:

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

【讨论】:

确实信息量很大,或者也可以使用以下代码找到一个月中的最大天数。 LocalDate.now().getMonth().maxLength() 另一个变体是YearMonth 类。 LocalDate endOfMonth = YearMonth.from( myLocalDate ).atEndOfMonth() ; 这个date.withDayOfMonth(date.getMonth().maxLength()) 将在二月份失败。解决方案见accepted and updated answer。 @AleksandrM 感谢您指出这一点。我已经根据您的提示更新了我的答案。【参考方案5】:

tl;博士

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.

看到这个code run live at IdeOne.com。

2012-01-31

YearMonth

YearMonth 类使这很容易。 atEndOfMonth 方法返回 LocalDate。闰年 2 月计算在内。

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

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

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

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

然后提取一个YearMonth 对象。

YearMonth ym = YearMonth.from( ld ) ;

YearMonth 确定当年该月的最后一天,占2 月的Leap Year。

LocalDate endOfMonth = ym.atEndOfMonth() ;

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

String output = endOfMonth.toString() ;  

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

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

从哪里获得 java.time 类?

Java SE 8Java SE 9Java SE 10Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。 Java 9 添加了一些小功能和修复。 Java SE 6Java SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android java.time 类的 android 捆绑包实现的更高版本。 对于早期的 Android (ThreeTenABP 项目适应 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。

【讨论】:

这里只是一个细节,与LocalDate.with相比,它需要从LocalDate实例化一个YearMonth,然后在月底重建LocalDate,所以它会再创建一个实例。 @AxelH 我不明白你的评论。所有 java.time 类都使用immutable objects,作为其线程安全设计的一部分并充当值对象。 LocalDate::with 总是提供一个新的实例,就像LocalDate::plusLocalDate::minus 等等。此外,使用现代 JVM,无需羞于创建对象。 只计算创建的实例数即可获得最后一天。使用LocalDate.with 只需要一个新实例,使用您的解决方案需要更多,使用YearMonth。这只是一个细节。【参考方案6】:

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

【讨论】:

问题需要解析一个字符串。你没有在这里解决这个问题。 这段代码可以使用YearMonth::lengthOfMonth进行简化 按照约定,Java 变量的首字母小写。【参考方案7】:

最简单的方法是构造一个新的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 的,例如一月为 0。

【讨论】:

【参考方案8】:

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

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;
    

【讨论】:

【参考方案9】:
            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 中测试。 我希望这会对某人有所帮助。

【讨论】:

【参考方案10】:

我认为最简单最快的方法是

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;
    

因为这些值是普遍不变的!

【讨论】:

不推荐。 (1) 不要使用Calendar,这是一个早已过时且设计混乱的类。 (2) 不要实现自己的日期逻辑。它容易出错,最好留给标准库,在这种情况下留给LocalDateYearMonth 类。你的代码也不正确。【参考方案11】:

使用GregorianCalendar。设置对象的日期,然后使用getActualMaximum(Calendar.DAY_IN_MONTH)

http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#getActualMaximum%28int%29(但在 Java 1.4 中是一样的)

【讨论】:

如何使用这个给定的“1/13/2012”?【参考方案12】:
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 年 3 月 31 日 月底最后一天:2017 年 4 月 30 日 月底最后一天:2017 年 5 月 31 日 月底最后一天:2017 年 6 月 30 日 月底最后一天:2017-07-31 月底最后一天:2017-08-31 月底最后一天:2017 年 9 月 30 日 月底最后一天:2017 年 10 月 31 日 月底最后一天:2017 年 11 月 30 日 月底最后一天:2017 年 12 月 31 日 月底最后一天:2018-01-31 月底最后一天:2018-02-28 月底最后一天:2018-03-31 月底最后一天:2010-02-28 月底最后一天:2011-02-28 月底最后一天:2012-02-29 月底最后一天:2013 年 2 月 28 日 月底最后一天:2014 年 2 月 28 日 月底最后一天:2015 年 2 月 28 日 月底最后一天:2016 年 2 月 29 日 月底最后一天:2017 年 2 月 28 日 月底最后一天:2018 年 2 月 28 日 月底最后一天:2019 年 2 月 28 日 月底最后一天:2020 年 2 月 29 日 每月最后一天:2021-02-28

【讨论】:

这段代码使用了多年来遗留下来的麻烦的旧日期时间类,被 java.time 类所取代。这个答案是不明智的。【参考方案13】:

您可以在 Java 8 中使用 plusMonths 和 minusDays 方法:

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

【讨论】:

existing similar Answer 比这个简单。 @BasilBourque 我并不认为这更简单。我声称它是不同的。【参考方案14】:

最后我发现解决方案已经过测试并且有效

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:2021 年 5 月 31 日

【讨论】:

请不要教年轻人使用早已过时且臭名昭著的麻烦SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中做得更好。 这也是 37 行代码,而其他一些答案有 3 到 10 行代码,您没有解释我们可能从您的较长代码中获得的任何东西。 那么您对这个问题的新的和智能的更新答案在哪里? 更新、现代和智能的答案是here、here、here、here 和here。加上接受的答案。我不需要重复他们已经说过的话。 (我对类似问题的回答是here,但不是同一个问题。)【参考方案15】:

这个对我来说很好用

    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 类所取代。请参阅correct Answer by Sheehan 及其评论。【参考方案16】:

我在我的 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,得到那个月的第一天,减去一天。

【讨论】:

以上是关于在给定的字符串日期中获取该月的最后一天的主要内容,如果未能解决你的问题,请参考以下文章

如何从此字符串'opimus_rise_issue_command_201912.txt'中提取该月的最后一天日期

如何使用 Python 仅查找包含该月最后一天的日期的文件?

返回该月的最后一天

SQL Server 2005获取任何年份中任何月份的第一个和最后一个日期

如何在Bash脚本中获取上个月的第一个和最后一个日期?

asp.net后台获得本月第一天和最后一天