Skip to content

Commit 2dbc50e

Browse files
committed
Added support for Year-Month dates; made sure our assumed end times are utilizing the maximum millisecond accuracy available in ES; tests verifying more cases now
1 parent 795bd3a commit 2dbc50e

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

schemas-analyze/src/main/java/org/cedar/schemas/analyze/Analyzers.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ public class Analyzers {
2626
.appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME) // e.g. 2010-12-30T00:00:00
2727
.appendOptional(DateTimeFormatter.ISO_LOCAL_DATE) // e.g. 2010-12-30
2828
.appendOptional(new DateTimeFormatterBuilder()
29-
.appendValue(ChronoField.YEAR)
30-
.appendPattern("-MM-dd").toFormatter()) // e.g. -200-01-01
31-
.appendOptional(new DateTimeFormatterBuilder()
32-
.appendValue(ChronoField.YEAR).toFormatter()) // e.g. -200
29+
.appendValue(ChronoField.YEAR) // e.g. -200
30+
.optionalStart()
31+
.appendPattern("-MM") // e.g. -200-10
32+
.optionalEnd()
33+
.optionalStart()
34+
.appendPattern("-dd") // e.g. -200-01-01
35+
.optionalEnd()
36+
.toFormatter())
3337
.toFormatter()
3438
.withResolverStyle(ResolverStyle.STRICT);
3539

@@ -256,6 +260,7 @@ private static TemporalAccessor parseDate(String date) {
256260
ZonedDateTime::from,
257261
LocalDateTime::from,
258262
LocalDate::from,
263+
YearMonth::from,
259264
Year::from);
260265
} catch (Exception e) {
261266
return null;
@@ -298,13 +303,19 @@ static String utcDateTimeString(TemporalAccessor parsedDate, boolean start) {
298303
if (parsedDate instanceof Year) {
299304
LocalDateTime yearDate = start ?
300305
((Year) parsedDate).atMonth(1).atDay(1).atStartOfDay() :
301-
((Year) parsedDate).atMonth(12).atEndOfMonth().atTime(23, 59, 59);
306+
((Year) parsedDate).atMonth(12).atEndOfMonth().atTime(23, 59, 59, 999000000);
302307
return DateTimeFormatter.ISO_ZONED_DATE_TIME.format(yearDate.atZone(ZoneOffset.UTC));
303308
}
309+
if (parsedDate instanceof YearMonth) {
310+
LocalDateTime yearMonthDate = start ?
311+
((YearMonth) parsedDate).atDay(1).atStartOfDay() :
312+
((YearMonth) parsedDate).atEndOfMonth().atTime(23, 59, 59, 999000000);
313+
return DateTimeFormatter.ISO_ZONED_DATE_TIME.format((yearMonthDate.atZone(ZoneOffset.UTC)));
314+
}
304315
if (parsedDate instanceof LocalDate) {
305316
LocalDateTime localDate = start ?
306317
((LocalDate) parsedDate).atStartOfDay() :
307-
((LocalDate) parsedDate).atTime(23, 59, 59);
318+
((LocalDate) parsedDate).atTime(23, 59, 59, 999000000);
308319
return DateTimeFormatter.ISO_ZONED_DATE_TIME.format(localDate.atZone(ZoneOffset.UTC));
309320
}
310321
if (parsedDate instanceof LocalDateTime) {
@@ -318,7 +329,7 @@ static String utcDateTimeString(TemporalAccessor parsedDate, boolean start) {
318329
}
319330

320331
static String utcDateTimeString(Long year, boolean start) {
321-
return start ? year.toString() + "-01-01T00:00:00Z" : year.toString() + "-12-31T23:59:59Z";
332+
return start ? year.toString() + "-01-01T00:00:00Z" : year.toString() + "-12-31T23:59:59.999Z";
322333
}
323334

324335
static TimeRangeDescriptor rangeDescriptor(DateInfo beginInfo, DateInfo endInfo, DateInfo instantInfo) {

schemas-analyze/src/test/groovy/org/cedar/schemas/analyze/AnalyzersSpec.groovy

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class AnalyzersSpec extends Specification {
7979
endPrecision : ChronoUnit.DAYS.toString(),
8080
endIndexable : true,
8181
endZoneSpecified : null,
82-
endUtcDateTimeString : '2010-10-01T23:59:59Z',
82+
endUtcDateTimeString : '2010-10-01T23:59:59.999Z',
8383
instantDescriptor : ValidDescriptor.UNDEFINED,
8484
instantPrecision : null,
8585
instantIndexable : true,
@@ -132,6 +132,7 @@ class AnalyzersSpec extends Specification {
132132
def 'extracts date info from date strings'() {
133133
when:
134134
def result = new Analyzers.DateInfo(input, start)
135+
println(result.utcDateTimeString)
135136

136137
then:
137138
result.descriptor == descriptor
@@ -144,11 +145,16 @@ class AnalyzersSpec extends Specification {
144145
input | start || descriptor | precision | indexable | zone | string
145146
'2042-04-02T00:42:42Z' | false || ValidDescriptor.VALID | 'Nanos' | true | 'Z' | '2042-04-02T00:42:42Z'
146147
'2042-04-02T00:42:42' | false || ValidDescriptor.VALID | 'Nanos' | true | null | '2042-04-02T00:42:42Z'
147-
'2042-04-02' | false || ValidDescriptor.VALID | 'Days' | true | null | '2042-04-02T23:59:59Z'
148+
'2042-04-02' | false || ValidDescriptor.VALID | 'Days' | true | null | '2042-04-02T23:59:59.999Z'
148149
'2042-04-02' | true || ValidDescriptor.VALID | 'Days' | true | null | '2042-04-02T00:00:00Z'
150+
'2042-05' | true || ValidDescriptor.VALID | 'Months' | true | null | '2042-05-01T00:00:00Z'
151+
'-2042-05' | false || ValidDescriptor.VALID | 'Months' | true | null | '-2042-05-31T23:59:59.999Z'
149152
'2042' | true || ValidDescriptor.VALID | 'Years' | true | null | '2042-01-01T00:00:00Z'
153+
'1965' | false || ValidDescriptor.VALID | 'Years' | true | null | '1965-12-31T23:59:59.999Z'
150154
'-5000' | true || ValidDescriptor.VALID | 'Years' | true | null | '-5000-01-01T00:00:00Z'
155+
'-3000' | false || ValidDescriptor.VALID | 'Years' | true | null | '-3000-12-31T23:59:59.999Z'
151156
'-100000001' | true || ValidDescriptor.VALID | 'Years' | false | null | '-100000001-01-01T00:00:00Z'
157+
'-100000002' | false || ValidDescriptor.VALID | 'Years' | false | null | '-100000002-12-31T23:59:59.999Z'
152158
'ABC' | true || ValidDescriptor.INVALID | null | false | null | null
153159
'' | true || ValidDescriptor.UNDEFINED | null | true | null | null
154160
null | true || ValidDescriptor.UNDEFINED | null | true | null | null

0 commit comments

Comments
 (0)