mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix DateRange bug
This commit is contained in:
parent
16910ed709
commit
5719c28158
@ -22,6 +22,7 @@
|
|||||||
* 【core 】 修复IdcardUtil.getIdcardInfo.getProvinceCode获取为汉字的问题(issue#I3XP4Q@Gitee)
|
* 【core 】 修复IdcardUtil.getIdcardInfo.getProvinceCode获取为汉字的问题(issue#I3XP4Q@Gitee)
|
||||||
* 【core 】 修复CollUtil.subtract使用非标准Set等空指针问题(issue#I3XN1Z@Gitee)
|
* 【core 】 修复CollUtil.subtract使用非标准Set等空指针问题(issue#I3XN1Z@Gitee)
|
||||||
* 【core 】 修复SqlFormatter部分SQL空指针问题(issue#I3XS44@Gitee)
|
* 【core 】 修复SqlFormatter部分SQL空指针问题(issue#I3XS44@Gitee)
|
||||||
|
* 【core 】 修复DateRange计算问题(issue#I3Y1US@Gitee)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ public class DateRange extends Range<DateTime> {
|
|||||||
/**
|
/**
|
||||||
* 构造,包含开始和结束日期时间
|
* 构造,包含开始和结束日期时间
|
||||||
*
|
*
|
||||||
* @param start 起始日期时间
|
* @param start 起始日期时间(包括)
|
||||||
* @param end 结束日期时间
|
* @param end 结束日期时间(包括)
|
||||||
* @param unit 步进单位
|
* @param unit 步进单位
|
||||||
*/
|
*/
|
||||||
public DateRange(Date start, Date end, final DateField unit) {
|
public DateRange(Date start, Date end, final DateField unit) {
|
||||||
@ -27,8 +27,8 @@ public class DateRange extends Range<DateTime> {
|
|||||||
/**
|
/**
|
||||||
* 构造,包含开始和结束日期时间
|
* 构造,包含开始和结束日期时间
|
||||||
*
|
*
|
||||||
* @param start 起始日期时间
|
* @param start 起始日期时间(包括)
|
||||||
* @param end 结束日期时间
|
* @param end 结束日期时间(包括)
|
||||||
* @param unit 步进单位
|
* @param unit 步进单位
|
||||||
* @param step 步进数
|
* @param step 步进数
|
||||||
*/
|
*/
|
||||||
@ -48,11 +48,12 @@ public class DateRange extends Range<DateTime> {
|
|||||||
*/
|
*/
|
||||||
public DateRange(Date start, Date end, final DateField unit, final int step, boolean isIncludeStart, boolean isIncludeEnd) {
|
public DateRange(Date start, Date end, final DateField unit, final int step, boolean isIncludeStart, boolean isIncludeEnd) {
|
||||||
super(DateUtil.date(start), DateUtil.date(end), (current, end1, index) -> {
|
super(DateUtil.date(start), DateUtil.date(end), (current, end1, index) -> {
|
||||||
DateTime dt = current.offsetNew(unit, step);
|
final DateTime dt = DateUtil.date(start).offsetNew(unit, (index + 1) * step);
|
||||||
if (dt.isAfter(end1)) {
|
if (dt.isAfter(end1)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return current.offsetNew(unit, step);
|
|
||||||
|
return dt;
|
||||||
}, isIncludeStart, isIncludeEnd);
|
}, isIncludeStart, isIncludeEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,8 +329,7 @@ public class DateTime extends Date {
|
|||||||
//noinspection MagicConstant
|
//noinspection MagicConstant
|
||||||
cal.add(datePart.getValue(), offset);
|
cal.add(datePart.getValue(), offset);
|
||||||
|
|
||||||
DateTime dt = ObjectUtil.clone(this);
|
return ObjectUtil.clone(this).setTimeInternal(cal.getTimeInMillis());
|
||||||
return dt.setTimeInternal(cal.getTimeInMillis());
|
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------- offset end
|
// -------------------------------------------------------------------- offset end
|
||||||
|
|
||||||
|
@ -1788,7 +1788,7 @@ public class DateUtil extends CalendarUtil {
|
|||||||
/**
|
/**
|
||||||
* 创建日期范围生成器
|
* 创建日期范围生成器
|
||||||
*
|
*
|
||||||
* @param start 起始日期时间
|
* @param start 起始日期时间(包括)
|
||||||
* @param end 结束日期时间
|
* @param end 结束日期时间
|
||||||
* @param unit 步进单位
|
* @param unit 步进单位
|
||||||
* @return {@link DateRange}
|
* @return {@link DateRange}
|
||||||
|
@ -17,36 +17,53 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||||||
* 此类使用{@link ReentrantReadWriteLock}保证线程安全
|
* 此类使用{@link ReentrantReadWriteLock}保证线程安全
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Looly
|
|
||||||
*
|
|
||||||
* @param <T> 生成范围对象的类型
|
* @param <T> 生成范围对象的类型
|
||||||
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 锁保证线程安全 */
|
/**
|
||||||
|
* 锁保证线程安全
|
||||||
|
*/
|
||||||
private Lock lock = new ReentrantLock();
|
private Lock lock = new ReentrantLock();
|
||||||
/** 起始对象 */
|
/**
|
||||||
|
* 起始对象
|
||||||
|
*/
|
||||||
private final T start;
|
private final T start;
|
||||||
/** 结束对象 */
|
/**
|
||||||
|
* 结束对象
|
||||||
|
*/
|
||||||
private final T end;
|
private final T end;
|
||||||
/** 当前对象 */
|
/**
|
||||||
|
* 当前对象
|
||||||
|
*/
|
||||||
private T current;
|
private T current;
|
||||||
/** 下一个对象 */
|
/**
|
||||||
|
* 下一个对象
|
||||||
|
*/
|
||||||
private T next;
|
private T next;
|
||||||
/** 步进 */
|
/**
|
||||||
|
* 步进
|
||||||
|
*/
|
||||||
private final Steper<T> steper;
|
private final Steper<T> steper;
|
||||||
/** 索引 */
|
/**
|
||||||
|
* 索引
|
||||||
|
*/
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
/** 是否包含第一个元素 */
|
/**
|
||||||
|
* 是否包含第一个元素
|
||||||
|
*/
|
||||||
private final boolean includeStart;
|
private final boolean includeStart;
|
||||||
/** 是否包含最后一个元素 */
|
/**
|
||||||
|
* 是否包含最后一个元素
|
||||||
|
*/
|
||||||
private boolean includeEnd;
|
private boolean includeEnd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param start 起始对象
|
* @param start 起始对象(包括)
|
||||||
* @param steper 步进
|
* @param steper 步进
|
||||||
*/
|
*/
|
||||||
public Range(T start, Steper<T> steper) {
|
public Range(T start, Steper<T> steper) {
|
||||||
@ -56,8 +73,8 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param start 起始对象(包含)
|
* @param start 起始对象(包含)
|
||||||
* @param end 结束对象(包含)
|
* @param end 结束对象(包含)
|
||||||
* @param steper 步进
|
* @param steper 步进
|
||||||
*/
|
*/
|
||||||
public Range(T start, T end, Steper<T> steper) {
|
public Range(T start, T end, Steper<T> steper) {
|
||||||
@ -67,11 +84,11 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param start 起始对象
|
* @param start 起始对象
|
||||||
* @param end 结束对象
|
* @param end 结束对象
|
||||||
* @param steper 步进
|
* @param steper 步进
|
||||||
* @param isIncludeStart 是否包含第一个元素
|
* @param isIncludeStart 是否包含第一个元素
|
||||||
* @param isIncludeEnd 是否包含最后一个元素
|
* @param isIncludeEnd 是否包含最后一个元素
|
||||||
*/
|
*/
|
||||||
public Range(T start, T end, Steper<T> steper, boolean isIncludeStart, boolean isIncludeEnd) {
|
public Range(T start, T end, Steper<T> steper, boolean isIncludeStart, boolean isIncludeEnd) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
@ -99,7 +116,7 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
|||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if(0 == this.index && this.includeStart) {
|
if (0 == this.index && this.includeStart) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (null == this.next) {
|
if (null == this.next) {
|
||||||
@ -193,9 +210,8 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
|||||||
* 3、限制range个数,通过实现此接口,在实现类中定义一个对象属性,可灵活定义limit,限制range个数
|
* 3、限制range个数,通过实现此接口,在实现类中定义一个对象属性,可灵活定义limit,限制range个数
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Looly
|
|
||||||
*
|
|
||||||
* @param <T> 需要增加步进的对象
|
* @param <T> 需要增加步进的对象
|
||||||
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
public interface Steper<T> {
|
public interface Steper<T> {
|
||||||
/**
|
/**
|
||||||
@ -204,8 +220,8 @@ public class Range<T> implements Iterable<T>, Iterator<T>, Serializable {
|
|||||||
* 用户需根据end参数自行定义边界,当达到边界时返回null表示结束,否则Range中边界对象无效,会导致无限循环
|
* 用户需根据end参数自行定义边界,当达到边界时返回null表示结束,否则Range中边界对象无效,会导致无限循环
|
||||||
*
|
*
|
||||||
* @param current 上一次增加步进后的基础对象
|
* @param current 上一次增加步进后的基础对象
|
||||||
* @param end 结束对象
|
* @param end 结束对象
|
||||||
* @param index 当前索引(步进到第几个元素),从0开始计数
|
* @param index 当前索引(步进到第几个元素),从0开始计数
|
||||||
* @return 增加步进后的对象
|
* @return 增加步进后的对象
|
||||||
*/
|
*/
|
||||||
T step(T current, T end, int index);
|
T step(T current, T end, int index);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.core.lang;
|
package cn.hutool.core.lang;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateField;
|
import cn.hutool.core.date.DateField;
|
||||||
|
import cn.hutool.core.date.DateRange;
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@ -26,9 +27,25 @@ public class RangeTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Assert.assertTrue(range.hasNext());
|
Assert.assertTrue(range.hasNext());
|
||||||
Assert.assertEquals(range.next(), DateUtil.parse("2017-01-01"));
|
Assert.assertEquals(DateUtil.parse("2017-01-01"), range.next());
|
||||||
Assert.assertTrue(range.hasNext());
|
Assert.assertTrue(range.hasNext());
|
||||||
Assert.assertEquals(range.next(), DateUtil.parse("2017-01-02"));
|
Assert.assertEquals(DateUtil.parse("2017-01-02"), range.next());
|
||||||
|
Assert.assertFalse(range.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dateRangeTest2() {
|
||||||
|
DateTime start = DateUtil.parse("2021-01-31");
|
||||||
|
DateTime end = DateUtil.parse("2021-03-31");
|
||||||
|
|
||||||
|
final DateRange range = DateUtil.range(start, end, DateField.MONTH);
|
||||||
|
|
||||||
|
Assert.assertTrue(range.hasNext());
|
||||||
|
Assert.assertEquals(DateUtil.parse("2021-01-31"), range.next());
|
||||||
|
Assert.assertTrue(range.hasNext());
|
||||||
|
Assert.assertEquals(DateUtil.parse("2021-02-28"), range.next());
|
||||||
|
Assert.assertTrue(range.hasNext());
|
||||||
|
Assert.assertEquals(DateUtil.parse("2021-03-31"), range.next());
|
||||||
Assert.assertFalse(range.hasNext());
|
Assert.assertFalse(range.hasNext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user