diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java index 8f7fd30e58..b67056afc4 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java @@ -256,7 +256,7 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel { }); - process = currentCase.makeAddImageProcess(Case.convertTimeZone(timeZone), noFatOrphans); + process = currentCase.makeAddImageProcess(timeZone, noFatOrphans); cancelledWhileRunning.enable(); try { process.run(imgPaths); diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Case.java b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java index ba7f0b8465..1cc68c654e 100755 --- a/Case/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -736,6 +736,7 @@ public class Case { TimeZone zone = TimeZone.getTimeZone(timezoneID); int offset = zone.getRawOffset() / 1000; int hour = offset / 3600; + int min = (offset % 3600) / 60; DateFormat dfm = new SimpleDateFormat("z"); dfm.setTimeZone(zone); @@ -744,6 +745,9 @@ public class Case { String second = dfm.format(new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3); // make it only 3 letters code int mid = hour * -1; result = first + Integer.toString(mid); + if (min != 0) { + result = result + ":" + Integer.toString(min); + } if (hasDaylight) { result = result + second; } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index cab3189405..0eefae9c27 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.text.SimpleDateFormat; import java.util.LinkedHashMap; import java.util.Map; import org.openide.nodes.Sheet; @@ -29,6 +30,8 @@ import org.sleuthkit.datamodel.FsContent; */ public abstract class AbstractFsContentNode extends AbstractContentNode { + private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss (z)"); + // Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed public static enum FsContentPropertyType { @@ -213,12 +216,13 @@ public abstract class AbstractFsContentNode extends Abstrac * @param content to extract properties from */ public static void fillPropertyMap(Map map, FsContent content) { + dateFormatter.setTimeZone(content.accept(new TimeZoneVisitor())); map.put(FsContentPropertyType.NAME.toString(), content.getName()); map.put(FsContentPropertyType.LOCATION.toString(), DataConversion.getformattedPath(ContentUtils.getDisplayPath(content), 0, 1)); - map.put(FsContentPropertyType.MOD_TIME.toString(), content.getMtimeAsDate()); - map.put(FsContentPropertyType.CHANGED_TIME.toString(), content.getCtimeAsDate()); - map.put(FsContentPropertyType.ACCESS_TIME.toString(), content.getAtimeAsDate()); - map.put(FsContentPropertyType.CREATED_TIME.toString(), content.getCrtimeAsDate()); + map.put(FsContentPropertyType.MOD_TIME.toString(), epochToString(content.getMtime())); + map.put(FsContentPropertyType.CHANGED_TIME.toString(), epochToString(content.getCtime())); + map.put(FsContentPropertyType.ACCESS_TIME.toString(), epochToString(content.getAtime())); + map.put(FsContentPropertyType.CREATED_TIME.toString(), epochToString(content.getCrtime())); map.put(FsContentPropertyType.SIZE.toString(), content.getSize()); map.put(FsContentPropertyType.FLAGS_DIR.toString(), content.getDirFlagsAsString()); map.put(FsContentPropertyType.FLAGS_META.toString(), content.getMetaFlagsAsString()); @@ -231,4 +235,12 @@ public abstract class AbstractFsContentNode extends Abstrac map.put(FsContentPropertyType.TYPE_META.toString(), content.getMetaTypeAsString()); map.put(FsContentPropertyType.KNOWN.toString(), content.getKnown().getName()); } + + private static String epochToString(long epoch) { + String time = "0000-00-00 00:00:00 (UTC)"; + if (epoch != 0) { + time = dateFormatter.format(new java.util.Date(epoch * 1000)); + } + return time; + } } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 4b72f89ef2..aaecdadc07 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -20,10 +20,10 @@ package org.sleuthkit.autopsy.datamodel; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; import java.util.logging.Level; import java.util.logging.Logger; import org.openide.nodes.AbstractNode; @@ -51,12 +51,11 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI BlackboardArtifact artifact; Content associated; static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); - - private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");; + private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public BlackboardArtifactNode(BlackboardArtifact artifact) { super(Children.LEAF, getLookups(artifact)); - + this.artifact = artifact; this.associated = getAssociatedContent(artifact); this.setName(Long.toString(artifact.getArtifactID())); @@ -119,11 +118,18 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI map.put(attribute.getAttributeTypeDisplayName(), attribute.getValueInt()); break; case LONG: - if(attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID() || - attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID()) { - map.put(attribute.getAttributeTypeDisplayName(), dateFormatter.format(new Date(attribute.getValueLong()))); - } else + if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID() + || attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID()) { + long epoch = attribute.getValueLong(); + String time = "0000-00-00 00:00:00"; + if (epoch != 0) { + dateFormatter.setTimeZone(getTimeZone(artifact)); + time = dateFormatter.format(new java.util.Date(epoch * 1000)); + } + map.put(attribute.getAttributeTypeDisplayName(), time); + } else { map.put(attribute.getAttributeTypeDisplayName(), attribute.getValueLong()); + } break; case DOUBLE: map.put(attribute.getAttributeTypeDisplayName(), attribute.getValueDouble()); @@ -164,7 +170,11 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI } throw new IllegalArgumentException("Couldn't get file from database"); } - + + private static TimeZone getTimeZone(BlackboardArtifact artifact) { + return getAssociatedContent(artifact).accept(new TimeZoneVisitor()); + } + private static HighlightLookup getHighlightLookup(BlackboardArtifact artifact, Content content) { if(artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) return null; diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/TimeZoneVisitor.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/TimeZoneVisitor.java new file mode 100644 index 0000000000..51e89c5778 --- /dev/null +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/TimeZoneVisitor.java @@ -0,0 +1,66 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import java.util.TimeZone; +import org.sleuthkit.datamodel.ContentVisitor; +import org.sleuthkit.datamodel.Directory; +import org.sleuthkit.datamodel.File; +import org.sleuthkit.datamodel.FileSystem; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.Volume; +import org.sleuthkit.datamodel.VolumeSystem; + +/** + * + * @author dfickling + */ +class TimeZoneVisitor implements ContentVisitor{ + + @Override + public TimeZone visit(Directory drctr) { + return visit(drctr.getFileSystem()); + } + + @Override + public TimeZone visit(File file) { + return visit(file.getFileSystem()); + } + + @Override + public TimeZone visit(FileSystem fs) { + return fs.getParent().accept(this); + } + + @Override + public TimeZone visit(Image image) { + return TimeZone.getTimeZone(image.getTimeZone()); + } + + @Override + public TimeZone visit(Volume volume) { + return visit(volume.getParent()); + } + + @Override + public TimeZone visit(VolumeSystem vs) { + return TimeZone.getTimeZone(vs.getParent().getTimeZone()); + } + +}