Merge pull request #1880 from OpenRefine/issue1874

Avoid localizing time for dates with unspecified time.
This commit is contained in:
Antonin Delpeuch 2018-12-06 23:01:46 +09:00 committed by GitHub
commit 5421a23fba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 13 deletions

View File

@ -37,6 +37,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
@ -166,7 +167,9 @@ public class ToDate implements Function {
return date;
} else {
try {
return javax.xml.bind.DatatypeConverter.parseDateTime(o1).getTime().toInstant().atOffset(ZoneOffset.of("Z"));
return javax.xml.bind.DatatypeConverter.parseDateTime(o1).getTime().toInstant()
.plusSeconds(ZonedDateTime.now().getOffset().getTotalSeconds())
.atOffset(ZoneOffset.of("Z"));
} catch (IllegalArgumentException e2) {
return null;
}

View File

@ -229,7 +229,8 @@ public class ParsingUtilities {
if (parsed == null) {
return null;
}
return parsed.toLocalDateTime();
return parsed.withOffsetSameInstant(OffsetDateTime.now().getOffset())
.toLocalDateTime();
}
static public String instantToString(Instant instant) {

View File

@ -35,6 +35,7 @@ package com.google.refine.tests.expr.functions.strings;
import java.time.OffsetDateTime;
import java.util.Properties;
import java.util.TimeZone;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
@ -49,6 +50,7 @@ import com.google.refine.expr.util.CalendarParserException;
import com.google.refine.grel.ControlFunctionRegistry;
import com.google.refine.grel.Function;
import com.google.refine.tests.RefineTest;
import com.google.refine.util.ParsingUtilities;
/**
@ -161,10 +163,10 @@ public class ToFromConversionTests extends RefineTest {
Assert.assertEquals(invoke("toDate", "01-六月-2013","zh","dd-MMM-yyyy"), CalendarParser.parseAsOffsetDateTime("2013-06-01"));
//if invalid format/locale strings are passed, ignore them
Assert.assertEquals(invoke("toDate", "2012-03-01","XXX"), CalendarParser.parseAsOffsetDateTime("2012-03-01"));
Assert.assertEquals(invoke("toDate", "2012-03-01","XXX"), invoke("toDate", "2012-03-01"));
// If a long, convert to string
Assert.assertEquals(invoke("toDate", (long) 2012), CalendarParser.parseAsOffsetDateTime("2012-01-01"));
Assert.assertEquals(invoke("toDate", (long) 2012), invoke("toDate", "2012-01-01"));
// If already a date, leave it alone
Assert.assertEquals(invoke("toDate", CalendarParser.parseAsOffsetDateTime("2012-03-01")),CalendarParser.parseAsOffsetDateTime("2012-03-01"));

View File

@ -2,24 +2,46 @@ package com.google.refine.tests.io;
import java.io.IOException;
import java.io.InputStream;
import java.util.TimeZone;
import org.apache.commons.io.IOUtils;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.google.refine.tests.util.TestUtils;
import com.google.refine.util.ParsingUtilities;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.refine.ProjectMetadata;
public class ProjectMetadataTests {
private String jsonSaveMode = null;
private String jsonNonSaveMode = null;
@BeforeSuite
public void setUpJson() throws IOException {
InputStream f = ProjectMetadataTests.class.getClassLoader().getResourceAsStream("example_project_metadata.json");
jsonNonSaveMode = IOUtils.toString(f);
f = ProjectMetadataTests.class.getClassLoader().getResourceAsStream("example_project_metadata_save_mode.json");
jsonSaveMode = IOUtils.toString(f);
}
@Test
public void serializeProjectMetadata() throws IOException {
InputStream f = ProjectMetadataTests.class.getClassLoader().getResourceAsStream("example_project_metadata.json");
String json = IOUtils.toString(f);
f = ProjectMetadataTests.class.getClassLoader().getResourceAsStream("example_project_metadata_save_mode.json");
String fullJson = IOUtils.toString(f);
ProjectMetadata metadata = ParsingUtilities.mapper.readValue(jsonSaveMode, ProjectMetadata.class);
TestUtils.isSerializedTo(metadata, jsonNonSaveMode);
TestUtils.isSerializedTo(metadata, jsonSaveMode, true);
}
f = ProjectMetadataTests.class.getClassLoader().getResourceAsStream("example_project_metadata_save_mode.json");
ProjectMetadata metadata = ParsingUtilities.mapper.readValue(f, ProjectMetadata.class);
TestUtils.isSerializedTo(metadata, json);
TestUtils.isSerializedTo(metadata, fullJson, true);
@Test
public void serializeProjectMetadataInDifferentTimezone() throws JsonParseException, JsonMappingException, IOException {
TimeZone.setDefault(TimeZone.getTimeZone("JST"));
try {
ProjectMetadata metadata = ParsingUtilities.mapper.readValue(jsonSaveMode, ProjectMetadata.class);
TestUtils.isSerializedTo(metadata, jsonNonSaveMode);
TestUtils.isSerializedTo(metadata, jsonSaveMode, true);
} finally {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
}
}

View File

@ -37,6 +37,7 @@ import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.slf4j.LoggerFactory;
@ -89,6 +90,23 @@ public class ParsingUtilitiesTests extends RefineTest {
Assert.assertEquals(2017, ParsingUtilities.stringToLocalDate("2017-04-03T08:09:43+00:00").getYear());
}
/**
* Converting between string and local time must be reversible, no matter the timezone.
*/
@Test
public void stringToLocalDateNonUTC() {
TimeZone.setDefault(TimeZone.getTimeZone("JST"));
try {
Assert.assertEquals(ParsingUtilities.stringToLocalDate("2001-08-12T00:00:00Z").getHour(), 9);
Assert.assertEquals(ParsingUtilities.localDateToString(
ParsingUtilities.stringToLocalDate("2001-08-12T00:00:00Z")),
"2001-08-12T00:00:00Z");
} finally {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
}
@Test
public void parseProjectModifiedBeforeJDK8() {
String modified = "2014-01-15T21:46:25Z";