如何在java.util.date中获取当前季度的第一个日期和最后一个日期
我需要获取当前季度的第一个日期作为java.util.date对象,获取当前季度的最后一个日期作为java.util.date对象 我使用以下方法来获取本月的第一个日期和本月的最后一个日期如何在java.util.date中获取当前季度的第一个日期和最后一个日期,java,date,Java,Date,我需要获取当前季度的第一个日期作为java.util.date对象,获取当前季度的最后一个日期作为java.util.date对象 我使用以下方法来获取本月的第一个日期和本月的最后一个日期 private Date getThisMonthFirstDate(){ Calendar calendar = new GregorianCalendar(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calend
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();
}
有没有办法修改该函数以实现这一点,或者有人能指出更好的方法
假设Q1=1-2-3月,Q2=4月,5月,6月等
private static Date getFirstDayOfQuarter(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)/3 * 3);
return cal.getTime();
}
private static Date getLastDayOfQuarter(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
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();
}
这应该行得通,但我建议您比我更仔细地测试它。
注意:Java中int值的除法返回下限值。您可以使用joda:
Date start = date.withMonthOfYear(((date.getMonthOfYear() / 3) + 1) * 3 - 2)
.withDayOfMonth(1)
.withTimeAtStartOfDay()
.toDate();
Date end = date.withMonthOfYear(((date.getMonthOfYear() / 3) + 1) * 3)
.withDayOfMonth(Month.of(((date.getMonthOfYear() / 3) + 1) * 3).maxLength())
.withTimeAtStartOfDay()
.toDate();
当DateTime日期=新的日期时间(2016,8,12,1,1,1)
我得到:
Fri Jul 01 00:00:00 CEST 2016
Fri Sep 30 00:00:00 CEST 2016
正如其他人提到的,您正在使用过时的类。Sun/Oracle决定用java.time框架取代旧的日期时间类,这是一个巨大的改进 避免使用旧的日期时间类。它们确实设计拙劣、令人困惑且麻烦 java.time 该框架内置于Java8中。对于Java 6和7,请使用后端口。对于Android,该后端端口的适应 time框架的灵感来自于非常成功的Joda时间库,由JSR 310定义,并由Three Ten Extra项目进行了扩展。看
LocalDate
对于只包含日期的值,不包含一天中的时间,也不包含时区,请将内置值作为java.time的一部分使用。要获取当前日期,需要一个时区,因为世界各地的日期各不相同(东方新的一天提前到来)
季度
和年度季度
上面提到的项目是将来可能添加到java.time的特性的试验场。要使用此库,请将其jar文件添加到项目中(或使用Maven等)。如果您确实不想添加库,请参阅其他解决方案
此库当前包含您可能会发现特别有用的和类。在代码中传递这些类型的对象比使用字符串和数字来表示宿舍更安全
YearQuarter currentQuarter = YearQuarter.now ( zoneId );
YearQuarter
有许多有用的方法,包括询问日期
LocalDate start = currentQuarter.atDay ( 1 );
LocalDate stop = currentQuarter.atEndOfQuarter ();
转储到控制台
System.out.println ( "today: " + today + " currentQuarter: " + currentQuarter + " start: " + start + " stop: " + stop );
今天:2016-04-08当前季度:2016-Q2开始:2016-04-01停止:2016-06-30
如果您确实不想像我建议的那样添加Three Ten额外的库,请参阅,以获得仅使用内置java.time类的另一个解决方案。但是如果你正在做很多关于Quarter的工作,我相信你会发现额外的Three-Ten非常值得为你的项目添加一个库
转化
如果必须使用java.util.Date处理尚未更新为java.time的旧代码,则可以来回转换。查找添加到旧类中进行转换的新方法
不幸的是,旧类缺少任何干净的方式来表示仅日期的值。因此,没有完全干净的方法去/从LocalDate
访问
java.sql.Date
该类假装只是一个日期,但实际上包含一个调整为00:00:00.0
的时间。这个类笨拙地继承自java.util.Date
,但文档明确警告不要使用这个事实;您应该将这两个类视为独立的、不相关的类
java.sql.Date sqlDate_quarterStart = java.sql.Date.valueOf( start );
java.util.Date
A表示一天中的日期和时间,有效地用UTC表示。我们可以首先将LocalDate
调整为一天中的第一个时刻,以获得带有时间的日期,即ZonedDateTime
。从那里,我们可以请求一个即时
,这是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 );
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(纯Java-8+解决方案:
LocalDate localDate = LocalDate.now(); LocalDate firstDayOfQuarter = localDate.with(localDate.getMonth().firstMonthOfQuarter()) .with(TemporalAdjusters.firstDayOfMonth()); LocalDate lastDayOfQuarter = firstDayOfQuarter.plusMonths(2) .with(TemporalAdjusters.lastDayOfMonth());
LocalDate非常简单LocalDate inputDate = LocalDate.parse("2018-09-04"); LocalDate firstDayOfQuarter = inputDate.withMonth(inputDate.get(IsoFields.QUARTER_OF_YEAR) * 3 - 2).with(TemporalAdjusters.firstDayOfMonth()); LocalDate lastDayOfQuarter = inputDate.withMonth(inputDate.get(IsoFields.QUARTER_OF_YEAR) * 3).with(TemporalAdjusters.lastDayOfMonth());
干杯!您可以使用Java8Locadate获取当前季度的第一天和最后一天 下面的代码将为您提供
在第二种方法中,92部分宽松 标准年第一季度的季度日值为1到90,闰年第一季度的季度日值为1到91,第二季度的季度日值为1到91,第三季度和第四季度的季度日值为1到92public static LocalDate getCurrentQuarterStartDay(LocalDate date) { return date.with(IsoFields.DAY_OF_QUARTER, 1L); } public static LocalDate getCurrentQuarterEndDate(LocalDate date) { return date.with(IsoFields.DAY_OF_QUARTER, 92L); }
有关详细信息,请参见ISOFields文档使用Volodymyr Masliy的答案,使用
,我的测试中出现了一些错误 如果你输入“31/05/2000”,它会返回当年的7月1日,这显然不是我们要找的 我使用了Basil Bourque和dheeran建议的java.util.Date
,测试用例工作正常 我的方法如下:java.time.LocalDate
public static Date lastDayOfQuarter(Date date) { LocalDate inputDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate lastDayOfQuarter = inputDate.withMonth(inputDate.get(IsoFields.QUARTER_OF_YEAR) * 3).with(TemporalAdjusters.lastDayOfMonth()); return Date.from(LastDayOfQuarter.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); }
我使用ZohhakRunner进行的单元测试如下:@TestWith({ "01/03/2000, 31/03/2000", "05/04/1982, 30/06/1982", "31/05/1982, 30/06/1982", "09/07/1990, 30/09/1990", "11/11/2019, 31/12/2019", "31/03/2016, 31/03/2016"}) public void lastDayOfQuarter_useInputDate_returnExpectedEndOfQuarterDate(String inputDateAsString, String endOfQuarterAsString) throws ParseException{ Date inputDate = new SimpleDateFormat("dd/MM/yyyy").parse(inputDateAsString); Date expectedDate = new SimpleDateFormat("dd/MM/yyyy").parse(endOfQuarterAsString); Date result = DateUtils.lastDayOfQuarter(inputDate); assertEquals(result, expectedDate); }
public static Date lastDayOfQuarter(Date date) { LocalDate inputDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate lastDayOfQuarter = inputDate.withMonth(inputDate.get(IsoFields.QUARTER_OF_YEAR) * 3).with(TemporalAdjusters.lastDayOfMonth()); return Date.from(LastDayOfQuarter.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); }
保持简单 我认为下面的代码是最优雅的,因为它没有任何神奇的数字(比如92)、临时调整器或不明显的计算,并且可以很容易地进行调整,以获得任何季度的开始和结束(不仅仅是当前季度) 如果您没有日期,但只有一年和一个季度(例如2020年第二季度),则这将成为:@TestWith({ "01/03/2000, 31/03/2000", "05/04/1982, 30/06/1982", "31/05/1982, 30/06/1982", "09/07/1990, 30/09/1990", "11/11/2019, 31/12/2019", "31/03/2016, 31/03/2016"}) public void lastDayOfQuarter_useInputDate_returnExpectedEndOfQuarterDate(String inputDateAsString, String endOfQuarterAsString) throws ParseException{ Date inputDate = new SimpleDateFormat("dd/MM/yyyy").parse(inputDateAsString); Date expectedDate = new SimpleDateFormat("dd/MM/yyyy").parse(endOfQuarterAsString); Date result = DateUtils.lastDayOfQuarter(inputDate); assertEquals(result, expectedDate); }
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();
如果您使用的是零=一月月份,如
does,则Date