Skip to content

Commit

Permalink
Add plusDays method for RDate
Browse files Browse the repository at this point in the history
  • Loading branch information
jarnaud committed Dec 4, 2020
1 parent e60a653 commit 0604f77
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 17 deletions.
64 changes: 50 additions & 14 deletions src/main/java/com/github/jarnaud/republican/RDate.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.github.jarnaud.republican;

import java.time.LocalDate;
import java.util.Objects;

/**
* A Republican local date.
*/
public final class RDate implements Comparable<RDate> {

/**
* The first day in the Republican calendar (corresponding Republican day would be An 1 Vendemiaire 1).
* Dates before this date are undefined in the Republican calendar.
*/
public static final LocalDate FIRST_DAY = LocalDate.of(1792, 9, 22);

private final int year;
private final RMonth month;
private final int decade;
Expand All @@ -30,13 +37,37 @@ private int processDecade(int day) {
*
* @param year the Republican year (eg. An XII).
* @param month the Republican month.
* @param day the Republican day in the month.
* @param day the Republican day in the month, must be:
* - between 1 and 30 for normal months.
* - between 1 and 5 for Sanculottide on normal years.
* - between 1 and 6 for Sanculottide on sextile years.
* @return the Republican date.
*/
public static RDate of(int year, RMonth month, int day) {
if (year < 1 || month == null || day < 1 || day > 30 || (month == RMonth.Sanculottide && day > 6)) {
throw new RuntimeException("Invalid parameters for building Republican date");
}
return new RDate(year, month, day);
}

/**
* Construct a new Republican date.
*
* @param year the Republican year (eg. An XII).
* @param month the Republican month number, between 1 (for Vendemiaire) and 13 (for Sanculottide).
* @param day the Republican day in the month, must be:
* - between 1 and 30 for normal months.
* - between 1 and 5 for Sanculottide on normal years.
* - between 1 and 6 for Sanculottide on sextile years.
* @return the Republican date.
*/
public static RDate of(int year, int month, int day) {
if (year < 1 || month < 1 || month > 13 || day < 1 || day > 30 || (month == 13 && day > 6)) {
throw new RuntimeException("Invalid parameters for building Republican date");
}
return new RDate(year, RMonth.values()[month - 1], day);
}

public int getYear() {
return year;
}
Expand Down Expand Up @@ -91,19 +122,6 @@ public int hashCode() {
return Objects.hash(year, month, decade, day);
}

/**
* Return a copy of this date shifted by the given number of days.
* <p>
* TODO used by converter for shifting by 1 or 2 days within a month,
* TODO will need to handle month/year shift before being made public.
*
* @param daysToAdd the number of days to add.
* @return the new date.
*/
RDate plusDays(int daysToAdd) {
return RDate.of(this.getYear(), this.getMonth(), this.getDay() + daysToAdd);
}

public boolean isBefore(RDate date) {
if (year != date.getYear()) return year < date.getYear();
if (month.ordinal() != date.getMonth().ordinal()) return month.ordinal() < date.getMonth().ordinal();
Expand All @@ -122,4 +140,22 @@ public boolean isSextile() {
return year >= 20 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

/**
* Return a copy of this date shifted by the given number of days.
* Cannot go back before the first day of the Republican calendar (1792-09-22).
* <p>
* Uses converters to go through LocalDate implementation of plusDays.
*
* @param daysToAdd the number of days to add.
* @return the new date.
*/
public RDate plusDays(int daysToAdd) {
LocalDate gregorianDate = new RGConverter().convert(this);
gregorianDate = gregorianDate.plusDays(daysToAdd);
if (gregorianDate.isBefore(FIRST_DAY)) {
throw new RuntimeException("Date " + gregorianDate + " is undefined in the Republican calendar.");
}
return new GRConverter().convert(gregorianDate);
}

}
14 changes: 13 additions & 1 deletion src/main/java/com/github/jarnaud/republican/RGConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,19 @@ private int getDaysSinceRYearStart(RDate rDate) {
*/
private RDate getGregorianYearStartDay(int rYear) {
RDate start = RDate.of(rYear, RMonth.Nivose, 12);
return start.plusDays(processShifts(rYear - 1));
return plusDays(start, processShifts(rYear - 1));
}

/**
* Return a copy of this date shifted by the given number of days.
* NB: used only by this converter for shifting by 1 or 2 days within a month (month/year shifts are not handled).
* Do not use as actual plus to add days on production dates
*
* @param daysToAdd the number of days to add.
* @return the new date.
*/
private RDate plusDays(RDate date, int daysToAdd) {
return RDate.of(date.getYear(), date.getMonth(), date.getDay() + daysToAdd);
}

/**
Expand Down
24 changes: 22 additions & 2 deletions src/test/java/com/github/jarnaud/republican/RDateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@

public class RDateTest {

@Test
public void testOf1() {
assertEquals(RMonth.Vendemiaire, RDate.of(1, RMonth.Vendemiaire, 1).getMonth());
assertThrows(RuntimeException.class, () -> RDate.of(1, null, 1));
assertThrows(RuntimeException.class, () -> RDate.of(-5, null, 1));
assertThrows(RuntimeException.class, () -> RDate.of(12, RMonth.Sanculottide, 7));
}

@Test
public void testOf2() {
assertEquals(RMonth.Vendemiaire, RDate.of(1, 1, 1).getMonth());
assertThrows(RuntimeException.class, () -> RDate.of(1, 0, 1));
assertEquals(RDate.of(58, RMonth.Floreal, 1), RDate.of(58, 8, 1));
}

@Test
public void testDecade() {
assertEquals(1, RDate.of(6, RMonth.Floreal, 1).getDecade());
Expand All @@ -20,7 +35,7 @@ public void testDecade() {
}

@Test
public void isBeforeTest() {
public void testIsBefore() {
RDate d1 = RDate.of(6, RMonth.Floreal, 4);
RDate d2 = RDate.of(6, RMonth.Floreal, 5);
assertTrue(d1.isBefore(d2));
Expand All @@ -29,7 +44,7 @@ public void isBeforeTest() {
}

@Test
public void isSextileTest() {
public void testIsSextile() {
assertFalse(RDate.of(1, RMonth.Floreal, 4).isSextile());
assertFalse(RDate.of(2, RMonth.Floreal, 4).isSextile());
assertTrue(RDate.of(3, RMonth.Floreal, 4).isSextile());
Expand All @@ -41,4 +56,9 @@ public void isSextileTest() {
assertFalse(RDate.of(300, RMonth.Floreal, 4).isSextile());
assertTrue(RDate.of(400, RMonth.Floreal, 4).isSextile());
}

@Test
public void testPlusDays() {
assertEquals(RDate.of(1, 1, 1), RDate.of(1, 1, 1).plusDays(0));
}
}

0 comments on commit 0604f77

Please sign in to comment.