Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zoneId to [At]DateString. #773

Merged
merged 2 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,19 @@

String ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

String DEFAULT_ZONE_ID = "UTC";

String value() default ISO_8601;

/**
* Some temporals like {@link java.time.Instant}, representing an instantaneous point in time cannot be formatted
* with a given {@link java.time.ZoneId}. In case you want to format an instant or similar with a default pattern,
* we assume a zone with the given id and default to {@literal UTC} which is the same assumption that the predefined
* patterns in {@link java.time.format.DateTimeFormatter} take.
* @return The zone id to use when applying a custom pattern to an instant temporal.
*/
String zoneId() default DEFAULT_ZONE_ID;

/**
* Toggle lenient conversion mode by setting this flag to true (defaults to false).
* Has to be supported by the corresponding converter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Object getConverter(Class<?> fieldType) {
if (fieldType == Date.class) {
return new DateStringConverter(format, isLenientConversion(dateStringConverterInfo));
} else if (fieldType == Instant.class) {
return new InstantStringConverter(format, isLenientConversion(dateStringConverterInfo));
return new InstantStringConverter(format, dateStringConverterInfo.get("zoneId"), isLenientConversion(dateStringConverterInfo));
} else {
throw new MappingException("Cannot use @DateString with attribute of type " + fieldType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.neo4j.ogm.typeconversion;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

import org.apache.commons.lang3.StringUtils;
Expand All @@ -45,11 +46,11 @@ public InstantStringConverter() {
this.lenient = false;
}

public InstantStringConverter(String userDefinedFormat, boolean lenient) {
public InstantStringConverter(String userDefinedFormat, String zoneId, boolean lenient) {

this.formatter = DateString.ISO_8601.equals(userDefinedFormat) ?
DateTimeFormatter.ISO_INSTANT :
DateTimeFormatter.ofPattern(userDefinedFormat);
DateTimeFormatter.ofPattern(userDefinedFormat).withZone(ZoneId.of(zoneId));
this.lenient = lenient;
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ public class Memo {
@DateString
private Instant actionedAsInstant;

@DateString(value = "yyyy-MM-dd HH:mm:ss")
private Instant actionedAsInstantWithCustomFormat1;

@DateString(value = "yyyy-MM-dd HH:mm:ss", zoneId = "Europe/Berlin")
private Instant actionedAsInstantWithCustomFormat2;

// uses default ISO 8601 date format
private Date[] escalations;

Expand Down Expand Up @@ -154,4 +160,20 @@ public Set<Date> getImplementations() {
public void setImplementations(Set<Date> implementations) {
this.implementations = implementations;
}

public Instant getActionedAsInstantWithCustomFormat1() {
return actionedAsInstantWithCustomFormat1;
}

public void setActionedAsInstantWithCustomFormat1(Instant actionedAsInstantWithCustomFormat1) {
this.actionedAsInstantWithCustomFormat1 = actionedAsInstantWithCustomFormat1;
}

public Instant getActionedAsInstantWithCustomFormat2() {
return actionedAsInstantWithCustomFormat2;
}

public void setActionedAsInstantWithCustomFormat2(Instant actionedAsInstantWithCustomFormat2) {
this.actionedAsInstantWithCustomFormat2 = actionedAsInstantWithCustomFormat2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void directoryShouldBeScanned() {
public void nestedDirectoryShouldBeScanned() {
final DomainInfo domainInfo = DomainInfo.create("org.neo4j.ogm.domain.convertible");

assertThat(domainInfo.getClassInfoMap()).hasSize(21);
assertThat(domainInfo.getClassInfoMap()).hasSize(20);

Set<String> classNames = domainInfo.getClassInfoMap().keySet();
assertThat(classNames.contains("org.neo4j.ogm.domain.convertible.bytes.Photo")).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

Expand All @@ -52,13 +53,14 @@

/**
* @author Luanne Misquitta
* @author Michael J. Simons
*/
public class ConvertibleIntegrationTest extends TestContainersTestBase {

private static Session session;

@BeforeClass
public static void init() throws IOException {
public static void init() {
session = new SessionFactory(getDriver(), "org.neo4j.ogm.domain.convertible").openSession();
}

Expand All @@ -67,10 +69,7 @@ public void teardown() {
session.purgeDatabase();
}

/**
* @see DATAGRAPH-550
*/
@Test
@Test // DATAGRAPH-550
public void shouldSaveAndRetrieveEnums() {
List<Education> completed = new ArrayList<>();
completed.add(Education.HIGHSCHOOL);
Expand Down Expand Up @@ -121,7 +120,7 @@ public void shouldSaveAndRetrieveEnumsAsResult() {
.equals(Education.PHD)).isTrue();
}

@Test // DATAGRAPH-550 GH-758
@Test // DATAGRAPH-550 GH-758 GH-771
public void shouldSaveAndRetrieveDates() {
SimpleDateFormat simpleDateISO8601format = new SimpleDateFormat(DateString.ISO_8601);
simpleDateISO8601format.setTimeZone(TimeZone.getTimeZone("UTC"));
Expand Down Expand Up @@ -186,6 +185,32 @@ public void shouldSaveAndRetrieveDates() {
assertThat(loadedCal.get(Calendar.YEAR)).isEqualTo(date100000.get(Calendar.YEAR));
}

@Test // GH-771
public void instantsWithCustomFormatAndTZShouldWork() {

Memo memo = new Memo();
memo.setMemo("theMemo");
Instant actionedInstant = ZonedDateTime.of(2020, 3, 6, 16, 6, 23, 0, ZoneId.of("Europe/Berlin")).toInstant();
memo.setActionedAsInstant(actionedInstant);
memo.setActionedAsInstantWithCustomFormat1(actionedInstant);
memo.setActionedAsInstantWithCustomFormat2(actionedInstant);
session.save(memo);

Memo loadedMemo = session.loadAll(Memo.class, new Filter("memo", ComparisonOperator.EQUALS, "theMemo"))
.iterator().next();

assertThat(loadedMemo.getActionedAsInstantWithCustomFormat1()).isEqualTo(actionedInstant);
assertThat(loadedMemo.getActionedAsInstantWithCustomFormat2()).isEqualTo(actionedInstant);

Iterable<Map<String, Object>> results = session.query(
"MATCH (m:Memo) WHERE id(m) = $id RETURN m.actionedAsInstantWithCustomFormat1 as a1, m.actionedAsInstantWithCustomFormat2 as a2",
Collections.singletonMap("id", loadedMemo.getId())).queryResults();
assertThat(results).hasSize(1);
Map<String, Object> result = results.iterator().next();
assertThat(result).containsEntry("a1", "2020-03-06 15:06:23");
assertThat(result).containsEntry("a2", "2020-03-06 16:06:23");
}

@Test
public void shouldSaveAndRetrieveJava8Dates() {

Expand All @@ -209,7 +234,7 @@ public void shouldSaveAndRetrieveJava8Dates() {
}

@Test
public void shouldSaveListOfLocalDate() throws Exception {
public void shouldSaveListOfLocalDate() {

Java8DatesMemo memo = new Java8DatesMemo();

Expand All @@ -231,7 +256,7 @@ public void shouldSaveListOfLocalDate() throws Exception {
}

@Test
public void shouldSaveLocalDateTime() throws Exception {
public void shouldSaveLocalDateTime() {

Java8DatesMemo memo = new Java8DatesMemo();

Expand Down Expand Up @@ -362,27 +387,4 @@ public void shouldSaveAndRetrieveIntegerFloats() {
loadedAccount = session.load(Account.class, account.getId());
assertThat(loadedAccount.getLimit()).isEqualTo(account.getLimit());
}

public void assertSameArray(Object[] as, Object[] bs) {

if (as == null || bs == null) {
fail("null arrays not allowed");
}
if (as.length != bs.length) {
fail("arrays are not same length");
}

for (Object a : as) {
boolean found = false;
for (Object b : bs) {
if (b.toString().equals(a.toString())) {
found = true;
break;
}
}
if (!found) {
fail("array contents are not the same: " + as + ", " + bs);
}
}
}
}