【问题标题】:Java current date minus 3 months and start from month begining [closed]Java 当前日期减去 3 个月并从月初开始 [关闭]
【发布时间】:2018-03-13 12:56:18
【问题描述】:

我需要获取一个季度的统计数据。

示例:今天是 2018 年 2 月 10 日th,我需要检索 2017 年 12 月的数据,从 1st 到 31st,然后从 2018 年 1 月,从 1st 到 30th 以及从 2 月 1st 到当前日期。

如何使用 Java Date 实现这一点?

【问题讨论】:

标签: java date date-manipulation


【解决方案1】:

tl;博士

YearMonth.now().minusMonths( 1 ).atEndOfMonth()  // or .atDay( 1 )

详情

获取今天的日期。

ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
LocalDate today = LocalDate.now( z ) ;

获取该日期的year-month

YearMonth ymCurrent = YearMonth.from( today ) ; 

ThreeTen-Extra 库添加到您的项目以访问LocalDateRange 类。此类将一对LocalDate 对象(开始日期和结束日期)表示为一个对象,日期范围从一个日期到另一个日期。

LocalDateRange rangeCurrent = LocalDateRange.ofClosed( ymCurrent.atDay( 1 ) , today ) ;

移到上个月。

YearMonth ymPrevious = ymCurrent.minusMonths( 1 ) ;
LocalDateRange rangePrevious = LocalDateRange.ofClosed( ymPrevious.atDay( 1 ) , ymPrevious.atEndOfMonth() ) ;

第三个月再减去一次。

提示:考虑使用半开方法来定义时间跨度,其中开始是包含,而结束是不包含。因此,一个月从当月的第一天开始,一直持续到但不包括下个月的第一天。

有关使用 java.time 类的另一种有效方法,请参阅the Answer by diston


关于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 类?

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

【讨论】:

    【解决方案2】:

    试试这样的:

    // Get current date
    Calendar start;
    start = Calendar.getInstance();
    
    // Go to beginning of month
    start.set(Calendar.DAY_OF_MONTH, 1);
    start.set(Calendar.HOUR_OF_DAY, 0);
    start.set(Calendar.MINUTE, 0);
    start.set(Calendar.SECOND, 0);
    start.set(Calendar.MILLISECOND, 0);
    
    // Go 2 months back
    my_date.add(Calendar.MONTH, -2);
    
    // Get end of same month
    Calendar end;
    end = start.clone();
    end.add(Calendar.MONTH, 1);
    end.add(Calendar.DAY_OF_MONTH, -1);
    

    然后,在其他月份做类似的事情

    【讨论】:

    • 仅供参考,麻烦的 Calendar 类已被遗留多年,取而代之的是 Java 8 及更高版本中内置的 java.time 类。
    【解决方案3】:

    您可以使用Java 8's java.time 类(或threeten backport 用于Java

    如果您只使用日/月/年而不关心小时和时区,最好使用LocalDate。创建特定日期很容易:

    // February 10th 2018
    LocalDate current = LocalDate.of(2018, 2, 10);
    

    或者您可以致电LocalDate.now() 获取当前日期。

    然后,要到 2017 年 12 月 1 日st,您必须减去 2 个月(2 月之前的 2 个月是 12 月)并将日期设置为 1:

    // start is December 1st 2017
    LocalDate start = current
        // 2 months ago = December
        .minusMonths(2)
        // change day of month to 1st
        .withDayOfMonth(1);
    

    然后您可以从 12 月 1 日st 循环到 2 月 10 日th

    LocalDate date = start;
    while (date.isBefore(current)) {
        // do whatever you need with the date
    
        // go to the next day
        date = date.plusDays(1);
    }
    

    注意plusDays返回的是一个新对象,所以我必须把它赋值给同一个变量,否则它不会被改变。

    我还使用了isBefore,它不包括循环中的当前日期 - 它将在 2 月 9 日th 停止。如果您想包含 2 月 10 日th,请将条件更改为 if (! date.isAfter(current))

    【讨论】:

    • 提示:java.time.YearMonth 类使这项工作更简单,并使代码更清楚地表明我们的意图。有关示例用法,请参阅我的答案。
    • @BasilBourque 在这种情况下,我认为代码有点等价,我看不出current.minusMonths(2).withDayOfMonth(1)YearMonth.from(current).minusMonths(2).atDay(1) 之间有太大区别——只是两种不同的方式来做同样的事情,IMO。
    • 为什么要投反对票?我会认为与它一起发表评论是一种很好的风格?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多