From 12e73fb314f593d690dc8251417df0d0aaac20bb Mon Sep 17 00:00:00 2001 From: "moandji.ezana" Date: Mon, 15 Dec 2014 15:44:03 +0200 Subject: [PATCH] Added support for RFC 3339 dates. --- README.md | 4 +++ .../com/moandjiezana/toml/DateConverter.java | 33 ++++++++++++++++--- .../java/com/moandjiezana/toml/DateTest.java | 32 ++++++++++-------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 49a22af..bae6891 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,10 @@ Long tableD = toml.getLong("table.d"); // returns null, not 5 Long arrayD = toml.getLong("array[0].d"); // returns 3 ```` +### Limitations + +Date precision is limited to milliseconds. + ## License toml4j is copyright of Moandji Ezana and is licensed under the [MIT License](LICENSE) diff --git a/src/main/java/com/moandjiezana/toml/DateConverter.java b/src/main/java/com/moandjiezana/toml/DateConverter.java index 8bbc1fa..d838824 100644 --- a/src/main/java/com/moandjiezana/toml/DateConverter.java +++ b/src/main/java/com/moandjiezana/toml/DateConverter.java @@ -2,6 +2,7 @@ package com.moandjiezana.toml; import static com.moandjiezana.toml.ValueConverterUtils.INVALID; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -9,23 +10,36 @@ import java.util.regex.Pattern; class DateConverter implements ValueConverter { static final DateConverter DATE_PARSER = new DateConverter(); - private static final Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]Z)(.*)"); + private static final Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9])(\\.\\d*)?(Z|(?:[+\\-]\\d{2}:\\d{2}))(.*)"); @Override public boolean canConvert(String s) { Matcher matcher = DATE_REGEX.matcher(s); - return matcher.matches() && ValueConverterUtils.isComment(matcher.group(2)); + return matcher.matches() && ValueConverterUtils.isComment(matcher.group(4)); } @Override public Object convert(String s) { Matcher matcher = DATE_REGEX.matcher(s); matcher.matches(); - s = matcher.group(1).replace("Z", "+00:00"); + s = matcher.group(1); + String zone = matcher.group(3); + String fractionalSeconds = matcher.group(2); + String format = "yyyy-MM-dd'T'HH:mm:ss"; + if (fractionalSeconds != null && !fractionalSeconds.isEmpty()) { + format += ".SSS"; + s += fractionalSeconds; + } + format += "Z"; + if ("Z".equals(zone)) { + s += "+0000"; +// s = s.substring(0, 22) + s.substring(23); + } else if (zone.contains(":")) { + s += zone.replace(":", ""); + } try { - s = s.substring(0, 22) + s.substring(23); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + SimpleDateFormat dateFormat = new SimpleDateFormat(format); dateFormat.setLenient(false); return dateFormat.parse(s); } catch (Exception e) { @@ -34,4 +48,13 @@ class DateConverter implements ValueConverter { } private DateConverter() {} + + public static void main(String[] args) throws ParseException { + Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](?:\\.\\d*)?)(Z|(?:[+\\-]\\d{2}:\\d{2}))(.*)"); + Pattern DATE_REGEX2 = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9])(Z|(?:[+\\-]\\d{2}:\\d{2}))"); + + System.out.println(DATE_REGEX.matcher("2011-11-11T12:32:00.999-07:00").matches()); + + System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parse("1979-05-27T00:32:00+0000")); + } } diff --git a/src/test/java/com/moandjiezana/toml/DateTest.java b/src/test/java/com/moandjiezana/toml/DateTest.java index 28810b4..4f6cc6e 100644 --- a/src/test/java/com/moandjiezana/toml/DateTest.java +++ b/src/test/java/com/moandjiezana/toml/DateTest.java @@ -9,30 +9,25 @@ import org.junit.Test; public class DateTest { + private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); + @Test public void should_get_date() throws Exception { Toml toml = new Toml().parse("a_date = 2011-11-10T13:12:00Z"); - Calendar calendar = Calendar.getInstance(); + Calendar calendar = Calendar.getInstance(UTC); calendar.set(2011, Calendar.NOVEMBER, 10, 13, 12, 00); calendar.set(Calendar.MILLISECOND, 0); - calendar.setTimeZone(TimeZone.getTimeZone("UTC")); assertEquals(calendar.getTime(), toml.getDate("a_date")); } - public static void main(String[] args) { - for (String tz : TimeZone.getAvailableIDs(-7 * 60 * 60 * 1000)) { - System.out.println(tz); - } - } - @Test - public void should_get_date_with_timezone_offset() throws Exception { + public void should_get_date_with_offset() throws Exception { Toml toml = new Toml().parse("a_date = 1979-05-27T00:32:00-07:00"); - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Etc/GMT-7")); - calendar.set(1979, Calendar.MAY, 27, 0, 32, 00); + Calendar calendar = Calendar.getInstance(UTC); + calendar.set(1979, Calendar.MAY, 27, 7, 32, 00); calendar.set(Calendar.MILLISECOND, 0); assertEquals(calendar.getTime(), toml.getDate("a_date")); @@ -40,10 +35,21 @@ public class DateTest { @Test public void should_get_date_with_fractional_seconds() throws Exception { + Toml toml = new Toml().parse("a_date = 1979-05-27T00:32:00.999Z"); + + Calendar calendar = Calendar.getInstance(UTC); + calendar.set(1979, Calendar.MAY, 27, 0, 32, 00); + calendar.set(Calendar.MILLISECOND, 999); + + assertEquals(calendar.getTime(), toml.getDate("a_date")); + } + + @Test + public void should_get_date_with_fractional_seconds_and_offset() throws Exception { Toml toml = new Toml().parse("a_date = 1979-05-27T00:32:00.999-07:00"); - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Etc/GMT-7")); - calendar.set(1979, Calendar.MAY, 27, 0, 32, 00); + Calendar calendar = Calendar.getInstance(UTC); + calendar.set(1979, Calendar.MAY, 27, 7, 32, 00); calendar.set(Calendar.MILLISECOND, 999); assertEquals(calendar.getTime(), toml.getDate("a_date"));