diff --git a/extensions/wikidata/module/langs/translation-en.json b/extensions/wikidata/module/langs/translation-en.json index 6367bf462..5b688d6c6 100644 --- a/extensions/wikidata/module/langs/translation-en.json +++ b/extensions/wikidata/module/langs/translation-en.json @@ -154,5 +154,7 @@ "warnings-messages/no-unit-provided/title": "Unit missing for {property_entity}", "warnings-messages/no-unit-provided/body": "Values such as {example_value} on {example_item_entity} are expected to have units.", "warnings-messages/invalid-entity-type/title": "{property_entity} used on items", - "warnings-messages/invalid-entity-type/body": "Uses of {property_entity} on items such as {example_entity} are invalid." + "warnings-messages/invalid-entity-type/body": "Uses of {property_entity} on items such as {example_entity} are invalid.", + "warnings-messages/early-gregorian-date/title": "Early dates in the Gregorian calendar", + "warnings-messages/early-gregorian-date/body": "Dates earlier than October 1582 (such as in year {example_year}) are unlikely to be expressed using the Gregorian calendar. See the manual to specify the appropriate calendar for your dates." } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java index 86b876b8c..531894588 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.openrefine.wikidata.qa.scrutinizers.CalendarScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.DistinctValuesScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.EditScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.EntityTypeScrutinizer; @@ -79,6 +80,7 @@ public class EditInspector { register(new QuantityScrutinizer()); register(new RestrictedValuesScrutinizer()); register(new EntityTypeScrutinizer()); + register(new CalendarScrutinizer()); } /** diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizer.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizer.java new file mode 100644 index 000000000..928cfc542 --- /dev/null +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizer.java @@ -0,0 +1,31 @@ +package org.openrefine.wikidata.qa.scrutinizers; + +import org.openrefine.wikidata.qa.QAWarning; +import org.wikidata.wdtk.datamodel.helpers.Datamodel; +import org.wikidata.wdtk.datamodel.interfaces.TimeValue; +import org.wikidata.wdtk.datamodel.interfaces.Value; + +public class CalendarScrutinizer extends ValueScrutinizer { + + public static final String earlyGregorianDateType = "early-gregorian-date"; + + public static final TimeValue earliestGregorian = Datamodel.makeTimeValue( + 1582, (byte)10, (byte)15, (byte)0, (byte)0, (byte)0, (byte)11, 0, 0, 0, TimeValue.CM_GREGORIAN_PRO); + + @Override + public void scrutinize(Value value) { + if(TimeValue.class.isInstance(value)) { + TimeValue time = (TimeValue)value; + if(time.getPreferredCalendarModel().equals(earliestGregorian.getPreferredCalendarModel()) && + time.getPrecision() >= 10 && + (time.getYear() < earliestGregorian.getYear() || + time.getYear() == earliestGregorian.getYear() && time.getMonth() < earliestGregorian.getMonth() || + time.getYear() == earliestGregorian.getYear() && time.getMonth() == earliestGregorian.getMonth() && time.getDay() < earliestGregorian.getDay())) { + QAWarning warning = new QAWarning(earlyGregorianDateType, null, QAWarning.Severity.WARNING, 1); + warning.setProperty("example_year", Long.toString(time.getYear())); + addIssue(warning); + } + } + } + +} diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizerTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizerTest.java new file mode 100644 index 000000000..5acb2b254 --- /dev/null +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/CalendarScrutinizerTest.java @@ -0,0 +1,37 @@ +package org.openrefine.wikidata.qa.scrutinizers; + +import org.testng.annotations.Test; +import org.wikidata.wdtk.datamodel.helpers.Datamodel; +import org.wikidata.wdtk.datamodel.interfaces.TimeValue; + +public class CalendarScrutinizerTest extends ValueScrutinizerTest { + + @Override + public EditScrutinizer getScrutinizer() { + return new CalendarScrutinizer(); + } + + @Test + public void testScrutinizeRecentValue() { + scrutinize(Datamodel.makeTimeValue(1978L, (byte)3, (byte)4, (byte)0, (byte)0, (byte)0, 11, TimeValue.CM_GREGORIAN_PRO)); + assertNoWarningRaised(); + } + + @Test + public void testScrutinizeCloseValue() { + scrutinize(Datamodel.makeTimeValue(1582L, (byte)10, (byte)17, (byte)0, (byte)0, (byte)0, 11, TimeValue.CM_GREGORIAN_PRO)); + assertNoWarningRaised(); + } + + @Test + public void testScrutinizeEarlyYear() { + scrutinize(Datamodel.makeTimeValue(1400L, (byte)1, (byte)1, (byte)0, (byte)0, (byte)0, (byte)9, 0, 0, 0, TimeValue.CM_GREGORIAN_PRO)); + assertNoWarningRaised(); + } + + @Test + public void testScrutinizeEarlyDay() { + scrutinize(Datamodel.makeTimeValue(1440L, (byte)10, (byte)17, (byte)0, (byte)0, (byte)0, 11, TimeValue.CM_GREGORIAN_PRO)); + assertWarningsRaised(CalendarScrutinizer.earlyGregorianDateType); + } +}