Last active
January 22, 2017 08:26
-
-
Save shauway/4ac8b210d467186b463c887c1cc51a16 to your computer and use it in GitHub Desktop.
根据账单日获取任何账期
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Java语法不允许数组索引值为负值或超出数组长度(含),该函数去除这一限制。 | |
* <br/> | |
* 规则:<br/> | |
* <code> | |
* array=[1,2,3,4,5] <br/> | |
* <p> | |
* array[-1]=5 <br/> | |
* array[-2]=4 <br/> | |
* array[-3]=3 <br/> | |
* array[-4]=2 <br/> | |
* array[-5]=1 <br/> | |
* array[-6]=5 <br/> | |
* <p> | |
* array[5]=1 <br/> | |
* array[6]=2 <br/> | |
* array[7]=3 <br/> | |
* array[8]=4 <br/> | |
* array[9]=5 <br/> | |
* </code> | |
* | |
* @param array 数组 | |
* @param index 索引值 | |
* @return | |
*/ | |
int anyIndexOf(int[] array, int index) { | |
int _index = index > 0 ? index % array.length : (array.length + index) % array.length; | |
return array[Math.abs(_index)]; | |
} | |
/** | |
* @param billDays 账单日 | |
* @param nextCount 要获取当前账期后的第几个账期。负值:前推账期;正值:后推账期 | |
* @return | |
*/ | |
public PaymentDays nextPaymentDays(int[] billDays, int nextCount) { | |
Arrays.sort(billDays); // 由小到大将账单日排序 | |
Calendar calendar = Calendar.getInstance(); // 日历系统 | |
int today = calendar.get(Calendar.DAY_OF_MONTH); // 今天是本月的第几天 | |
int paymentDaysDayLen = billDays.length; // 总共有多少个账单日 | |
PaymentDays thisPaymentDays = null; // 本账期 | |
PaymentDays nextPaymentDays = null; // 推nextCount个账期后的账期 | |
int thisPaymentDaysBeginBillIndex = 0; // 本账期 开始日期 是账单日中的哪一日 | |
int thisPaymentDaysEndBillIndex = 0; // 本账期 结束日期 是账单日中的哪一日 | |
/* | |
设账单日为每月的5号、15号、25号,则 billDays=[5,15,25] | |
若today<5,则 | |
thisPaymentDaysBeginBillIndex=-1 billDays[thisPaymentDaysBeginBillIndex]=25 | |
thisPaymentDaysEndBillIndex=0 billDays[thisPaymentDaysEndBillIndex]=5 | |
若today<15,则 | |
thisPaymentDaysBeginBillIndex=0 billDays[thisPaymentDaysBeginBillIndex]=5 | |
thisPaymentDaysEndBillIndex=1 billDays[thisPaymentDaysEndBillIndex]=15 | |
若today<25,则 | |
thisPaymentDaysBeginBillIndex=1 billDays[thisPaymentDaysBeginBillIndex]=15 | |
thisPaymentDaysEndBillIndex=2 billDays[thisPaymentDaysEndBillIndex]=25 | |
*/ | |
for (int i = 0; i <= paymentDaysDayLen; i++) { | |
if (today < anyIndexOf(billDays, i)) { | |
thisPaymentDays = new PaymentDays(); | |
thisPaymentDaysBeginBillIndex = i - 1; | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, thisPaymentDaysBeginBillIndex)); | |
if (thisPaymentDaysBeginBillIndex < 0) { | |
calendar.add(Calendar.MONTH, -1); | |
} | |
thisPaymentDays.setBegin(calendar.getTime()); | |
calendar.setTimeInMillis(System.currentTimeMillis()); | |
thisPaymentDaysEndBillIndex = i; | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, thisPaymentDaysEndBillIndex)); | |
if (i == paymentDaysDayLen) { | |
calendar.add(Calendar.MONTH, 1); | |
} | |
thisPaymentDays.setEnd(calendar.getTime()); | |
break; | |
} | |
} | |
/* | |
若today>=25,则 | |
thisPaymentDaysBeginBillIndex=-1 billDays[thisPaymentDaysBeginBillIndex]=25 | |
thisPaymentDaysEndBillIndex=0 billDays[thisPaymentDaysEndBillIndex]=5 | |
*/ | |
if (thisPaymentDays == null) { | |
thisPaymentDays = new PaymentDays(); | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, -1)); | |
thisPaymentDays.setBegin(calendar.getTime()); | |
calendar.add(Calendar.MONTH, 1); | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, 0)); | |
thisPaymentDays.setEnd(calendar.getTime()); | |
} | |
if (nextCount == 0) { // 本账期 | |
nextPaymentDays = thisPaymentDays; | |
} else { | |
nextPaymentDays = new PaymentDays(); | |
calendar.setTimeInMillis(System.currentTimeMillis()); | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, thisPaymentDaysBeginBillIndex + nextCount)); | |
int monthDvBegin = (int) Math.floor((thisPaymentDaysBeginBillIndex + nextCount) * 1.0 / paymentDaysDayLen); | |
calendar.add(Calendar.MONTH, monthDvBegin); | |
nextPaymentDays.setBegin(calendar.getTime()); | |
calendar.setTimeInMillis(System.currentTimeMillis()); | |
calendar.set(Calendar.DAY_OF_MONTH, anyIndexOf(billDays, thisPaymentDaysEndBillIndex + nextCount)); | |
int monthDvEnd = (int) Math.floor((thisPaymentDaysEndBillIndex + nextCount) * 1.0 / paymentDaysDayLen); | |
calendar.add(Calendar.MONTH, monthDvEnd); | |
nextPaymentDays.setEnd(calendar.getTime()); | |
} | |
calendar.setTime(nextPaymentDays.getEnd()); | |
calendar.add(Calendar.DAY_OF_MONTH, -1); // 将账期变为既含前也含后 | |
nextPaymentDays.setEnd(calendar.getTime()); | |
return nextPaymentDays; | |
} | |
@Test | |
public void testPaymentDays() throws Exception { | |
int[] ints = new int[]{25}; | |
for (int i = -6; i <= 6; i++) { | |
if (i == 0) { | |
System.out.println("==========="); | |
} | |
System.out.println(nextPaymentDays(ints, i)); | |
if (i == 0) { | |
System.out.println("==========="); | |
} | |
} | |
System.out.println(""); | |
System.out.println(""); | |
ints = new int[]{5, 15, 25}; | |
for (int i = -6; i <= 6; i++) { | |
if (i == 0) { | |
System.out.println("==========="); | |
} | |
System.out.println(nextPaymentDays(ints, i)); | |
if (i == 0) { | |
System.out.println("==========="); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment