Skip to content

Commit

Permalink
api
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg-cherednik committed Jan 2, 2024
1 parent 4552e27 commit 5bb7066
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import java.util.Objects;
import java.util.ServiceLoader;
import java.util.TimeZone;

/**
* @author Oleg Cherednik
Expand Down Expand Up @@ -80,6 +81,9 @@ private static ObjectMapper createMapper(JsonSettings settings) {
}

private static ObjectMapper config(ObjectMapper mapper, JsonSettings settings) {
if (settings.getZoneId() != null)
mapper.setTimeZone(TimeZone.getTimeZone(settings.getZoneId()));

return mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)

Expand All @@ -91,8 +95,8 @@ private static ObjectMapper config(ObjectMapper mapper, JsonSettings settings) {
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
.disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
.disable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID) // let df choose it

.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)
.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION)
.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE)
.enable(JsonGenerator.Feature.AUTO_CLOSE_TARGET)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,10 @@ protected JacksonLocalTimeSerializer withFormat(Boolean useTimestamp,

@Override
public void serialize(LocalTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (useTimestamp(provider)) {
if (useNanoseconds(provider))
gen.writeNumber(value.toNanoOfDay());
else if (shape == JsonFormat.Shape.ARRAY)
super.serialize(value, gen, provider);
else
gen.writeNumber(value.toSecondOfDay());
} else if (_formatter == null)
gen.writeString(value.toString());
if (useTimestamp(provider) || _formatter != null)
super.serialize(value, gen, provider);
else
gen.writeString(_formatter.format(value));
}

@Override
protected boolean useNanoseconds(SerializerProvider provider) {
if (shape == JsonFormat.Shape.NUMBER_INT)
return false;
if (shape == JsonFormat.Shape.NUMBER_FLOAT)
return true;

return super.useNanoseconds(provider);
gen.writeString(value.toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.function.UnaryOperator;

import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_WITH_CONTEXT_TIME_ZONE;

/**
* @author Oleg Cherednik
* @since 01.12.2023
Expand Down Expand Up @@ -96,4 +99,21 @@ public void serialize(ZonedDateTime value, JsonGenerator generator, SerializerPr
// generator.writeString(_formatter.format(value));
}

@Override
protected String formatValue(ZonedDateTime value, SerializerProvider provider) {
if (_formatter == null)
return value.toString();

DateTimeFormatter df = _formatter;

if (_formatter.getZone() == null
&& provider.getConfig().hasExplicitTimeZone()
&& provider.isEnabled(WRITE_DATES_WITH_CONTEXT_TIME_ZONE)) {
ZoneId zoneId = provider.getTimeZone().toZoneId();
df = df.withZone("UTC".equals(zoneId.getId()) ? ZoneOffset.UTC : zoneId);
}

return df.format(value);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,30 @@
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public class DateTimeCombinationTest {

// public void shouldWriteDatesWithDefaultJsonSettings() throws IOException {
// DataOne data = new DataOne(ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00"));
//
// String actual = Json.writeValue(data);
// String expected = ResourceData.getResourceAsString("/datetime/def_date_one.json").trim();
// assertThat(actual).isEqualTo(expected);
// }

// public void shouldReadDatesWithDefaultJsonSettings() throws IOException {
// ZonedDateTime zdt = ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00");
//
// String json = ResourceData.getResourceAsString("/datetime/def_date_one.json").trim();
// DataOne actual = Json.readValue(json, DataOne.class);
// DataOne expected = new DataOne(zdt.toInstant(),
// zdt.toLocalDate(),
// zdt.toLocalTime(),
// zdt.toLocalDateTime(),
// zdt.toOffsetDateTime().toOffsetTime(),
// zdt.toOffsetDateTime(),
// zdt.withZoneSameInstant(ZoneId.systemDefault()),
// Date.from(zdt.toInstant()));
// assertThat(actual).isEqualTo(expected);
// }
private static final ZonedDateTime ZONED_DATE_TIME =
ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00[Europe/Moscow]");

public void shouldWriteDatesWithDefaultJsonSettings() throws IOException {
DataOne data = new DataOne(ZONED_DATE_TIME);

String actual = Json.writeValue(data);
String expected = ResourceData.getResourceAsString("/datetime/def_date_one.json").trim();
assertThat(actual).isEqualTo(expected);
}

public void shouldReadDatesWithDefaultJsonSettings() throws IOException {
String json = ResourceData.getResourceAsString("/datetime/def_date_one.json").trim();
DataOne actual = Json.readValue(json, DataOne.class);
DataOne expected = new DataOne(ZONED_DATE_TIME.toInstant(),
ZONED_DATE_TIME.toLocalDate(),
ZONED_DATE_TIME.toLocalTime(),
ZONED_DATE_TIME.toLocalDateTime(),
ZONED_DATE_TIME.toOffsetDateTime().toOffsetTime(),
ZONED_DATE_TIME.toOffsetDateTime(),
ZONED_DATE_TIME.withZoneSameInstant(ZoneId.systemDefault()),
Date.from(ZONED_DATE_TIME.toInstant()));
assertThat(actual).isEqualTo(expected);
}

public void shouldWriteDatesWithAnnotationSettingsPreferable() throws IOException {
DataTwo data = new DataTwo(ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00"));
Expand Down Expand Up @@ -117,29 +118,48 @@ private static JsonSettings getSettings() {
.build();
}

// public void shouldWriteDatesAsNumbersWhenAnnotationSettingsNumberInt() throws IOException {
// DataThree data = new DataThree(ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00"));
// String actual = Json.writeValue(data);
// String expected = ResourceData.getResourceAsString("/datetime/date_one_num.json").trim();
// assertThat(actual).isEqualTo(expected);
// }
public void shouldWriteDatesAsNumbersWhenAnnotationSettingsNumberInt() throws IOException {
DataThree data = new DataThree(ZONED_DATE_TIME);
String actual = Json.writeValue(data);
String expected = ResourceData.getResourceAsString("/datetime/date_one_num.json").trim();
assertThat(actual).isEqualTo(expected);
}

@EqualsAndHashCode
static class Data1 {

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private Instant instant = ZONED_DATE_TIME.toInstant();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private LocalDate localDate = ZONED_DATE_TIME.toLocalDate();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private LocalTime localTime = ZONED_DATE_TIME.toLocalTime();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private LocalDateTime localDateTime = ZONED_DATE_TIME.toLocalDateTime();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private OffsetTime offsetTime = ZONED_DATE_TIME.toOffsetDateTime().toOffsetTime();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private OffsetDateTime offsetDateTime = ZONED_DATE_TIME.toOffsetDateTime();
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private ZonedDateTime zonedDateTime = ZONED_DATE_TIME.withZoneSameInstant(ZoneOffset.UTC);
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
private Date date = Date.from(ZONED_DATE_TIME.toInstant());

}

public void shouldReadDatesAsNumber() throws IOException {
ZonedDateTime zdt = ZonedDateTime.parse("2023-12-03T10:39:20.187+03:00");
Data1 expected = new Data1();
String json = Json.writeValue(expected);
Data1 actual = Json.readValue(json, Data1.class);

String json = ResourceData.getResourceAsString("/datetime/date_one_num.json").trim();
// String json = ResourceData.getResourceAsString("/datetime/date_one_num.json").trim();

DataThree actual = Json.readValue(json, DataThree.class);
DataThree expected = new DataThree(zdt.toInstant(),
zdt.toLocalDate(),
zdt.toLocalTime(),
zdt.toLocalDateTime(),
zdt.toOffsetDateTime().toOffsetTime(),
zdt.toOffsetDateTime(),
zdt.withZoneSameInstant(ZoneOffset.UTC),
Date.from(zdt.toInstant()));
// DataThree actual = Json.readValue(json, DataThree.class);
// DataThree expected = new DataThree();

assertThat(actual).isEqualTo(expected);
// assertThat(actual).isEqualTo(expected);
int a = 0;
a++;
}

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
import org.testng.annotations.Test;
import ru.olegcherednik.json.api.Json;
import ru.olegcherednik.json.api.JsonSettings;
import ru.olegcherednik.json.api.ZoneModifier;
import ru.olegcherednik.json.jackson.LocalZoneId;
import ru.olegcherednik.json.jackson.ResourceData;

import java.io.IOException;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Map;

Expand All @@ -39,31 +39,31 @@
@Test
public class ZonedDateTimePrettyPrintTest {

// public void shouldRetrievePrettyPrintJsonUtcZoneWhenWriteZonedDateTimeMapWithPrettyPrint() throws IOException {
// JsonSettings settings = JsonSettings.builder()
// .zoneModifier(ZoneModifier.CONVERT_TO_UTC)
// .build();
//
// Map<String, ZonedDateTime> map = ZonedDateTimeTest.createData();
// String actual = Json.createPrettyPrint(settings).writeValue(map);
// String expected = ResourceData.getResourceAsString("/datetime/zoned_date_time_utc.json").trim();
//
// assertThat(actual).isNotEqualTo(expected);
// assertThat(Json.readMap(actual)).isEqualTo(Json.readMap(expected));
// }
public void shouldRetrievePrettyPrintJsonUtcZoneWhenWriteZonedDateTimeMapWithPrettyPrint() throws IOException {
JsonSettings settings = JsonSettings.builder()
.zoneId(ZoneOffset.UTC)
.build();

// public void shouldRetrievePrettyPrintJsonSingaporeZoneWhenWriteZonedDateTimeMapWithPrettyPrint()
// throws IOException {
// JsonSettings settings = JsonSettings.builder()
// .zoneModifier(zone -> LocalZoneId.ASIA_SINGAPORE)
// .build();
//
// Map<String, ZonedDateTime> map = ZonedDateTimeTest.createData();
// String actual = Json.createPrettyPrint(settings).writeValue(map);
// String expected = ResourceData.getResourceAsString("/datetime/zoned_date_time_singapore.json").trim();
//
// assertThat(actual).isNotEqualTo(expected);
// assertThat(Json.readMap(actual)).isEqualTo(Json.readMap(expected));
// }
Map<String, ZonedDateTime> map = ZonedDateTimeTest.createData();
String actual = Json.createPrettyPrint(settings).writeValue(map);
String expected = ResourceData.getResourceAsString("/datetime/zoned_date_time_utc.json").trim();

assertThat(actual).isNotEqualTo(expected);
assertThat(Json.readMap(actual)).isEqualTo(Json.readMap(expected));
}

public void shouldRetrievePrettyPrintJsonSingaporeZoneWhenWriteZonedDateTimeMapWithPrettyPrint()
throws IOException {
JsonSettings settings = JsonSettings.builder()
.zoneId(LocalZoneId.ASIA_SINGAPORE)
.build();

Map<String, ZonedDateTime> map = ZonedDateTimeTest.createData();
String actual = Json.createPrettyPrint(settings).writeValue(map);
String expected = ResourceData.getResourceAsString("/datetime/zoned_date_time_singapore.json").trim();

assertThat(actual).isNotEqualTo(expected);
assertThat(Json.readMap(actual)).isEqualTo(Json.readMap(expected));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@
import org.testng.annotations.Test;
import ru.olegcherednik.json.api.Json;
import ru.olegcherednik.json.api.JsonSettings;
import ru.olegcherednik.json.api.ZoneModifier;
import ru.olegcherednik.json.jackson.LocalZoneId;
import ru.olegcherednik.json.jackson.MapUtils;

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -42,55 +39,38 @@
@Test
public class ZonedDateTimeTest {

public void shouldRetrieveJsonOriginalZonWhenWriteZonedDateTimeWithUseOriginalZoneModifier() {
JsonSettings settings = JsonSettings.builder()
.zoneModifier(ZoneModifier.USE_ORIGINAL)
.build();

String actual = Json.createWriter(settings).writeValue(createData());
public void shouldRetrieveJsonOriginalZoneWhenWriteDefaultSettings() {
String actual = Json.createWriter().writeValue(createData());
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(
"{\"UTC\":\"2017-07-23T13:57:14.225Z\","
+ "\"Asia/Singapore\":\"2017-07-23T13:57:14.225+08:00[Asia/Singapore]\","
+ "\"Australia/Sydney\":\"2017-07-23T13:57:14.225+10:00[Australia/Sydney]\"}");
}

// public void shouldRetrieveJsonUtcZonWhenWriteZonedDateTimeWithConvertToUtcZoneModifier() {
// JsonSettings settings = JsonSettings.builder()
// .zoneModifier(ZoneModifier.CONVERT_TO_UTC)
// .build();
//
// String actual = Json.createWriter(settings).writeValue(createData());
// assertThat(actual).isNotNull();
// assertThat(actual).isEqualTo("{\"UTC\":\"2017-07-23T13:57:14.225Z\","
// + "\"Asia/Singapore\":\"2017-07-23T05:57:14.225Z\","
// + "\"Australia/Sydney\":\"2017-07-23T03:57:14.225Z\"}");
// }
public void shouldRetrieveJsonUtcZoneWhenWriteZonedDateTimeWithUtcZoneId() {
JsonSettings settings = JsonSettings.builder()
.zoneId(ZoneOffset.UTC)
.build();

// public void shouldRetrieveJsonSystemDefaultZoneWhenWriteZonedDateTimeDefaultSettings() {
// Map<String, ZonedDateTime> map1 = createData();
// Map<String, String> map2 = withDateFormatSystemDefault(map1, JsonSettings.DF_ZONED_DATE_TIME);
//
// String actual = Json.writeValue(map1);
// String expected = String.format("{\"UTC\":\"%s\",\"Asia/Singapore\":\"%s\",\"Australia/Sydney\":\"%s\"}",
// map2.get("UTC"), map2.get("Asia/Singapore"), map2.get("Australia/Sydney"));
//
// assertThat(actual).isNotNull();
// assertThat(actual).isEqualTo(expected);
// }
String actual = Json.createWriter(settings).writeValue(createData());
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo("{\"UTC\":\"2017-07-23T13:57:14.225Z\","
+ "\"Asia/Singapore\":\"2017-07-23T05:57:14.225Z\","
+ "\"Australia/Sydney\":\"2017-07-23T03:57:14.225Z\"}");
}

// public void shouldRetrieveJsonSingaporeZoneWhenWriteZonedDateTimeSingaporeZone() {
// JsonSettings settings = JsonSettings.builder()
// .zoneModifier(zoneId -> LocalZoneId.ASIA_SINGAPORE)
// .build();
//
// String actual = Json.createWriter(settings).writeValue(createData());
// assertThat(actual).isNotNull();
// assertThat(actual).isEqualTo(
// "{\"UTC\":\"2017-07-23T21:57:14.225+08:00[Asia/Singapore]\","
// + "\"Asia/Singapore\":\"2017-07-23T13:57:14.225+08:00[Asia/Singapore]\","
// + "\"Australia/Sydney\":\"2017-07-23T11:57:14.225+08:00[Asia/Singapore]\"}");
// }
public void shouldRetrieveJsonSingaporeWhenWriteZonedDateTimeWithSingaporeZoneId() {
JsonSettings settings = JsonSettings.builder()
.zoneId(LocalZoneId.ASIA_SINGAPORE)
.build();

String actual = Json.createWriter(settings).writeValue(createData());
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo("{\"UTC\":\"2017-07-23T21:57:14.225+08:00[Asia/Singapore]\","
+ "\"Asia/Singapore\":\"2017-07-23T13:57:14.225+08:00[Asia/Singapore]\","
+ "\"Australia/Sydney\":\"2017-07-23T11:57:14.225+08:00[Asia/Singapore]\"}");
}

public void shouldRetrieveDeserializedZonedDateTimeMapWhenReadJsonAsMap() {
String json = "{\"UTC\":\"2017-07-23T13:57:14.225Z\","
Expand All @@ -112,10 +92,4 @@ static Map<String, ZonedDateTime> createData() {
"Australia/Sydney", ZonedDateTime.parse(str, df.withZone(LocalZoneId.AUSTRALIA_SYDNEY)));
}

static Map<String, String> withDateFormatSystemDefault(Map<String, ZonedDateTime> map, DateTimeFormatter df) {
Map<String, String> res = new LinkedHashMap<>();
map.forEach((key, value) -> res.put(key, df.withZone(ZoneId.systemDefault()).format(value)));
return res;
}

}
Loading

0 comments on commit 5bb7066

Please sign in to comment.