TomlWriter can display fractional seconds

This commit is contained in:
moandji.ezana 2015-07-01 12:25:40 +02:00
parent b59a246b86
commit dbab02ce52
5 changed files with 123 additions and 35 deletions

View file

@ -3,7 +3,6 @@ package com.moandjiezana.toml;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -91,7 +90,7 @@ class DateConverter implements ValueConverter, ValueWriter {
@Override @Override
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
DateFormat formatter = getFormatter(context.getTimeZone()); DateFormat formatter = getFormatter(context.getDatePolicy());
context.write(formatter.format(value)); context.write(formatter.format(value));
} }
@ -100,35 +99,57 @@ class DateConverter implements ValueConverter, ValueWriter {
return true; return true;
} }
private DateFormat getFormatter(TimeZone timeZone) { private DateFormat getFormatter(DatePolicy datePolicy) {
String format = "UTC".equals(timeZone.getID()) ? "yyyy-MM-dd'T'HH:m:ss'Z'" : "yyyy-MM-dd'T'HH:m:ssXXX"; boolean utc = "UTC".equals(datePolicy.getTimeZone().getID());
String format;
if (utc && datePolicy.isShowFractionalSeconds()) {
format = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
} else if (utc) {
format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
} else if (datePolicy.isShowFractionalSeconds()) {
format = getTimeZoneAndFractionalSecondsFormat();
} else {
format = getTimeZoneFormat();
}
SimpleDateFormat formatter = new SimpleDateFormat(format); SimpleDateFormat formatter = new SimpleDateFormat(format);
formatter.setTimeZone(timeZone); formatter.setTimeZone(datePolicy.getTimeZone());
return formatter; return formatter;
} }
String getTimeZoneFormat() {
return "yyyy-MM-dd'T'HH:mm:ssXXX";
}
String getTimeZoneAndFractionalSecondsFormat() {
return "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
}
private DateConverter() {} private DateConverter() {}
private static class DateConverterJdk6 extends DateConverter { private static class DateConverterJdk6 extends DateConverter {
@Override @Override
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
TimeZone timeZone = context.getTimeZone(); DateFormat formatter = super.getFormatter(context.getDatePolicy());
DateFormat formatter = getFormatter(timeZone);
String date = formatter.format(value); String date = formatter.format(value);
if ("UTC".equals(timeZone.getID())) { if ("UTC".equals(context.getDatePolicy().getTimeZone().getID())) {
context.write(date); context.write(date);
} else { } else {
context.write(date.substring(0, 22)).write(':').write(date.substring(22)); int insertionIndex = date.length() - 2;
context.write(date.substring(0, insertionIndex)).write(':').write(date.substring(insertionIndex));
} }
} }
private DateFormat getFormatter(TimeZone timeZone) { @Override
String format = "UTC".equals(timeZone.getID()) ? "yyyy-MM-dd'T'HH:m:ss'Z'" : "yyyy-MM-dd'T'HH:m:ssZ"; String getTimeZoneAndFractionalSecondsFormat() {
SimpleDateFormat formatter = new SimpleDateFormat(format); return "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
formatter.setTimeZone(timeZone); }
return formatter;
@Override
String getTimeZoneFormat() {
return "yyyy-MM-dd'T'HH:mm:ssZ";
} }
} }

View file

@ -0,0 +1,22 @@
package com.moandjiezana.toml;
import java.util.TimeZone;
class DatePolicy {
private final TimeZone timeZone;
private final boolean showFractionalSeconds;
DatePolicy(TimeZone timeZone, boolean showFractionalSeconds) {
this.timeZone = timeZone;
this.showFractionalSeconds = showFractionalSeconds;
}
TimeZone getTimeZone() {
return timeZone;
}
boolean isShowFractionalSeconds() {
return showFractionalSeconds;
}
}

View file

@ -37,6 +37,7 @@ public class TomlWriter {
private int tableIndentation; private int tableIndentation;
private int arrayDelimiterPadding = 0; private int arrayDelimiterPadding = 0;
private TimeZone timeZone = TimeZone.getTimeZone("UTC"); private TimeZone timeZone = TimeZone.getTimeZone("UTC");
private boolean showFractionalSeconds = false;
public TomlWriter.Builder indentValuesBy(int spaces) { public TomlWriter.Builder indentValuesBy(int spaces) {
this.keyIndentation = spaces; this.keyIndentation = spaces;
@ -67,23 +68,28 @@ public class TomlWriter {
} }
public TomlWriter build() { public TomlWriter build() {
return new TomlWriter(keyIndentation, tableIndentation, arrayDelimiterPadding, timeZone); return new TomlWriter(keyIndentation, tableIndentation, arrayDelimiterPadding, timeZone, showFractionalSeconds);
}
public TomlWriter.Builder showFractionalSeconds() {
this.showFractionalSeconds = true;
return this;
} }
} }
private final WriterIndentationPolicy indentationPolicy; private final WriterIndentationPolicy indentationPolicy;
private TimeZone timeZone; private final DatePolicy datePolicy;
/** /**
* Creates a TomlWriter instance. * Creates a TomlWriter instance.
*/ */
public TomlWriter() { public TomlWriter() {
this(0, 0, 0, TimeZone.getTimeZone("UTC")); this(0, 0, 0, TimeZone.getTimeZone("UTC"), false);
} }
private TomlWriter(int keyIndentation, int tableIndentation, int arrayDelimiterPadding, TimeZone timeZone) { private TomlWriter(int keyIndentation, int tableIndentation, int arrayDelimiterPadding, TimeZone timeZone, boolean showFractionalSeconds) {
this.indentationPolicy = new WriterIndentationPolicy(keyIndentation, tableIndentation, arrayDelimiterPadding); this.indentationPolicy = new WriterIndentationPolicy(keyIndentation, tableIndentation, arrayDelimiterPadding);
this.timeZone = timeZone; this.datePolicy = new DatePolicy(timeZone, showFractionalSeconds);
} }
/** /**
@ -140,7 +146,7 @@ public class TomlWriter {
* @throws IOException if target.write() fails * @throws IOException if target.write() fails
*/ */
public void write(Object from, Writer target) throws IOException { public void write(Object from, Writer target) throws IOException {
WriterContext context = new WriterContext(indentationPolicy, timeZone, target); WriterContext context = new WriterContext(indentationPolicy, datePolicy, target);
WRITERS.write(from, context); WRITERS.write(from, context);
} }

View file

@ -3,7 +3,6 @@ package com.moandjiezana.toml;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.Arrays; import java.util.Arrays;
import java.util.TimeZone;
class WriterContext { class WriterContext {
private String arrayKey = null; private String arrayKey = null;
@ -14,10 +13,10 @@ class WriterContext {
private final String currentFieldIndent; private final String currentFieldIndent;
private final Writer output; private final Writer output;
private final WriterIndentationPolicy indentationPolicy; private final WriterIndentationPolicy indentationPolicy;
private final TimeZone timeZone; private final DatePolicy datePolicy;
WriterContext(WriterIndentationPolicy indentationPolicy, TimeZone timeZone, Writer output) { WriterContext(WriterIndentationPolicy indentationPolicy, DatePolicy datePolicy, Writer output) {
this("", "", output, indentationPolicy, timeZone); this("", "", output, indentationPolicy, datePolicy);
} }
WriterContext pushTable(String newKey) { WriterContext pushTable(String newKey) {
@ -28,7 +27,7 @@ class WriterContext {
String fullKey = key.isEmpty() ? newKey : key + "." + newKey; String fullKey = key.isEmpty() ? newKey : key + "." + newKey;
WriterContext subContext = new WriterContext(fullKey, newIndent, output, indentationPolicy, timeZone); WriterContext subContext = new WriterContext(fullKey, newIndent, output, indentationPolicy, datePolicy);
if (!empty) { if (!empty) {
subContext.empty = false; subContext.empty = false;
} }
@ -37,7 +36,7 @@ class WriterContext {
} }
WriterContext pushTableFromArray() { WriterContext pushTableFromArray() {
WriterContext subContext = new WriterContext(key, currentTableIndent, output, indentationPolicy, timeZone); WriterContext subContext = new WriterContext(key, currentTableIndent, output, indentationPolicy, datePolicy);
if (!empty) { if (!empty) {
subContext.empty = false; subContext.empty = false;
} }
@ -106,8 +105,8 @@ class WriterContext {
} }
} }
TimeZone getTimeZone() { DatePolicy getDatePolicy() {
return timeZone; return datePolicy;
} }
WriterContext setIsArrayOfTable(boolean isArrayOfTable) { WriterContext setIsArrayOfTable(boolean isArrayOfTable) {
@ -126,13 +125,13 @@ class WriterContext {
return new String(chars); return new String(chars);
} }
private WriterContext(String key, String tableIndent, Writer output, WriterIndentationPolicy indentationPolicy, TimeZone timeZone) { private WriterContext(String key, String tableIndent, Writer output, WriterIndentationPolicy indentationPolicy, DatePolicy datePolicy) {
this.key = key; this.key = key;
this.output = output; this.output = output;
this.indentationPolicy = indentationPolicy; this.indentationPolicy = indentationPolicy;
this.currentTableIndent = tableIndent; this.currentTableIndent = tableIndent;
this.datePolicy = datePolicy;
this.currentFieldIndent = tableIndent + fillStringWithSpaces(this.indentationPolicy.getKeyValueIndent()); this.currentFieldIndent = tableIndent + fillStringWithSpaces(this.indentationPolicy.getKeyValueIndent());
this.timeZone = timeZone;
} }
public WriterContext setArrayKey(String arrayKey) { public WriterContext setArrayKey(String arrayKey) {

View file

@ -53,7 +53,7 @@ public class TomlWriterTest {
o.aBoolean = false; o.aBoolean = false;
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Africa/Johannesburg")); Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Africa/Johannesburg"));
calendar.set(2015, Calendar.JULY, 1, 11, 15, 30); calendar.set(2015, Calendar.JULY, 1, 11, 5, 30);
calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.MILLISECOND, 0);
o.aDate = calendar.getTime(); o.aDate = calendar.getTime();
@ -63,7 +63,7 @@ public class TomlWriterTest {
"aFloat = 1.23\n" + "aFloat = 1.23\n" +
"aDouble = -5.43\n" + "aDouble = -5.43\n" +
"aBoolean = false\n" + "aBoolean = false\n" +
"aDate = 2015-07-01T09:15:30Z\n"; "aDate = 2015-07-01T09:05:30Z\n";
assertEquals(expected, output); assertEquals(expected, output);
} }
@ -354,7 +354,7 @@ public class TomlWriterTest {
@Test @Test
public void should_use_specified_time_zone() throws Exception { public void should_use_specified_time_zone() throws Exception {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.set(2015, Calendar.JULY, 1, 11, 15, 30); calendar.set(2015, Calendar.JULY, 1, 11, 5, 30);
calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.MILLISECOND, 0);
Map<String, Date> o = new HashMap<String, Date>(); Map<String, Date> o = new HashMap<String, Date>();
@ -365,7 +365,47 @@ public class TomlWriterTest {
timeZone(TimeZone.getTimeZone("Africa/Johannesburg")). timeZone(TimeZone.getTimeZone("Africa/Johannesburg")).
build(); build();
assertEquals("sast = 2015-07-01T13:15:30+02:00\n", writer.write(o)); assertEquals("sast = 2015-07-01T13:05:30+02:00\n", writer.write(o));
}
@Test
public void should_show_fractional_seconds() throws Exception {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.set(2015, Calendar.JULY, 1, 11, 5, 30);
calendar.set(Calendar.MILLISECOND, 345);
Map<String, Date> o = new HashMap<String, Date>();
o.put("date", calendar.getTime());
TomlWriter writer = new TomlWriter.Builder().
showFractionalSeconds().
build();
assertEquals("date = 2015-07-01T11:05:30.345Z\n", writer.write(o));
}
@Test
public void should_show_fractional_seconds_in_specified_time_zone() throws Exception {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.set(2015, Calendar.JULY, 1, 11, 5, 30);
calendar.set(Calendar.MILLISECOND, 345);
Map<String, Date> o = new LinkedHashMap<String, Date>();
o.put("date", calendar.getTime());
calendar.set(Calendar.MINUTE, 37);
o.put("date2", calendar.getTime());
TomlWriter writer = new TomlWriter.Builder().
timeZone(TimeZone.getTimeZone("Africa/Johannesburg")).
showFractionalSeconds().
build();
String expected = "date = 2015-07-01T13:05:30.345+02:00\n"
+ "date2 = 2015-07-01T13:37:30.345+02:00\n";
assertEquals(expected, writer.write(o));
} }
private static class SimpleTestClass { private static class SimpleTestClass {