]> source.dussan.org Git - poi.git/commitdiff
59183 - handle timezones (even with colons) in date parsing metadata in ooxml opc
authorTim Allison <tallison@apache.org>
Wed, 16 Mar 2016 17:52:42 +0000 (17:52 +0000)
committerTim Allison <tallison@apache.org>
Wed, 16 Mar 2016 17:52:42 +0000 (17:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1735270 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java

index 1b3690f72012bb86cb03878926cbdaef22c786aa..455891f644563cd93be021e4bd7602d8d3efe9b9 100644 (file)
@@ -23,6 +23,8 @@ import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
@@ -49,9 +51,22 @@ public final class PackagePropertiesPart extends PackagePart implements
        public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/";
 
        private final static String DEFAULT_DATEFORMAT =     "yyyy-MM-dd'T'HH:mm:ss'Z'";
-       private final static String ALTERNATIVE_DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SS'Z'";
-       
-       
+
+       private final static String[] DATE_FORMATS = new String[]{
+                       DEFAULT_DATEFORMAT,
+                       "yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
+       };
+
+       //Had to add this and TIME_ZONE_PAT to handle tz with colons.
+       //When we move to Java 7, we should be able to add another
+       //date format to DATE_FORMATS that uses XXX and get rid of this
+       //and TIME_ZONE_PAT
+       private final String[] TZ_DATE_FORMATS = new String[]{
+                       "yyyy-MM-dd'T'HH:mm:ssz",
+                       "yyyy-MM-dd'T'HH:mm:ss.SSSz"
+       };
+
+       private final Pattern TIME_ZONE_PAT = Pattern.compile("([-+]\\d\\d):?(\\d\\d)");
        /**
         * Constructor.
         *
@@ -562,20 +577,43 @@ public final class PackagePropertiesPart extends PackagePart implements
                if (dateStr == null || dateStr.equals("")) {
                        return new Nullable<Date>();
                }
+
+               Matcher m = TIME_ZONE_PAT.matcher(dateStr);
+               if (m.find()) {
+                       String dateTzStr = dateStr.substring(0, m.start())+
+                                       m.group(1)+m.group(2);
+                       for (String fStr : TZ_DATE_FORMATS) {
+                               SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
+                               df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+                               Date d = new SimpleDateFormat(fStr).parse(dateTzStr, new ParsePosition(0));
+                               if (d != null) {
+                                       return new Nullable<Date>(d);
+                               }
+                       }
+               }
                String dateTzStr = dateStr.endsWith("Z") ? dateStr : (dateStr + "Z");
-               SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATEFORMAT, Locale.ROOT);
-               df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
-               Date d = df.parse(dateTzStr, new ParsePosition(0));
-               if (d == null) {
-                   df = new SimpleDateFormat(ALTERNATIVE_DATEFORMAT, Locale.ROOT);
-                   df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
-                   d = df.parse(dateTzStr, new ParsePosition(0));
+               for (String fStr : DATE_FORMATS) {
+                       SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
+                       df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+                       Date d = df.parse(dateTzStr, new ParsePosition(0));
+                       if (d != null) {
+                               return new Nullable<Date>(d);
+                       }
                }
-               if (d == null) {
-                       throw new InvalidFormatException("Date " + dateTzStr + " not well formated, "
-                               + "expected format " + DEFAULT_DATEFORMAT + " or " + ALTERNATIVE_DATEFORMAT);
+               //if you're here, no pattern matched, throw exception
+               StringBuilder sb = new StringBuilder();
+               int i = 0;
+               for (String fStr : TZ_DATE_FORMATS) {
+                       if (i++ > 0) {
+                               sb.append(", ");
+                       }
+                       sb.append(fStr);
+               }
+               for (String fStr : DATE_FORMATS) {
+                       sb.append(", ").append(fStr);
                }
-               return new Nullable<Date>(d);
+               throw new InvalidFormatException("Date " + dateStr + " not well formatted, "
+                       + "expected format in: "+sb.toString());
        }
 
        /**
index bbc53d6b97950552a19427d24a99562a19b1f375..612371506d0bd7bcd69d3f4e498584301105c166 100644 (file)
@@ -70,11 +70,36 @@ public final class TestPackageCoreProperties {
         df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
                Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition(0));
 
+        SimpleDateFormat msdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
+        msdf.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+
                PackageProperties props = p.getPackageProperties();
-               props.setCategoryProperty("MyCategory");
+
+        //test various date formats
+        props.setCreatedProperty("2007-05-12T08:00:00Z");
+        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T08:00:00"); //no Z, assume Z
+        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T08:00:00.123Z");//millis
+        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T10:00:00+0200");
+        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T10:00:00+02:00");//colon in tz
+        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T06:00:00-0200");
+        assertEquals(dateToInsert, props.getCreatedProperty().getValue());
+
+        props.setCreatedProperty("2007-05-12T10:00:00.123+0200");
+        assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue());
+
+        props.setCategoryProperty("MyCategory");
                props.setContentStatusProperty("MyContentStatus");
                props.setContentTypeProperty("MyContentType");
-               props.setCreatedProperty(new Nullable<Date>(dateToInsert));
                props.setCreatorProperty("MyCreator");
                props.setDescriptionProperty("MyDescription");
                props.setIdentifierProperty("MyIdentifier");