Merge pull request #1384 from jackyq2015/issue/1383

Issue #1383
This commit is contained in:
Thad Guidry 2017-12-15 21:18:17 -06:00 committed by GitHub
commit eeb8ade5c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 151 additions and 100 deletions

View File

@ -1,15 +1,15 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7 org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0

View File

@ -35,10 +35,11 @@ package com.google.refine;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -193,7 +194,7 @@ public abstract class ProjectManager {
}//FIXME what should be the behaviour if metadata is null? i.e. not found }//FIXME what should be the behaviour if metadata is null? i.e. not found
Project project = getProject(id); Project project = getProject(id);
if (project != null && metadata != null && metadata.getModified().after(project.getLastSave())) { if (project != null && metadata != null && metadata.getModified().isAfter(project.getLastSave())) {
try { try {
saveProject(project); saveProject(project);
} catch (Exception e) { } catch (Exception e) {
@ -256,7 +257,7 @@ public abstract class ProjectManager {
*/ */
protected void saveProjects(boolean allModified) { protected void saveProjects(boolean allModified) {
List<SaveRecord> records = new ArrayList<SaveRecord>(); List<SaveRecord> records = new ArrayList<SaveRecord>();
Date startTimeOfSave = new Date(); LocalDateTime startTimeOfSave = LocalDateTime.now();
synchronized (this) { synchronized (this) {
for (long id : _projectsMetadata.keySet()) { for (long id : _projectsMetadata.keySet()) {
@ -265,18 +266,18 @@ public abstract class ProjectManager {
if (project != null) { if (project != null) {
boolean hasUnsavedChanges = boolean hasUnsavedChanges =
metadata.getModified().getTime() >= project.getLastSave().getTime(); metadata.getModified().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() >= project.getLastSave().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
// We use >= instead of just > to avoid the case where a newly created project // We use >= instead of just > to avoid the case where a newly created project
// has the same modified and last save times, resulting in the project not getting // has the same modified and last save times, resulting in the project not getting
// saved at all. // saved at all.
if (hasUnsavedChanges) { if (hasUnsavedChanges) {
long msecsOverdue = startTimeOfSave.getTime() - project.getLastSave().getTime(); long msecsOverdue = startTimeOfSave.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - project.getLastSave().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
records.add(new SaveRecord(project, msecsOverdue)); records.add(new SaveRecord(project, msecsOverdue));
} else if (!project.getProcessManager().hasPending() } else if (!project.getProcessManager().hasPending()
&& startTimeOfSave.getTime() - project.getLastSave().getTime() > PROJECT_FLUSH_DELAY) { && startTimeOfSave.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - project.getLastSave().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() > PROJECT_FLUSH_DELAY) {
/* /*
* It's been a while since the project was last saved and it hasn't been * It's been a while since the project was last saved and it hasn't been
@ -309,7 +310,8 @@ public abstract class ProjectManager {
for (int i = 0; for (int i = 0;
i < records.size() && i < records.size() &&
(allModified || (new Date().getTime() - startTimeOfSave.getTime() < QUICK_SAVE_MAX_TIME)); (allModified || (LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() -
startTimeOfSave.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < QUICK_SAVE_MAX_TIME));
i++) { i++) {
try { try {
@ -332,7 +334,7 @@ public abstract class ProjectManager {
ProjectMetadata metadata = getProjectMetadata(id); ProjectMetadata metadata = getProjectMetadata(id);
Project project = _projects.get(id); Project project = _projects.get(id);
if (project != null && !project.getProcessManager().hasPending() if (project != null && !project.getProcessManager().hasPending()
&& metadata.getModified().getTime() < project.getLastSave().getTime()) { && metadata.getModified().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < project.getLastSave().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) {
_projects.remove(id).dispose(); _projects.remove(id).dispose();
} }
} }

View File

@ -35,8 +35,8 @@ package com.google.refine;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -57,12 +57,11 @@ import com.google.refine.util.JSONUtilities;
import com.google.refine.util.ParsingUtilities; import com.google.refine.util.ParsingUtilities;
public class ProjectMetadata implements Jsonizable { public class ProjectMetadata implements Jsonizable {
private final LocalDateTime _created;
private final Date _created; private LocalDateTime _modified;
private Date _modified; private LocalDateTime written = null;
private Date written = null; private String _name = "";
private String _name = ""; private String _password = "";
private String _password = "";
private String _encoding = ""; private String _encoding = "";
private int _encodingConfidence; private int _encodingConfidence;
@ -79,24 +78,24 @@ public class ProjectMetadata implements Jsonizable {
private JSONArray _importOptionMetadata = new JSONArray(); private JSONArray _importOptionMetadata = new JSONArray();
// user metadata // user metadata
private JSONArray _userMetadata = new JSONArray();; private JSONArray _userMetadata = new JSONArray();
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>(); private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
private PreferenceStore _preferenceStore = new PreferenceStore(); private PreferenceStore _preferenceStore = new PreferenceStore();
private final static Logger logger = LoggerFactory.getLogger("project_metadata"); private final static Logger logger = LoggerFactory.getLogger("project_metadata");
protected ProjectMetadata(Date date) { protected ProjectMetadata(LocalDateTime date) {
_created = date; _created = date;
preparePreferenceStore(_preferenceStore); preparePreferenceStore(_preferenceStore);
} }
public ProjectMetadata() { public ProjectMetadata() {
this(new Date()); this(LocalDateTime.now());
_modified = _created; _modified = _created;
} }
public ProjectMetadata(Date created, Date modified, String name) { public ProjectMetadata(LocalDateTime created, LocalDateTime modified, String name) {
this(created); this(created);
_modified = modified; _modified = modified;
_name = name; _name = name;
@ -115,10 +114,8 @@ public class ProjectMetadata implements Jsonizable {
writer.value(tag); writer.value(tag);
} }
writer.endArray(); writer.endArray();
writer.key("created"); writer.key("created"); writer.value(ParsingUtilities.localDateToString(_created));
writer.value(ParsingUtilities.dateToString(_created)); writer.key("modified"); writer.value(ParsingUtilities.localDateToString(_modified));
writer.key("modified");
writer.value(ParsingUtilities.dateToString(_modified));
writer.key("creator"); writer.key("creator");
writer.value(_creator); writer.value(_creator);
writer.key("contributors"); writer.key("contributors");
@ -132,6 +129,7 @@ public class ProjectMetadata implements Jsonizable {
writer.key("customMetadata"); writer.key("customMetadata");
writer.object(); writer.object();
for (String key : _customMetadata.keySet()) { for (String key : _customMetadata.keySet()) {
Serializable value = _customMetadata.get(key); Serializable value = _customMetadata.get(key);
writer.key(key); writer.key(key);
@ -167,7 +165,7 @@ public class ProjectMetadata implements Jsonizable {
writer.endObject(); writer.endObject();
if (isSaveMode(options)) { if (isSaveMode(options)) {
written = new Date(); written = LocalDateTime.now();
} }
} }
@ -181,7 +179,7 @@ public class ProjectMetadata implements Jsonizable {
} }
public boolean isDirty() { public boolean isDirty() {
return written == null || _modified.after(written); return written == null || _modified.isAfter(written);
} }
public void write(JSONWriter jsonWriter) public void write(JSONWriter jsonWriter)
@ -207,10 +205,10 @@ public class ProjectMetadata implements Jsonizable {
} }
static public ProjectMetadata loadFromJSON(JSONObject obj) { static public ProjectMetadata loadFromJSON(JSONObject obj) {
// TODO: Is this correct? It's using modified date for creation date // TODO: Is this correct? It's using modified date for creation date
ProjectMetadata pm = new ProjectMetadata(JSONUtilities.getDate(obj, "modified", new Date())); ProjectMetadata pm = new ProjectMetadata(JSONUtilities.getLocalDate(obj, "modified", LocalDateTime.now()));
pm._modified = JSONUtilities.getDate(obj, "modified", new Date()); pm._modified = JSONUtilities.getLocalDate(obj, "modified", LocalDateTime.now());
pm._name = JSONUtilities.getString(obj, "name", "<Error recovering project name>"); pm._name = JSONUtilities.getString(obj, "name", "<Error recovering project name>");
pm._password = JSONUtilities.getString(obj, "password", ""); pm._password = JSONUtilities.getString(obj, "password", "");
@ -275,10 +273,10 @@ public class ProjectMetadata implements Jsonizable {
} catch (JSONException e) { } catch (JSONException e) {
logger.error(ExceptionUtils.getFullStackTrace(e)); logger.error(ExceptionUtils.getFullStackTrace(e));
} }
} }
pm.written = new Date(); // Mark it as not needing writing until modified pm.written = LocalDateTime.now(); // Mark it as not needing writing until modified
return pm; return pm;
} }
@ -287,7 +285,7 @@ public class ProjectMetadata implements Jsonizable {
// Any project specific preferences? // Any project specific preferences?
} }
public Date getCreated() { public LocalDateTime getCreated() {
return _created; return _created;
} }
@ -358,12 +356,12 @@ public class ProjectMetadata implements Jsonizable {
return _password; return _password;
} }
public Date getModified() { public LocalDateTime getModified() {
return _modified; return _modified;
} }
public void updateModified() { public void updateModified() {
_modified = new Date(); _modified = LocalDateTime.now();
} }
public PreferenceStore getPreferenceStore() { public PreferenceStore getPreferenceStore() {

View File

@ -35,8 +35,10 @@ package com.google.refine.commands.expr;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.OffsetDateTime;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@ -212,10 +214,10 @@ public class PreviewExpressionCommand extends Command {
Calendar c = (Calendar) v; Calendar c = (Calendar) v;
sb.append("[date " + sb.append("[date " +
ParsingUtilities.dateToString(c.getTime()) +"]"); ParsingUtilities.dateToString(OffsetDateTime.ofInstant(c.toInstant(), ZoneId.systemDefault())) +"]");
} else if (v instanceof Date) { } else if (v instanceof LocalDateTime) {
sb.append("[date " + sb.append("[date " +
ParsingUtilities.dateToString((Date) v) +"]"); ParsingUtilities.dateToString((OffsetDateTime) v) +"]");
} else if (v instanceof String) { } else if (v instanceof String) {
if (quote) { if (quote) {
sb.append(JSONObject.quote((String) v)); sb.append(JSONObject.quote((String) v));

View File

@ -35,6 +35,7 @@ package com.google.refine.expr.functions;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -83,7 +84,7 @@ public class ToDate implements Function {
try { try {
return CalendarParser.parse( o1, (month_first) ? CalendarParser.MM_DD_YY : CalendarParser.DD_MM_YY); return CalendarParser.parse( o1, (month_first) ? CalendarParser.MM_DD_YY : CalendarParser.DD_MM_YY);
} catch (CalendarParserException e) { } catch (CalendarParserException e) {
Date d = ParsingUtilities.stringToDate(o1); OffsetDateTime d = ParsingUtilities.stringToDate(o1);
if (d != null) { if (d != null) {
return d; return d;
} else { } else {

View File

@ -34,7 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.history; package com.google.refine.history;
import java.io.Writer; import java.io.Writer;
import java.util.Date; import java.time.ZoneId;
import java.time.OffsetDateTime;
import java.util.Properties; import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
@ -59,7 +60,7 @@ public class HistoryEntry implements Jsonizable {
final public long id; final public long id;
final public long projectID; final public long projectID;
final public String description; final public String description;
final public Date time; final public OffsetDateTime time;
// the manager (deals with IO systems or databases etc.) // the manager (deals with IO systems or databases etc.)
final public HistoryEntryManager _manager; final public HistoryEntryManager _manager;
@ -85,11 +86,11 @@ public class HistoryEntry implements Jsonizable {
} }
public HistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change) { public HistoryEntry(long id, Project project, String description, AbstractOperation operation, Change change) {
this(id,project.id,description,operation,new Date()); this(id,project.id,description,operation,OffsetDateTime.now(ZoneId.of("Z")));
setChange(change); setChange(change);
} }
protected HistoryEntry(long id, long projectID, String description, AbstractOperation operation, Date time) { protected HistoryEntry(long id, long projectID, String description, AbstractOperation operation, OffsetDateTime time) {
this.id = id; this.id = id;
this.projectID = projectID; this.projectID = projectID;
this.description = description; this.description = description;

View File

@ -39,7 +39,9 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.util.Date; import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -137,7 +139,9 @@ public class ProjectMetadataUtilities {
mtime = Math.max(mtime, time); mtime = Math.max(mtime, time);
} }
} }
pm = new ProjectMetadata(new Date(ctime),new Date(mtime), tempName); pm = new ProjectMetadata(LocalDateTime.ofInstant(Instant.ofEpochMilli(ctime), ZoneId.systemDefault()),
LocalDateTime.ofInstant(Instant.ofEpochMilli(mtime), ZoneId.systemDefault()),
tempName);
logger.error("Partially recovered missing metadata project in directory " + projectDir + " - " + tempName); logger.error("Partially recovered missing metadata project in directory " + projectDir + " - " + tempName);
} }
return pm; return pm;

View File

@ -35,15 +35,16 @@ package com.google.refine.model;
import java.io.Serializable; import java.io.Serializable;
import java.io.Writer; import java.io.Writer;
import java.util.Calendar; import java.time.LocalDateTime;
import java.util.Date; import java.time.OffsetDateTime;
import java.util.Properties; import java.util.Properties;
import org.json.JSONException;
import org.json.JSONWriter;
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.JsonToken;
import org.json.JSONException;
import org.json.JSONWriter;
import com.google.refine.Jsonizable; import com.google.refine.Jsonizable;
import com.google.refine.expr.EvalError; import com.google.refine.expr.EvalError;
@ -86,11 +87,11 @@ public class Cell implements HasFields, Jsonizable {
} else { } else {
writer.key("v"); writer.key("v");
if (value != null) { if (value != null) {
if (value instanceof Calendar) { if (value instanceof LocalDateTime) {
writer.value(ParsingUtilities.dateToString(((Calendar) value).getTime())); writer.value(ParsingUtilities.localDateToString((LocalDateTime)value));
writer.key("t"); writer.value("date"); writer.key("t"); writer.value("date");
} else if (value instanceof Date) { } else if (value instanceof OffsetDateTime) {
writer.value(ParsingUtilities.dateToString((Date) value)); writer.value(ParsingUtilities.dateToString((OffsetDateTime) value));
writer.key("t"); writer.value("date"); writer.key("t"); writer.value("date");
} else if (value instanceof Double } else if (value instanceof Double
&& (((Double)value).isNaN() || ((Double)value).isInfinite())) { && (((Double)value).isNaN() || ((Double)value).isInfinite())) {

View File

@ -41,8 +41,8 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -66,21 +66,15 @@ public class Project {
final static protected Map<String, Class<? extends OverlayModel>> final static protected Map<String, Class<? extends OverlayModel>>
s_overlayModelClasses = new HashMap<String, Class<? extends OverlayModel>>(); s_overlayModelClasses = new HashMap<String, Class<? extends OverlayModel>>();
static public void registerOverlayModel(String modelName, Class<? extends OverlayModel> klass) {
s_overlayModelClasses.put(modelName, klass);
}
final public long id; final public long id;
final public List<Row> rows = new ArrayList<Row>(); final public List<Row> rows = new ArrayList<Row>();
final public ColumnModel columnModel = new ColumnModel(); final public ColumnModel columnModel = new ColumnModel();
final public RecordModel recordModel = new RecordModel(); final public RecordModel recordModel = new RecordModel();
final public Map<String, OverlayModel> overlayModels = new HashMap<String, OverlayModel>(); final public Map<String, OverlayModel> overlayModels = new HashMap<String, OverlayModel>();
final public History history; final public History history;
transient public ProcessManager processManager = new ProcessManager(); transient public ProcessManager processManager = new ProcessManager();
transient private Date _lastSave = new Date(); transient private LocalDateTime _lastSave = LocalDateTime.now();
final static Logger logger = LoggerFactory.getLogger("project"); final static Logger logger = LoggerFactory.getLogger("project");
@ -98,6 +92,10 @@ public class Project {
this.history = new History(this); this.history = new History(this);
} }
static public void registerOverlayModel(String modelName, Class<? extends OverlayModel> klass) {
s_overlayModelClasses.put(modelName, klass);
}
/** /**
* Free/dispose of project data from memory. * Free/dispose of project data from memory.
*/ */
@ -113,14 +111,14 @@ public class Project {
// The rest of the project should get garbage collected when we return. // The rest of the project should get garbage collected when we return.
} }
public Date getLastSave(){ public LocalDateTime getLastSave(){
return this._lastSave; return this._lastSave;
} }
/** /**
* Sets the lastSave time to now * Sets the lastSave time to now
*/ */
public void setLastSave(){ public void setLastSave(){
this._lastSave = new Date(); this._lastSave = LocalDateTime.now();
} }
public ProjectMetadata getMetadata() { public ProjectMetadata getMetadata() {

View File

@ -38,6 +38,8 @@ import java.io.InputStream;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.time.ZoneId;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -307,9 +309,11 @@ public class StandardReconConfig extends ReconConfig {
jsonWriter.key("name"); jsonWriter.value(cell2.recon.match.name); jsonWriter.key("name"); jsonWriter.value(cell2.recon.match.name);
jsonWriter.endObject(); jsonWriter.endObject();
} else if (cell2.value instanceof Calendar) { } else if (cell2.value instanceof Calendar) {
jsonWriter.value(ParsingUtilities.dateToString(((Calendar) cell2.value).getTime())); Calendar calendar = (Calendar) cell2.value;
OffsetDateTime d = OffsetDateTime.ofInstant(calendar.toInstant(), ZoneId.of("Z"));
jsonWriter.value(ParsingUtilities.dateToString(d));
} else if (cell2.value instanceof Date) { } else if (cell2.value instanceof Date) {
jsonWriter.value(ParsingUtilities.dateToString((Date) cell2.value)); jsonWriter.value(ParsingUtilities.dateToString((OffsetDateTime) cell2.value));
} else { } else {
jsonWriter.value(cell2.value.toString()); jsonWriter.value(cell2.value.toString());
} }

View File

@ -33,6 +33,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.util; package com.google.refine.util;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
@ -94,9 +97,19 @@ public class JSONUtilities {
} }
} }
static public Date getDate(JSONObject obj, String key, Date def) { static public OffsetDateTime getDate(JSONObject obj, String key, OffsetDateTime def) {
try { try {
Date d = ParsingUtilities.stringToDate(obj.getString(key)); OffsetDateTime d = ParsingUtilities.stringToDate(obj.getString(key));
return d != null ? d : def;
} catch (JSONException e) {
return def;
}
}
static public LocalDateTime getLocalDate(JSONObject obj, String key, LocalDateTime def) {
try {
LocalDateTime d = ParsingUtilities.stringToLocalDate(obj.getString(key));
return d != null ? d : def; return d != null ? d : def;
} catch (JSONException e) { } catch (JSONException e) {
@ -180,9 +193,9 @@ public class JSONUtilities {
} else if (value instanceof Boolean) { } else if (value instanceof Boolean) {
obj.put(key, value); obj.put(key, value);
} else if (value instanceof Date) { } else if (value instanceof Date) {
obj.put(key, ParsingUtilities.dateToString((Date) value)); obj.put(key, ParsingUtilities.dateToString((OffsetDateTime) value));
} else if (value instanceof Calendar) { } else if (value instanceof Calendar) {
obj.put(key, ParsingUtilities.dateToString(((Calendar) value).getTime())); obj.put(key, ParsingUtilities.dateToString(OffsetDateTime.ofInstant(((Calendar)value).toInstant(), ZoneId.of("Z"))));
} else if (value instanceof String) { } else if (value instanceof String) {
obj.put(key, value); obj.put(key, value);
} else { } else {

View File

@ -38,9 +38,10 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Properties; import java.util.Properties;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -168,26 +169,30 @@ public class ParsingUtilities {
} }
/** /**
* Convert a date/time to an ISO 8601 string * Convert a date/time to an ISO_LOCAL_DATE_TIME string
* *
* @param d the date to be written * @param d the date to be written
* @return string with ISO 8601 formatted date & time * @return string with ISO_LOCAL_DATE_TIME formatted date & time
*/ */
static public String dateToString(Date d) { static public String dateToString(OffsetDateTime d) {
return ISO8601_FORMAT.get().format(d); return d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
static public String localDateToString(LocalDateTime d) {
return d.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} }
/** /**
* Parse an ISO 8601 formatted string into a Java Date. * Parse an ISO_LOCAL_DATE_TIME formatted string into a Java Date.
* *
* @param s the string to be parsed * @param s the string to be parsed
* @return Date or null if the parse failed * @return LocalDateTime or null if the parse failed
*/ */
static public Date stringToDate(String s) { static public OffsetDateTime stringToDate(String s) {
try { return OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
return ISO8601_FORMAT.get().parse(s); }
} catch (ParseException e) {
return null; static public LocalDateTime stringToLocalDate(String s) {
} return LocalDateTime.parse(s, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} }
} }

View File

@ -41,8 +41,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.Date; import java.time.LocalDateTime;
import java.util.GregorianCalendar;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -226,7 +225,7 @@ public class ProjectManagerTests extends RefineTest {
} }
protected void whenProjectGetLastSave(Project proj){ protected void whenProjectGetLastSave(Project proj){
Date projectLastSaveDate = new GregorianCalendar(1970,01,02,00,30,00).getTime(); LocalDateTime projectLastSaveDate = LocalDateTime.of(1970,01,02,00,30,00);
when(proj.getLastSave()).thenReturn(projectLastSaveDate); when(proj.getLastSave()).thenReturn(projectLastSaveDate);
} }
@ -234,7 +233,7 @@ public class ProjectManagerTests extends RefineTest {
whenMetadataGetModified(meta, 5*60); whenMetadataGetModified(meta, 5*60);
} }
protected void whenMetadataGetModified(ProjectMetadata meta, int secondsDifference){ protected void whenMetadataGetModified(ProjectMetadata meta, int secondsDifference){
Date metadataModifiedDate = new GregorianCalendar(1970,01,02,00, 30, secondsDifference).getTime(); LocalDateTime metadataModifiedDate = LocalDateTime.of(1970,01,02,00, 30 + secondsDifference);
when(meta.getModified()).thenReturn(metadataModifiedDate); when(meta.getModified()).thenReturn(metadataModifiedDate);
} }

View File

@ -40,8 +40,9 @@ import static org.mockito.Mockito.when;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Calendar; import java.time.LocalDateTime;
import java.util.Date; import java.time.ZoneId;
import java.time.OffsetDateTime;
import java.util.Properties; import java.util.Properties;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -200,11 +201,11 @@ public class CsvExporterTests extends RefineTest {
@Test @Test
public void exportDateColumns(){ public void exportDateColumns(){
CreateGrid(1,2); CreateGrid(1,2);
Calendar calendar = Calendar.getInstance(); LocalDateTime localDate = LocalDateTime.now();
Date date = new Date(); OffsetDateTime date = OffsetDateTime.now(ZoneId.of("Z"));
when(options.getProperty("printColumnHeader")).thenReturn("false"); when(options.getProperty("printColumnHeader")).thenReturn("false");
project.rows.get(0).cells.set(0, new Cell(calendar, null)); project.rows.get(0).cells.set(0, new Cell(localDate, null));
project.rows.get(0).cells.set(1, new Cell(date, null)); project.rows.get(0).cells.set(1, new Cell(date, null));
try { try {
@ -213,7 +214,7 @@ public class CsvExporterTests extends RefineTest {
Assert.fail(); Assert.fail();
} }
String expectedOutput = ParsingUtilities.dateToString(calendar.getTime()) + "," + String expectedOutput = ParsingUtilities.localDateToString(localDate) + "," +
ParsingUtilities.dateToString(date) + "\n"; ParsingUtilities.dateToString(date) + "\n";
Assert.assertEquals(writer.toString(), expectedOutput); Assert.assertEquals(writer.toString(), expectedOutput);

View File

@ -33,6 +33,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.tests.util; package com.google.refine.tests.util;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -85,4 +88,23 @@ public class ParsingUtilitiesTests extends RefineTest {
//expected //expected
} }
} }
@Test
public void zonedDateTimeTest() {
// String d = "2017-07-18T20:26:28.582+03:00[Asia/Istanbul]";
// DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME ;
// OffsetDateTime.parse(d, formatter);
String d = "2017-12-01T14:53:36Z";
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
OffsetDateTime.parse(d, formatter);
}
@Test
public void parseProjectBeforeJDK8() {
String historyEntryDate = "2017-12-01T14:53:36Z";
OffsetDateTime zdt = ParsingUtilities.stringToDate(historyEntryDate);
String zdtString = ParsingUtilities.dateToString(zdt);
Assert.assertEquals(zdtString, historyEntryDate);
}
} }