diff --git a/src/freenet/client/async/USKDateHint.java b/src/freenet/client/async/USKDateHint.java index 6a464d9c23..4e994a650b 100644 --- a/src/freenet/client/async/USKDateHint.java +++ b/src/freenet/client/async/USKDateHint.java @@ -1,9 +1,11 @@ package freenet.client.async; -import java.util.Calendar; -import java.util.GregorianCalendar; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.temporal.TemporalField; +import java.time.temporal.WeekFields; +import java.util.Arrays; import java.util.Locale; -import java.util.TimeZone; import freenet.keys.ClientSSK; import freenet.keys.FreenetURI; @@ -12,16 +14,13 @@ /** Utility class for date-based edition hints */ public class USKDateHint { - + public enum Type { YEAR, MONTH, DAY, WEEK; - /** cached values(). Never modify or pass this array to outside code! */ - private static final Type[] values = values(); - public boolean alwaysMorePreciseThan(Type type) { if(this.equals(type)) return false; if(this.equals(DAY)) { // Day beats everything. @@ -34,57 +33,63 @@ public boolean alwaysMorePreciseThan(Type type) { return false; } } - - private GregorianCalendar cal; - private USKDateHint() { - cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US); + private static final TemporalField WEEK_OF_YEAR = WeekFields.of(Locale.US).weekOfWeekBasedYear(); + private static final TemporalField WEEK_YEAR = WeekFields.of(Locale.US).weekBasedYear(); + + private final LocalDate dateUtc; + + USKDateHint(LocalDate dateUtc) { + this.dateUtc = dateUtc; } public static USKDateHint now() { - return new USKDateHint(); + return new USKDateHint(LocalDate.now(ZoneOffset.UTC)); } - public String get(Type t) { - StringBuffer sb = new StringBuffer(); - sb.append(cal.get(Calendar.YEAR)); - if(t == Type.YEAR) return sb.toString(); - if(t == Type.WEEK) { - sb.append("-WEEK-"); - sb.append(cal.get(Calendar.WEEK_OF_YEAR)); + public String get(Type type) { + if(type == Type.WEEK) { + return dateUtc.get(WEEK_YEAR) + "-WEEK-" + dateUtc.get(WEEK_OF_YEAR); + } + + StringBuilder sb = new StringBuilder(); + sb.append(dateUtc.getYear()); + if (type == Type.YEAR) { return sb.toString(); } - sb.append("-"); - sb.append(cal.get(Calendar.MONTH)); - if(t == Type.MONTH) return sb.toString(); - sb.append("-"); - sb.append(cal.get(Calendar.DAY_OF_MONTH)); + + sb.append('-'); + sb.append(dateUtc.getMonthValue() - 1); // zero-indexed month + if(type == Type.MONTH) { + return sb.toString(); + } + + sb.append('-'); + sb.append(dateUtc.getDayOfMonth()); return sb.toString(); } /** Return the data to insert to each hint slot. */ public String getData(long edition) { - return "HINT\n"+Long.toString(edition)+"\n"+get(Type.DAY)+"\n"; + return String.format("HINT\n%d\n%s\n", edition, get(Type.DAY)); } - - static final String PREFIX = "-DATEHINT-"; - + /** Return the URL's to insert hint data to */ public FreenetURI[] getInsertURIs(InsertableUSK key) { - FreenetURI[] uris = new FreenetURI[Type.values.length]; - int x = 0; - for(Type t : Type.values) - uris[x++] = key.getInsertableSSK(key.siteName+PREFIX+get(t)).getInsertURI(); - return uris; + return Arrays.stream(Type.values()) + .map(type -> key.getInsertableSSK(getDocName(key, type)).getInsertURI()) + .toArray(FreenetURI[]::new); } /** Return the URL's to fetch hint data from */ public ClientSSK[] getRequestURIs(USK key) { - ClientSSK[] uris = new ClientSSK[Type.values.length]; - int x = 0; - for(Type t : Type.values) - uris[x++] = key.getSSK(key.siteName+PREFIX+get(t)); - return uris; + return Arrays.stream(Type.values()) + .map(type -> key.getSSK(getDocName(key, type))) + .toArray(ClientSSK[]::new); + } + + private String getDocName(USK key, Type type) { + return String.format("%s-DATEHINT-%s", key.siteName, get(type)); } } diff --git a/test/freenet/client/async/USKDateHintTest.java b/test/freenet/client/async/USKDateHintTest.java new file mode 100644 index 0000000000..b30e38fec3 --- /dev/null +++ b/test/freenet/client/async/USKDateHintTest.java @@ -0,0 +1,47 @@ +package freenet.client.async; + +import static freenet.client.async.USKDateHint.Type.DAY; +import static freenet.client.async.USKDateHint.Type.MONTH; +import static freenet.client.async.USKDateHint.Type.WEEK; +import static freenet.client.async.USKDateHint.Type.YEAR; +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; + +import org.junit.Test; + +public class USKDateHintTest { + + @Test + public void getYear() { + USKDateHint hint = new USKDateHint(LocalDate.parse("2023-06-01")); + assertEquals("2023", hint.get(YEAR)); + } + + @Test + public void getMonth() { + USKDateHint hint = new USKDateHint(LocalDate.parse("2023-06-01")); + assertEquals("2023-5", hint.get(MONTH)); + } + + @Test + public void getDay() { + USKDateHint hint = new USKDateHint(LocalDate.parse("2023-06-01")); + assertEquals("2023-5-1", hint.get(DAY)); + } + + @Test + public void getWeek() { + USKDateHint hintStartOfYear = new USKDateHint(LocalDate.parse("2023-01-01")); + USKDateHint hintEndOfYear = new USKDateHint(LocalDate.parse("2023-12-31")); + assertEquals("2023-WEEK-1", hintStartOfYear.get(WEEK)); + assertEquals("2024-WEEK-1", hintEndOfYear.get(WEEK)); + } + + @Test + public void getData() { + USKDateHint hint = new USKDateHint(LocalDate.parse("2023-06-01")); + assertEquals("HINT\n12345\n2023-5-1\n", hint.getData(12345)); + } + +}