如何在java.util.Date中获取当前季度的第一个日期和最后日期

Asa*_*aya 6 java date

我需要将当前季度第一个日期作为java.util.Date对象,并将当前季度最后日期作为java.util.Date对象.

我正在使用以下方法来获取本月的第一个日期和本月的最后一个日期.

private   Date getThisMonthFirstDate(){
    Calendar calendar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    return calendar.getTime();
}

private   Date getThisMonthLastDate(){
    Calendar calandar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.DAY_OF_MONTH,1);
    calendar.add(Calendar.MONTH, 1);
    calendar.add(Calendar.DATE, -1);
   return calendar.getTime();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法修改该功能来实现这一点,还是有人能指出更好的方法?

假设Q1 = 1月2月3月,Q2 = 4月,5月,6月等.

Pav*_*vel 14

纯Java-8 +解决方案:

LocalDate localDate = LocalDate.now();
LocalDate firstDayOfQuarter = localDate.with(localDate.getMonth().firstMonthOfQuarter())
    .with(TemporalAdjusters.firstDayOfMonth());

LocalDate lastDayOfQuarter = firstDayOfQuarter.plusMonths(2)
    .with(TemporalAdjusters.lastDayOfMonth());
Run Code Online (Sandbox Code Playgroud)

  • firstDayOfQuarter可以更加增强`LocalDate firstDayOfQuarter = date.with(IsoFields.DAY_OF_QUARTER,1L);` (4认同)

Vol*_*liy 13

private static Date getFirstDayOfQuarter(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)/3 * 3);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    return cal.getTime();
}

private static Date getLastDayOfQuarter(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)/3 * 3 + 2);
    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
    return cal.getTime();
}
Run Code Online (Sandbox Code Playgroud)

这应该有用,但我建议你比我更仔细地测试它.注意:Java中的int值分区返回最低值.


Bas*_*que 7

正如其他人提到的,您正在使用过时的课程。Sun/Oracle 决定用 java.time 框架取代旧的日期时间类,这是一个巨大的改进。

避免使用旧的日期时间类。它们确实设计得很差,令人困惑,而且很麻烦。

时间

所述java.time框架内置的Java 8.对于Java 6和7中,使用回端口,ThreeTen-反向移植。对于 Android,该后向端口ThreeTenABP 的改编

java.time 框架的灵感来自非常成功的 Joda-Time 库,该库由 JSR 310 定义,并由 ThreeTen-Extra 项目扩展。请参阅Oracle 教程

LocalDate

对于没有时间和时区的仅日期值,使用LocalDate内置作为 java.time 的一部分。要获得当前日期需要一个时区,因为世界各地的日期都不同(新的一天在东部更早的时候)。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
Run Code Online (Sandbox Code Playgroud)

Quarter & YearQuarter

上面提到的ThreeTen-Extra项目作为未来可能添加到 java.time 的功能的试验场。要使用此库,请将其 jar 文件添加到您的项目中(或使用 Maven 等)。如果您真的不想添加库,请参阅dheeran的替代解决方案答案

该库当前包含您可能会发现特别有用的QuarterYearQuarter类。在您的代码中传递这些类型的对象比使用字符串和数字来表示您的宿舍更安全。

YearQuarter currentQuarter = YearQuarter.now ( zoneId );
Run Code Online (Sandbox Code Playgroud)

YearQuarter具有许多有用的方法,包括要求它的日期。

LocalDate start = currentQuarter.atDay ( 1 );
LocalDate stop = currentQuarter.atEndOfQuarter ();
Run Code Online (Sandbox Code Playgroud)

转储到控制台。

System.out.println ( "today: " + today + " currentQuarter: " + currentQuarter + " start: " + start + " stop: " + stop );
Run Code Online (Sandbox Code Playgroud)

今天:2016-04-08 当前季度:2016-Q2 开始:2016-04-01 停止:2016-06-30

如果您真的不想按照我的建议添加ThreeTen-Extra库,请参阅Pavel答案以获取仅使用内置java.time类的另一种解决方案。但是,如果您在宿舍方面做了很多工作,我相信您会发现ThreeTen-Extra非常值得为您的项目添加一个库。

转换

如果必须使用 java.util.Date 来处理尚未更新为 java.time 的旧代码,则可以来回转换。查找添加到旧类中的新方法以进行转换。

不幸的是,旧类缺乏任何干净的方式来表示仅日期值。所以没有完全干净的方式去/从LocalDate.

java.sql.Date

java.sql.Date班假装是一个日期,但仅实际上包含调整到时间的天00:00:00.0。此类笨拙地继承自,java.util.Date但文档明确警告不要使用该事实;您应该将两者视为单独的不相关类。

java.sql.Date sqlDate_quarterStart = java.sql.Date.valueOf( start );
Run Code Online (Sandbox Code Playgroud)

java.util.Date

Ajava.util.Date表示日期和时间,有效地使用 UTC。我们可以先将我们LocalDate的调整到一天的第一时刻,以获得一个带有时间的日期, a ZonedDateTime。从那里我们可以要求Instant在 UTC 时间线上的某个时刻。旧的 .Date 类有一个静态from( Instant )转换方法。

ZonedDateTime zdt = start.atStartOfDay( zoneId ); // First moment of the day on a certain date.
Instant instant = zdt.toInstant(); // Moment on the timeline in UTC.
java.util.Date utilDate = java.util.Date.from( instant );
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & 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,和更多


her*_*man 5

把事情简单化

我认为下面的代码是最优雅的,因为它没有任何神奇的数字(如 92)、TemporalAdjusters 或非明显的计算,并且可以轻松地进行调整以获取任何季度的开始和结束(而不仅仅是当前季度)。

import static java.time.temporal.IsoFields.QUARTER_OF_YEAR;

LocalDate date = LocalDate.now(); // can be any other date

int year = date.getYear();
int quarter = date.get(QUARTER_OF_YEAR);
        
LocalDate start = YearMonth.of(year, 1)                    // January of given year
                           .with(QUARTER_OF_YEAR, quarter) // becomes first month of given quarter
                           .atDay(1);                      // becomes first day of given quarter

LocalDate end = YearMonth.of(year, 3)                      // March of given year
                         .with(QUARTER_OF_YEAR, quarter)   // becomes 3rd (last) month of given quarter
                         .atEndOfMonth();                  // becomes last day of given quarter
Run Code Online (Sandbox Code Playgroud)

如果您没有日期,只有一年和季度(例如 2020 年第二季度),则变为:

LocalDate start = YearMonth.of(2020, 1).with(QUARTER_OF_YEAR, 2).atDay(1);
LocalDate end = YearMonth.of(2020, 3).with(QUARTER_OF_YEAR, 2).atEndOfMonth();
Run Code Online (Sandbox Code Playgroud)