Streamlined writing dates in UTC timezone.

This commit is contained in:
moandji.ezana 2015-07-01 10:21:10 +02:00
parent d9abbe7bc3
commit a6e31da5ca
6 changed files with 36 additions and 109 deletions

View file

@ -2,7 +2,6 @@ package com.moandjiezana.toml;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
@ -90,21 +89,8 @@ class DateConverter implements ValueConverter, ValueWriter {
@Override
public void write(Object value, WriterContext context) {
DateFormat dateFormat;
DateFormat customDateFormat = context.getTomlWriter().getDateFormat();
if (customDateFormat != null) {
dateFormat = customDateFormat;
} else {
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:m:ss");
}
dateFormat.setTimeZone(context.getTomlWriter().getTimeZone());
DateFormat dateFormat = context.getDateFormat();
context.write(dateFormat.format(value));
if (customDateFormat == null) {
Calendar calendar = context.getTomlWriter().getCalendar();
int tzOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000);
context.write(String.format("%+03d:%02d", tzOffset / 60, tzOffset % 60));
}
}
@Override

View file

@ -9,8 +9,6 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
@ -38,6 +36,7 @@ public class TomlWriter {
private int keyIndentation;
private int tableIndentation;
private int arrayDelimiterPadding = 0;
private TimeZone timeZone = TimeZone.getTimeZone("UTC");
public TomlWriter.Builder indentValuesBy(int spaces) {
this.keyIndentation = spaces;
@ -62,23 +61,23 @@ public class TomlWriter {
}
public TomlWriter build() {
return new TomlWriter(keyIndentation, tableIndentation, arrayDelimiterPadding);
return new TomlWriter(keyIndentation, tableIndentation, arrayDelimiterPadding, timeZone);
}
}
private final WriterIndentationPolicy indentationPolicy;
private GregorianCalendar calendar = new GregorianCalendar();
private DateFormat customDateFormat = null;
private TimeZone timeZone;
/**
* Creates a TomlWriter instance.
*/
public TomlWriter() {
this(0, 0, 0);
this(0, 0, 0, TimeZone.getTimeZone("UTC"));
}
private TomlWriter(int keyIndentation, int tableIndentation, int arrayDelimiterPadding) {
private TomlWriter(int keyIndentation, int tableIndentation, int arrayDelimiterPadding, TimeZone timeZone) {
this.indentationPolicy = new WriterIndentationPolicy(keyIndentation, tableIndentation, arrayDelimiterPadding);
this.timeZone = timeZone;
}
/**
@ -135,54 +134,11 @@ public class TomlWriter {
* @throws IOException if target.write() fails
*/
public void write(Object from, Writer target) throws IOException {
WRITERS.write(from, this, target);
WriterContext context = new WriterContext(indentationPolicy, timeZone, target);
WRITERS.write(from, context);
}
WriterIndentationPolicy getIndentationPolicy() {
return indentationPolicy;
}
/**
* Set the {@link TimeZone} used when formatting datetimes.
*
* If unset, datetimes will be rendered in the current time zone.
*
* @param timeZone custom TimeZone.
* @return this TomlWriter instance
*/
public TomlWriter setTimeZone(TimeZone timeZone) {
calendar = new GregorianCalendar(timeZone);
return this;
}
/**
* Get the {@link TimeZone} in use for this TomlWriter.
*
* @return the currently set TimeZone.
*/
public TimeZone getTimeZone() {
return calendar.getTimeZone();
}
/**
* Override the default date format.
*
* If a time zone was set with {@link #setTimeZone(TimeZone)}, it will be applied before formatting
* datetimes.
*
* @param customDateFormat a custom DateFormat
* @return this TomlWriter instance
*/
public TomlWriter setDateFormat(DateFormat customDateFormat) {
this.customDateFormat = customDateFormat;
return this;
}
public DateFormat getDateFormat() {
return customDateFormat;
}
GregorianCalendar getCalendar() {
return calendar;
}
}

View file

@ -9,8 +9,6 @@ import static com.moandjiezana.toml.PrimitiveArrayValueWriter.PRIMITIVE_ARRAY_VA
import static com.moandjiezana.toml.StringConverter.STRING_PARSER;
import static com.moandjiezana.toml.TableArrayValueWriter.TABLE_ARRAY_VALUE_WRITER;
import java.io.Writer;
class ValueWriters {
static final ValueWriters WRITERS = new ValueWriters();
@ -25,11 +23,6 @@ class ValueWriters {
return OBJECT_VALUE_WRITER;
}
void write(Object value, TomlWriter tomlWriter, Writer output) {
WriterContext context = new WriterContext(tomlWriter, output);
write(value, context);
}
void write(Object value, WriterContext context) {
findWriterFor(value).write(value, context);
}

View file

@ -2,7 +2,10 @@ package com.moandjiezana.toml;
import java.io.IOException;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.TimeZone;
class WriterContext {
private String arrayKey = null;
@ -11,12 +14,12 @@ class WriterContext {
private final String key;
private final String currentTableIndent;
private final String currentFieldIndent;
private final TomlWriter tomlWriter;
private final Writer output;
private final WriterIndentationPolicy indentationPolicy;
private final TimeZone timeZone;
WriterContext(TomlWriter tomlWriter, Writer output) {
this("", "", output, tomlWriter);
WriterContext(WriterIndentationPolicy indentationPolicy, TimeZone timeZone, Writer output) {
this("", "", output, indentationPolicy, timeZone);
}
WriterContext pushTable(String newKey) {
@ -27,7 +30,7 @@ class WriterContext {
String fullKey = key.isEmpty() ? newKey : key + "." + newKey;
WriterContext subContext = new WriterContext(fullKey, newIndent, output, tomlWriter);
WriterContext subContext = new WriterContext(fullKey, newIndent, output, indentationPolicy, timeZone);
if (!empty) {
subContext.empty = false;
}
@ -36,7 +39,7 @@ class WriterContext {
}
WriterContext pushTableFromArray() {
WriterContext subContext = new WriterContext(key, currentTableIndent, output, tomlWriter);
WriterContext subContext = new WriterContext(key, currentTableIndent, output, indentationPolicy, timeZone);
if (!empty) {
subContext.empty = false;
}
@ -104,6 +107,14 @@ class WriterContext {
write(currentFieldIndent);
}
}
DateFormat getDateFormat() {
String format = "yyyy-MM-dd'T'HH:m:ss'Z'";
SimpleDateFormat formatter = new SimpleDateFormat(format);
formatter.setTimeZone(timeZone);
return formatter;
}
WriterContext setIsArrayOfTable(boolean isArrayOfTable) {
this.isArrayOfTable = isArrayOfTable;
@ -121,17 +132,13 @@ class WriterContext {
return new String(chars);
}
private WriterContext(String key, String tableIndent, Writer output, TomlWriter tomlWriter) {
private WriterContext(String key, String tableIndent, Writer output, WriterIndentationPolicy indentationPolicy, TimeZone timeZone) {
this.key = key;
this.output = output;
this.indentationPolicy = tomlWriter.getIndentationPolicy();
this.indentationPolicy = indentationPolicy;
this.currentTableIndent = tableIndent;
this.currentFieldIndent = tableIndent + fillStringWithSpaces(this.indentationPolicy.getKeyValueIndent());
this.tomlWriter = tomlWriter;
}
public TomlWriter getTomlWriter() {
return tomlWriter;
this.timeZone = timeZone;
}
public WriterContext setArrayKey(String arrayKey) {

View file

@ -125,11 +125,7 @@ public class BurntSushiValidEncoderTest {
private static final Gson GSON = new Gson();
private void runEncoder(String testName) {
runEncoder(testName,
new TomlWriter.Builder().
build().
setTimeZone(TimeZone.getTimeZone("UTC")).
setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")));
runEncoder(testName, new TomlWriter());
}
private void runEncoder(String testName, TomlWriter tomlWriter) {

View file

@ -14,14 +14,13 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.junit.Rule;
import org.junit.Test;
@ -52,32 +51,22 @@ public class TomlWriterTest {
o.aDouble = -5.43;
o.aBoolean = false;
o.aDate = new Date();
String theDate = formatDate(o.aDate);
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Africa/Johannesburg"));
calendar.set(2015, Calendar.JULY, 1, 11, 15, 30);
calendar.set(Calendar.MILLISECOND, 0);
o.aDate = calendar.getTime();
String output = new TomlWriter().write(o);
String expected = "aString = \"hello\"\n" +
"anInt = 4\n" +
"aFloat = 1.23\n" +
"aDouble = -5.43\n" +
"aBoolean = false\n" +
"aDate = " + theDate + "\n";
"aDate = 2015-07-01T09:15:30Z\n";
assertEquals(expected, output);
}
private String formatDate(Date date) {
// Copying the date formatting code from DateValueWriter isn't optimal, but
// I can't see any other way to check date formatting - the test gets
// run in multiple time zones, so we can't just hard-code a time zone.
String dateString = new SimpleDateFormat("yyyy-MM-dd'T'HH:m:ss").format(date);
Calendar calendar = new GregorianCalendar();
int tzOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000);
dateString += String.format("%+03d:%02d", tzOffset / 60, tzOffset % 60);
return dateString;
}
class SubChild {
int anInt;
}