我需要获取一个季度的统计数据。
示例:今天是2018年2月10日,我需要检索2017年12月的数据,从1st到31st,然后从2018年1月,从1st到30th以及从2月1st到当前日期。
如何使用 JavaDate
实现此目的?
tl;博士
YearMonth.now().minusMonths( 1 ).atEndOfMonth() // or .atDay( 1 )
详
获取今天的日期。
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
LocalDate today = LocalDate.now( z ) ;
获取该日期的年月。
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类的另一种有效方法,请参阅 diston 的答案。
关于java.time
java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧旧日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。
您可以直接与数据库交换java.time对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要java.sql.*
类。
从哪里获得java.time类?
Java SE 8、Java SE- 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9添加了一些小功能和修复。
Java SE 6 和 Java SE 7 大部分 - java.time 功能在ThreeTen-Backport中向后移植到 Java 6 和 7。
Android- 更高版本的 java.time 类的 Android 捆绑实现。
- 对于早期的Android(<26),ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP...。
ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
等。
尝试这样的事情:
// 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);
然后,在其他月份做类似的事情
您可以使用Java8的java.time类(或Java 的三个向后移植<= 7)。
如果您只使用日/月/年,而不关心小时和时区,则使用的最佳类是LocalDate
。创建特定日期很简单:
// February 10th 2018
LocalDate current = LocalDate.of(2018, 2, 10);
或者,您可以拨打LocalDate.now()
以获取当前日期。
然后,要到达 2017年12 月 1 日,您必须减去 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日到2月10日循环:
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日停止。如果要包含 2 月 10日,请将条件更改为if (! date.isAfter(current))