Skip to content

Commit

Permalink
kshaia tuning
Browse files Browse the repository at this point in the history
see issue #851
  • Loading branch information
MenoData committed Jul 12, 2020
1 parent 6ddd4b2 commit 9df9298
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 10 deletions.
20 changes: 20 additions & 0 deletions base/src/main/java/net/time4j/calendar/IndianMonth.java
Expand Up @@ -283,4 +283,24 @@ public boolean test(IndianCalendar context) {

}

/**
* <p>Rolls this month by given amount of months. </p>
*
* @param months count of months (maybe negative)
* @return result of rolling operation
* @since 5.7
*/
/*[deutsch]
* <p>Rollt um die angegebene Anzahl von Monaten vor oder zur&uuml;ck. </p>
*
* @param months count of months (maybe negative)
* @return result of rolling operation
* @since 5.7
*/
public IndianMonth roll(int months) {

return IndianMonth.valueOf((this.ordinal() + (months % 12 + 12)) % 12 + 1);

}

}
2 changes: 1 addition & 1 deletion base/src/main/java/net/time4j/calendar/hindu/HinduCS.java
Expand Up @@ -111,7 +111,7 @@ final boolean isExpunged(
) {
long utcDays = this.create(kyYear, month, HinduDay.valueOf(15)).getDaysSinceEpochUTC();
HinduCalendar cal = this.create(utcDays);
return (cal.getExpiredYearOfKaliYuga() != kyYear) || !cal.getMonth().equals(month);
return !cal.getMonth().getValue().equals(month.getValue());
}

// expunged days are gaps
Expand Down
45 changes: 36 additions & 9 deletions base/src/main/java/net/time4j/calendar/hindu/HinduCalendar.java
Expand Up @@ -968,8 +968,10 @@ public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(this.variant);
sb.append(",kali-yuga-year=");
sb.append(this.kyYear);
sb.append(",era=");
sb.append(this.getEra());
sb.append(",year-of-era=");
sb.append(this.getYear());
sb.append(",month=");
sb.append(this.month);
sb.append(",day-of-month=");
Expand Down Expand Up @@ -1106,12 +1108,19 @@ private HinduCalendar withAdjustedDayInMonth(HinduDay desired) {
int count = 5;
boolean purnimanta = this.variant.isPurnimanta();
boolean aroundNewYear = (purnimanta && this.isChaitra() && this.withNewYear().month.equals(this.month));
int y;

while (calsys.isExpunged(this.criticalYear(aroundNewYear, dom), this.month, dom)) {
while (calsys.isExpunged(y = this.criticalYear(aroundNewYear, dom), this.month, dom)) {
if ((dom.getValue() == (purnimanta ? 16 : 1)) && !dom.isLeap()) {
return this.withFirstDayOfMonth();
} else if (count == 0) {
throw new IllegalArgumentException("No valid day found: " + this + " => (day=" + desired + ")");
if (calsys.isExpunged(y, this.month)) {
throw new IllegalArgumentException(
"Kshaia (lost) month is never valid: kali-yuga-year=" + y + ", month=" + this.month);
} else {
throw new IllegalArgumentException(
"No valid day found for: " + this + " => (desired day=" + desired + ")");
}
} else if (dom.isLeap()) {
dom = HinduDay.valueOf(dom.getValue());
} else {
Expand All @@ -1127,7 +1136,7 @@ private HinduCalendar withAdjustedDayInMonth(HinduDay desired) {
count--;
}

return calsys.create(this.criticalYear(aroundNewYear, dom), this.month, dom);
return calsys.create(y, this.month, dom);
}

private int criticalYear(
Expand Down Expand Up @@ -1427,24 +1436,42 @@ public HinduCalendar withValue(

switch (this.index) {
case YEAR_INDEX:
HinduCS calsys = context.variant.getCalendarSystem();
int y = HinduEra.KALI_YUGA.yearOfEra(context.getEra(), value);

if (!context.variant.isUsingElapsedYears()) {
y--;
}

if (y == context.kyYear) {
return context;
}

int midOfMonth = 15;

if (context.variant.isPurnimanta()) {
midOfMonth = (context.dayOfMonth.getValue() >= 16) ? 29 : 2; // preserving fortnight
}

HinduCalendar date = calsys.create(y, context.month, HinduDay.valueOf(midOfMonth));
HinduCS calsys = context.variant.getCalendarSystem();
HinduMonth m = context.month;
boolean kshaia = calsys.isExpunged(y, m);

if (kshaia) {
m = HinduMonth.of(context.month.getValue().roll((y > context.kyYear) ? -1 : 1));
if (y < context.kyYear){
long u = calsys.create(y, m, HinduDay.valueOf(midOfMonth)).getDaysSinceEpochUTC() - 30;
HinduMonth ml = calsys.create(u).month;
if (ml.equals(m.withLeap())) {
m = ml;
}
}
}

HinduCalendar date = calsys.create(y, m, HinduDay.valueOf(midOfMonth));

if (context.month.isLeap()) {
if (!kshaia && m.isLeap()) {
date = calsys.transform(date.utcDays);
if (date.month.getValue().getValue() > context.month.getValue().getValue()) {
if (date.month.getValue().getValue() > m.getValue().getValue()) {
date = calsys.create(date.utcDays - 30);
}
}
Expand Down
Expand Up @@ -261,6 +261,48 @@ public void dayOfMonthChangeInPurnimanta() {
is(1851));
}

@Test
public void kshaia1() {
HinduCalendar cal = PlainDate.of(1982, 2, 14).transform(HinduCalendar.family(), HinduRule.AMANTA.variant());
assertThat(cal.getMonth(), is(HinduMonth.ofLunisolar(11)));

HinduCalendar expected =
HinduCalendar.of(
HinduRule.AMANTA.variant(),
HinduEra.VIKRAMA,
2039,
HinduMonth.ofLunisolar(10),
cal.getDayOfMonth());

assertThat(
cal.with(HinduCalendar.YEAR_OF_ERA, 2039),
is(expected));
assertThat(
cal.nextYear(),
is(expected));
}

@Test
public void kshaia2() {
HinduCalendar cal = PlainDate.of(1984, 2, 14).transform(HinduCalendar.family(), HinduRule.AMANTA.variant());
assertThat(cal.getMonth(), is(HinduMonth.ofLunisolar(11)));

HinduCalendar expected =
HinduCalendar.of(
HinduRule.AMANTA.variant(),
HinduEra.VIKRAMA,
2039,
HinduMonth.ofLunisolar(12).withLeap(),
cal.getDayOfMonth());

assertThat(
cal.with(HinduCalendar.YEAR_OF_ERA, 2039),
is(expected));
assertThat(
cal.previousYear(),
is(expected));
}

@Test
public void amantaMonthSequence1982() { // CC: page 341, with two leap months and a lost month
HinduCalendar cal = PlainDate.of(1982, 3, 14).transform(HinduCalendar.family(), HinduRule.AMANTA.variant());
Expand Down

0 comments on commit 9df9298

Please sign in to comment.