Skip to content

Commit

Permalink
Temporal accessor
Browse files Browse the repository at this point in the history
  • Loading branch information
jarnaud committed Dec 5, 2020
1 parent 0604f77 commit c857f4c
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
67 changes: 66 additions & 1 deletion src/main/java/com/github/jarnaud/republican/RDate.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.github.jarnaud.republican;

import java.time.LocalDate;
import java.time.Year;
import java.time.temporal.*;
import java.util.Objects;

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

/**
* The first day in the Republican calendar (corresponding Republican day would be An 1 Vendemiaire 1).
Expand Down Expand Up @@ -76,6 +78,14 @@ public RMonth getMonth() {
return month;
}

/**
* Return the decade of this date.
* In the Republican calendar, a decade is a 10 days period within a month (each month being composed of 3 decades).
* <p>
* This is NOT a 10 year period!
*
* @return the decade (1, 2 or 3).
*/
public int getDecade() {
return decade;
}
Expand Down Expand Up @@ -122,6 +132,12 @@ public int hashCode() {
return Objects.hash(year, month, decade, day);
}

/**
* Return true if the given date is strictly before this date.
*
* @param date the date.
* @return true if date is before this date, false otherwise.
*/
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 Down Expand Up @@ -158,4 +174,53 @@ public RDate plusDays(int daysToAdd) {
return new GRConverter().convert(gregorianDate);
}


// Temporal accessor implementation.

@Override
public boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) {
switch ((ChronoField) field) {
case DAY_OF_MONTH:
case MONTH_OF_YEAR:
case YEAR:
return true;
}
}
return false;
}

@Override
public ValueRange range(TemporalField field) {
if (field instanceof ChronoField) {
if (isSupported(field)) {
ChronoField f = (ChronoField) field;
switch (f) {
case DAY_OF_MONTH:
return ValueRange.of(1, 30);
case MONTH_OF_YEAR:
return ValueRange.of(1, 13);
case YEAR:
return ValueRange.of(1, Year.MAX_VALUE);
}
}
}
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}

@Override
public long getLong(TemporalField field) {
if (field instanceof ChronoField) {
switch ((ChronoField) field) {
case DAY_OF_MONTH:
return getDay();
case MONTH_OF_YEAR:
return getMonth().ordinal() + 1;
case YEAR:
return getYear();
}
}
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.github.jarnaud.republican;

import org.junit.jupiter.api.Test;

import java.time.Year;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.time.temporal.ValueRange;

import static java.time.temporal.ChronoField.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Test the behaviour of RDate in regard to its implementation of TemporalAccessor.
*/
public class RDateTemporalAccessorTest {

@Test
public void testRange_supported() {
assertEquals(ValueRange.of(1, 30), RDate.of(6, RMonth.Floreal, 1).range(DAY_OF_MONTH));
assertEquals(ValueRange.of(1, 13), RDate.of(6, RMonth.Floreal, 1).range(MONTH_OF_YEAR));
assertEquals(ValueRange.of(1, Year.MAX_VALUE), RDate.of(6, RMonth.Floreal, 1).range(YEAR));
}

@Test
public void testRange_notSupported() {
assertThrows(UnsupportedTemporalTypeException.class, () -> RDate.of(6, RMonth.Floreal, 1).range(CLOCK_HOUR_OF_DAY));
assertThrows(UnsupportedTemporalTypeException.class, () -> RDate.of(6, RMonth.Floreal, 1).range(ALIGNED_WEEK_OF_YEAR));
}

@Test
public void testGetLong_supported() {
assertEquals(1, RDate.of(6, RMonth.Floreal, 1).getLong(DAY_OF_MONTH));
assertEquals(8, RDate.of(6, RMonth.Floreal, 1).getLong(MONTH_OF_YEAR));
assertEquals(6, RDate.of(6, RMonth.Floreal, 1).getLong(YEAR));
}

@Test
public void testGetLong_notSupported() {
assertThrows(UnsupportedTemporalTypeException.class, () -> RDate.of(6, RMonth.Floreal, 1).getLong(CLOCK_HOUR_OF_DAY));
assertThrows(UnsupportedTemporalTypeException.class, () -> RDate.of(6, RMonth.Floreal, 1).getLong(ALIGNED_WEEK_OF_YEAR));
}
}
11 changes: 10 additions & 1 deletion src/test/java/com/github/jarnaud/republican/RDateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,16 @@ public void testIsSextile() {
}

@Test
public void testPlusDays() {
public void testPlusDays_success() {
assertEquals(RDate.of(1, 1, 1), RDate.of(1, 1, 1).plusDays(0));
assertEquals(RDate.of(1, 1, 2), RDate.of(1, 1, 1).plusDays(1));
assertEquals(RDate.of(1, 8, 1), RDate.of(1, 1, 1).plusDays(7 * 30));
assertEquals(RDate.of(2, 1, 1), RDate.of(1, 1, 1).plusDays(365));
}

@Test
public void testPlusDays_invalid() {
assertThrows(RuntimeException.class, () -> RDate.of(1, 1, 1).plusDays(-1));
}

}

0 comments on commit c857f4c

Please sign in to comment.