Skip to content

Commit

Permalink
fix(topicdata): parse microseconds at any precision between 0 and 6 (#…
Browse files Browse the repository at this point in the history
…762)

partial fix for #761
  • Loading branch information
timtebeek authored and tchiotludo committed Oct 24, 2021
1 parent 613fdcb commit 5a6b4e4
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 8 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ client/build
### Ide ###
.idea/*
.vscode/*
.project/*
.classpath*
.project*
.settings/*
out/*
bin/*

### Log ###
.*.log
Expand Down
17 changes: 10 additions & 7 deletions src/main/java/org/akhq/utils/AvroSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import java.nio.ByteBuffer;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Map;
Expand All @@ -41,7 +43,12 @@ public class AvroSerializer {

protected static final String DATE_FORMAT = "yyyy-MM-dd[XXX]";
protected static final String TIME_FORMAT = "HH:mm[:ss][.SSSSSS][XXX]";
protected static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm[:ss][.SSSSSS][XXX]";
protected static final DateTimeFormatter DATETIME_FORMAT = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"))
.appendOptional(DateTimeFormatter.ofPattern(":ss"))
.appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
.appendOptional(DateTimeFormatter.ofPattern("XXX"))
.toFormatter();

public static GenericRecord recordSerializer(Map<String, ?> record, Schema schema) {
GenericRecord returnValue = new GenericData.Record(schema);
Expand Down Expand Up @@ -199,13 +206,9 @@ private static Long timestampMillisSerializer(Object data, Schema schema, Schema

protected static Instant parseDateTime(String data) {
try {
return ZonedDateTime.parse(data, DateTimeFormatter.ofPattern(AvroSerializer.DATETIME_FORMAT)).toInstant();
return ZonedDateTime.parse(data, DATETIME_FORMAT).toInstant();
} catch (DateTimeParseException e) {
LocalDateTime localDateTime = LocalDateTime.parse(
data,
DateTimeFormatter.ofPattern(AvroSerializer.DATETIME_FORMAT)
);

LocalDateTime localDateTime = LocalDateTime.parse(data, DATETIME_FORMAT);
return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
}
}
Expand Down
106 changes: 106 additions & 0 deletions src/test/java/org/akhq/utils/AvroSerializerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.akhq.utils;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

import static org.junit.jupiter.api.Assertions.assertEquals;

class AvroSerializerTest {

@Nested
static class ParseDateTime {

@Nested
static class Utc {

@Test
void testParseDateTime_micros_utc() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345678Z"),
Instant.parse("2021-07-16T21:30:12.345678Z"));
}

@Test
void testParseDateTime_millis_utc() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345Z"),
Instant.parse("2021-07-16T21:30:12.345Z"));
}

@Test
void testParseDateTime_seconds_utc() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12Z"),
Instant.parse("2021-07-16T21:30:12Z"));
}

@Test
void testParseDateTime_minutes_utc() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30Z"),
Instant.parse("2021-07-16T21:30:00Z"));
}

}

@Nested
static class Offset {

@Test
void testParseDateTime_micros_offset() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345678+08:00"),
Instant.parse("2021-07-16T13:30:12.345678Z"));
}

@Test
void testParseDateTime_millis_offset() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345+08:00"),
Instant.parse("2021-07-16T13:30:12.345Z"));
}

@Test
void testParseDateTime_seconds_offset() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12+08:00"),
Instant.parse("2021-07-16T13:30:12Z"));
}

@Test
void testParseDateTime_minutes_offset() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30+08:00"),
Instant.parse("2021-07-16T13:30:00Z"));
}

}

@Nested
static class Local {

@Test
void testParseDateTime_micros_local() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345678"),
LocalDateTime.parse("2021-07-16T21:30:12.345678").atZone(ZoneId.systemDefault()).toInstant());
}

@Test
void testParseDateTime_millis_local() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12.345"),
LocalDateTime.parse("2021-07-16T21:30:12.345").atZone(ZoneId.systemDefault()).toInstant());
}

@Test
void testParseDateTime_seconds_local() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30:12"),
LocalDateTime.parse("2021-07-16T21:30:12").atZone(ZoneId.systemDefault()).toInstant());
}

@Test
void testParseDateTime_minutes_local() {
assertEquals(AvroSerializer.parseDateTime("2021-07-16T21:30"),
LocalDateTime.parse("2021-07-16T21:30").atZone(ZoneId.systemDefault()).toInstant());
}

}

}

}

0 comments on commit 5a6b4e4

Please sign in to comment.