Skip to content

Commit

Permalink
Calculate epoch day in constructor.
Browse files Browse the repository at this point in the history
Exclude supplementary days from week/month calculations.
Introduce proleptic week.
Re-work value ranges.
Optimised plus/minus for days/week/months.
  • Loading branch information
catull committed Mar 2, 2017
1 parent 5e8626a commit 7747f33
Showing 1 changed file with 111 additions and 18 deletions.
129 changes: 111 additions & 18 deletions src/main/java/org/threeten/extra/chrono/FrenchRepublicDate.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
package org.threeten.extra.chrono;

import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.DAY_OF_WEEK;
import static java.time.temporal.ChronoField.DAY_OF_YEAR;
import static java.time.temporal.ChronoField.EPOCH_DAY;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
Expand All @@ -55,9 +54,9 @@
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQuery;
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.time.temporal.ValueRange;
import java.time.temporal.WeekFields;
import static org.threeten.extra.chrono.FrenchRepublicChronology.DOW_RANGE;


/**
* A date in the FrenchRepublic calendar system.
Expand All @@ -74,7 +73,7 @@
* identity hash code or use the distinction between equals() and ==.
*/
public final class FrenchRepublicDate
extends AbstractNileDate
extends AbstractDate
implements ChronoLocalDate, Serializable {

/**
Expand All @@ -98,11 +97,15 @@ public final class FrenchRepublicDate
/**
* The month.
*/
private final short month;
private final int month;
/**
* The day.
*/
private final short day;
private final int day;
/**
* Epoch day
*/
private final long epochDay;

//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -196,22 +199,74 @@ public static FrenchRepublicDate from(TemporalAccessor temporal) {

@Override
ValueRange rangeAlignedWeekOfMonth() {
return ValueRange.of(1, getMonth() == 13 ? 1 : 3);
return ValueRange.of(getMonth() != 13 ? 1 : 0, getMonth() != 13 ? 3 : 0);
}


@Override
int getDayOfWeek() {
return (int) Math.floorMod(day, 10);
if (month == 13) {
return 0;
}
return Math.floorMod(day, 10);
}

@Override
int lengthOfWeek() {
return 10;
}

@Override
public int lengthOfMonth() {
if (getMonth() != 13) {
return 30;
}
return 0;
}

@Override
int lengthOfYearInMonths() {
return 12;
}

@Override
int getDayOfYear() {
return (getMonth() - 1) * 30 + getDayOfMonth();
}

@Override
public ValueRange range(TemporalField field) {
if (field instanceof ChronoField) {
if (isSupported(field)) {
ChronoField f = (ChronoField) field;
switch (f) {
case ALIGNED_DAY_OF_WEEK_IN_MONTH:
case ALIGNED_DAY_OF_WEEK_IN_YEAR:
case DAY_OF_WEEK:
return month != 13 ? FrenchRepublicChronology.DOW_RANGE : FrenchRepublicChronology.EMPTY;
case ALIGNED_WEEK_OF_MONTH:
return month != 13 ? ValueRange.of(1, 3) : FrenchRepublicChronology.EMPTY;
case ALIGNED_WEEK_OF_YEAR:
return month != 13 ? ValueRange.of(1, 36) : FrenchRepublicChronology.EMPTY;
case DAY_OF_MONTH:
return month != 13 ? ValueRange.of(1, lengthOfMonth()) : FrenchRepublicChronology.EMPTY;
case DAY_OF_YEAR:
return isLeapYear() ? ValueRange.of(1, 366) : ValueRange.of(1, 365);
//case EPOCH_DAY:
// return ValueRange.of(-999_999, 999_999);
//case ERA:
// return ERA_RANGE;
case MONTH_OF_YEAR:
return ValueRange.of(1, 12);
default:
break;
}
} else {
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}
}
return super.range(field);
}
//-----------------------------------------------------------------------
/**
* Obtains a {@code FrenchRepublicDate} representing a date in the FrenchRepublic calendar
Expand Down Expand Up @@ -301,8 +356,10 @@ static FrenchRepublicDate create(int prolepticYear, int month, int dayOfMonth) {
*/
private FrenchRepublicDate(int prolepticYear, int month, int dayOfMonth) {
this.prolepticYear = prolepticYear;
this.month = (short) month;
this.day = (short) dayOfMonth;
this.month = month;
this.day = dayOfMonth;
long calendarEpochDay = (prolepticYear * 365) + Math.floorDiv(prolepticYear, 4) + (getDayOfYear() - 1);
this.epochDay = calendarEpochDay - 365 - EPOCH_DAY_DIFFERENCE;
}

/**
Expand All @@ -315,10 +372,6 @@ private Object readResolve() {
}

//-----------------------------------------------------------------------
@Override
int getEpochDayDifference() {
return EPOCH_DAY_DIFFERENCE;
}

@Override
int getProlepticYear() {
Expand All @@ -335,6 +388,10 @@ int getDayOfMonth() {
return day;
}

private long getProlepticWeek() {
return getProlepticMonth() * 3 + ((getDayOfMonth() - 1) / 10) - 1;
}

@Override
FrenchRepublicDate resolvePrevious(int newYear, int newMonth, int dayOfMonth) {
return resolvePreviousValid(newYear, newMonth, dayOfMonth);
Expand All @@ -357,7 +414,7 @@ public FrenchRepublicChronology getChronology() {
/**
* Gets the era applicable at this date.
* <p>
* The FrenchRepublic calendar system has two eras, 'AM' and 'BEFORE_AM',
* The FrenchRepublic calendar system has two eras, 'REPUBLICAN' and 'BEFORE_REPUBLICAN',
* defined by {@link FrenchRepublicEra}.
*
* @return the era applicable at this date, not null
Expand Down Expand Up @@ -389,6 +446,44 @@ public FrenchRepublicDate plus(long amountToAdd, TemporalUnit unit) {
return (FrenchRepublicDate) super.plus(amountToAdd, unit);
}

/*
*/
@Override
FrenchRepublicDate plusMonths(long months) {
if (months % 12 == 0) {
return (FrenchRepublicDate) plusYears(months / 12);
}
if (month == 13 || 0 == months) {
return this;
}
return (FrenchRepublicDate) super.plusMonths(months);
}

@Override
FrenchRepublicDate plusWeeks(long weeks) {
if (weeks % 3 == 0) {
return plusMonths(weeks / 3);
}
if (month == 13 || 0 == weeks) {
return this;
}
long curEm = getProlepticWeek();
long calcEm = Math.addExact(curEm, weeks) + 1;
int newYear = Math.toIntExact(Math.floorDiv(calcEm, lengthOfYearInMonths() * 3));
int yearWeeks = (int) Math.floorMod(calcEm, lengthOfYearInMonths() * 3);
int weekDays = ((getDayOfMonth() - 1) % lengthOfWeek()) + 1;
int newMonth = yearWeeks / 3 + 1;
return resolvePrevious(newYear, newMonth, (yearWeeks % 3) * lengthOfWeek() + weekDays);
}

@Override
FrenchRepublicDate plusDays(long days) {
if (days % 10 == 0) {
return plusWeeks(days / 10);

This comment has been minimized.

Copy link
@ledahulevogyre

ledahulevogyre Mar 2, 2017

Owner

This assumption does not take the complementary days into account. I've removed the test.

}
return (FrenchRepublicDate) super.plusDays(days);
}

@Override
public FrenchRepublicDate minus(TemporalAmount amount) {
return (FrenchRepublicDate) amount.subtractFrom(this);
Expand Down Expand Up @@ -418,8 +513,6 @@ public ChronoPeriod until(ChronoLocalDate endDateExclusive) {

@Override
public long toEpochDay() {
long year = (long) getProlepticYear();
long calendarEpochDay = (year * 365) + Math.floorDiv(year, 4) + (getDayOfYear() - 1);
return calendarEpochDay - 365 - getEpochDayDifference();
return this.epochDay;
}
}

0 comments on commit 7747f33

Please sign in to comment.