Skip to content

Commit d1010e1

Browse files
committed
Time and Date classes compressed down to single String field
1 parent f92b187 commit d1010e1

36 files changed

+248
-420
lines changed

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Key Features:
1010
- Supports polymorphic types and complex object graphs
1111
- Zero external dependencies (other than java-util)
1212
- Fully compatible with both JPMS and OSGi environments
13-
- Lightweight (224K for json-io.jar, 405K for java-util)
13+
- Lightweight (237K for json-io.jar, 405K for java-util)
1414
- Compatible with JDK 1.8 through JDK 23
1515
- Extensive configuration options via ReadOptions and WriteOptions
1616
- Featured on [json.org](http://json.org)
@@ -31,15 +31,15 @@ ___
3131
To include in your project:
3232
##### Gradle
3333
```groovy
34-
implementation 'com.cedarsoftware:json-io:4.33.0'
34+
implementation 'com.cedarsoftware:json-io:4.34.0'
3535
```
3636

3737
##### Maven
3838
```xml
3939
<dependency>
4040
<groupId>com.cedarsoftware</groupId>
4141
<artifactId>json-io</artifactId>
42-
<version>4.33.0</version>
42+
<version>4.34.0</version>
4343
</dependency>
4444
```
4545
___
@@ -57,23 +57,23 @@ ___
5757
>- [ ] **Java Package**: com.cedarsoftware.io
5858
>- [ ] **Java**: JDK17+ (Class file 61 format, includes module-info.class - multi-release JAR)
5959
>- [ ] **API**
60-
> - Static methods on [JsonIo](https://www.javadoc.io/doc/com.cedarsoftware/json-io/latest/com/cedarsoftware/io/JsonIo.html): [toJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#toJson(java.lang.Object,com.cedarsoftware.io.WriteOptions)), [toObjects()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#toObjects(java.lang.String,com.cedarsoftware.io.ReadOptions,java.lang.Class)), [formatJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#formatJson(java.lang.String,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions)), [deepCopy()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#deepCopy(java.lang.Object,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions))
60+
> - Static methods on [JsonIo](https://www.javadoc.io/doc/com.cedarsoftware/json-io/latest/com/cedarsoftware/io/JsonIo.html): [toJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#toJson(java.lang.Object,com.cedarsoftware.io.WriteOptions)), [toObjects()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#toObjects(java.lang.String,com.cedarsoftware.io.ReadOptions,java.lang.Class)), [formatJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#formatJson(java.lang.String,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions)), [deepCopy()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#deepCopy(java.lang.Object,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions))
6161
> - Use [ReadOptionsBuilder](/user-guide-readOptions.md) and [WriteOptionsBuilder](/user-guide-writeOptions.md) to configure `JsonIo`
62-
> - Use [JsonReader.ClassFactory](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonReader.ClassFactory.html) for difficult classes (hard to instantiate & fill)
63-
> - Use [JsonWriter.JsonClassWriter](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonWriter.JsonClassWriter.html) to customize the output JSON for a particular class
62+
> - Use [JsonReader.ClassFactory](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonReader.ClassFactory.html) for difficult classes (hard to instantiate & fill)
63+
> - Use [JsonWriter.JsonClassWriter](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonWriter.JsonClassWriter.html) to customize the output JSON for a particular class
6464
>- [ ] Updates will be 5.1.0, 5.2.0, ...
65-
>### 4.33.0 (current)
66-
>- [ ] **Version**: [4.33.0](https://www.javadoc.io/doc/com.cedarsoftware/json-io/4.33.0/index.html)
65+
>### 4.34.0 (current)
66+
>- [ ] **Version**: [4.34.0](https://www.javadoc.io/doc/com.cedarsoftware/json-io/4.34.0/index.html)
6767
>- [ ] **Bundling**: Both JPMS (Java Platform Module System) and OSGi (Open Service Gateway initiative)
6868
>- [ ] **Maintained**: Fully
6969
>- [ ] **Java Package**: com.cedarsoftware.io
7070
>- [ ] **Java**: JDK1.8+ (Class file 52 format, includes module-info.class - multi-release JAR)
7171
>- [ ] **API**
72-
> - Static methods on [JsonIo](https://www.javadoc.io/doc/com.cedarsoftware/json-io/latest/com/cedarsoftware/io/JsonIo.html): [toJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#toJson(java.lang.Object,com.cedarsoftware.io.WriteOptions)), [toObjects()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#toObjects(java.lang.String,com.cedarsoftware.io.ReadOptions,java.lang.Class)), [formatJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#formatJson(java.lang.String,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions)), [deepCopy()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonIo.html#deepCopy(java.lang.Object,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions))
72+
> - Static methods on [JsonIo](https://www.javadoc.io/doc/com.cedarsoftware/json-io/latest/com/cedarsoftware/io/JsonIo.html): [toJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#toJson(java.lang.Object,com.cedarsoftware.io.WriteOptions)), [toObjects()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#toObjects(java.lang.String,com.cedarsoftware.io.ReadOptions,java.lang.Class)), [formatJson()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#formatJson(java.lang.String,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions)), [deepCopy()](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonIo.html#deepCopy(java.lang.Object,com.cedarsoftware.io.ReadOptions,com.cedarsoftware.io.WriteOptions))
7373
> - Use [ReadOptionsBuilder](/user-guide-readOptions.md) and [WriteOptionsBuilder](/user-guide-writeOptions.md) to configure `JsonIo`
74-
> - Use [JsonReader.ClassFactory](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonReader.ClassFactory.html) for difficult classes (hard to instantiate & fill)
75-
> - Use [JsonWriter.JsonClassWriter](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.33.0/com/cedarsoftware/io/JsonWriter.JsonClassWriter.html) to customize the output JSON for a particular class
76-
>- [ ] Updates will be 4.34.0, 4.35.0, ...
74+
> - Use [JsonReader.ClassFactory](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonReader.ClassFactory.html) for difficult classes (hard to instantiate & fill)
75+
> - Use [JsonWriter.JsonClassWriter](https://www.javadoc.io/static/com.cedarsoftware/json-io/4.34.0/com/cedarsoftware/io/JsonWriter.JsonClassWriter.html) to customize the output JSON for a particular class
76+
>- [ ] Updates will be 4.35.0, 4.36.0, ...
7777
>### 4.14.x (supported)
7878
>- [ ] **Version**: [4.14.3](https://www.javadoc.io/doc/com.cedarsoftware/json-io/4.14.3/index.html)
7979
>- [ ] **Bundling**: Both JPMS (Java Platform Module System) and OSGi (Open Service Gateway initiative)

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
### Revision History
2+
#### 4.34.0
3+
* Improved Date and java.sql.Date handling within Converters.
24
#### 4.33.0
35
* New custom `ClassFactory` classes are easier to write:
46
* See [examples](user-guide.md#classfactory-and-customwriter-examples)

pom.xml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<groupId>com.cedarsoftware</groupId>
66
<artifactId>json-io</artifactId>
77
<packaging>bundle</packaging>
8-
<version>4.33.0</version>
8+
<version>4.34.0</version>
99
<description>Java JSON serialization</description>
1010
<url>https://github.com/jdereg/json-io</url>
1111

@@ -26,8 +26,7 @@
2626
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss.SSSZ</maven.build.timestamp.format>
2727
<!-- remove source encoding warnings from maven output -->
2828
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
29-
30-
<version.java-util>3.0.2</version.java-util>
29+
<version.java-util>3.0.3</version.java-util>
3130
<!-- testing only -->
3231
<version.junit-jupiter-params>5.11.4</version.junit-jupiter-params>
3332
<version.assertj-core>3.27.2</version.assertj-core>

src/main/java/com/cedarsoftware/io/JsonIo.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.io.InputStream;
44
import java.io.OutputStream;
55
import java.nio.charset.StandardCharsets;
6-
import java.text.SimpleDateFormat;
76
import java.util.Arrays;
87
import java.util.Collection;
98
import java.util.HashMap;
@@ -381,11 +380,8 @@ public static WriteOptionsBuilder getWriteOptionsBuilder(Map<String, Object> opt
381380
WriteOptionsBuilder builder = new WriteOptionsBuilder();
382381

383382
Object dateFormat = optionalArgs.get(DATE_FORMAT);
384-
if (dateFormat instanceof String)
385-
{
386-
builder.dateTimeFormat((String) dateFormat);
387-
} else if (dateFormat instanceof SimpleDateFormat) {
388-
builder.dateTimeFormat(((SimpleDateFormat) dateFormat).toPattern());
383+
if (dateFormat != null) {
384+
builder.isoDateFormat();
389385
}
390386

391387
Boolean showType = com.cedarsoftware.util.Converter.convert(optionalArgs.get(TYPE), Boolean.class);

src/main/java/com/cedarsoftware/io/WriteOptionsBuilder.java

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -636,23 +636,14 @@ public WriteOptionsBuilder addExcludedFields(Map<Class<?>, Collection<String>> e
636636
}
637637

638638
/**
639-
* Change the date-time format to the ISO date format: "yyyy-MM-dd". This is for java.util.Data and
640-
* java.sql.Date.
639+
* Change the date-time format to the ISO date format: "yyyy-MM-ddThh:mm:ss.SSSZ". This is for java.util.Date and
640+
* java.sql.Date. The fractional sections are omitted if millis are 0.
641641
*
642642
* @return WriteOptionsBuilder for chained access.
643643
*/
644644
public WriteOptionsBuilder isoDateFormat() {
645-
return dateTimeFormat(ISO_DATE_FORMAT);
646-
}
647-
648-
/**
649-
* Change the date-time format to the ISO date-time format: "yyyy-MM-dd'T'HH:mm:ss" (default). This is
650-
* for java.util.Date and java.sql.Date.
651-
*
652-
* @return WriteOptionsBuilder for chained access.
653-
*/
654-
public WriteOptionsBuilder isoDateTimeFormat() {
655-
return dateTimeFormat(ISO_DATE_TIME_FORMAT);
645+
addCustomWrittenClass(Date.class, new Writers.DateWriter());
646+
return this;
656647
}
657648

658649
/**
@@ -666,18 +657,6 @@ public WriteOptionsBuilder longDateFormat() {
666657
addCustomWrittenClass(Date.class, new Writers.DateAsLongWriter());
667658
return this;
668659
}
669-
670-
/**
671-
* Change the date-time format to the passed in format. The format pattens can be found in the Java Doc
672-
* for the java.time.format.DateTimeFormatter class. There are many constants you can use, as well as
673-
* the definition of how to construct your own patterns. This is for java.util.Date and java.sql.Date.
674-
*
675-
* @return WriteOptionsBuilder for chained access.
676-
*/
677-
public WriteOptionsBuilder dateTimeFormat(String format) {
678-
addCustomWrittenClass(Date.class, new Writers.DateWriter(format));
679-
return this;
680-
}
681660

682661
/**
683662
* This option permits adding non-standard accessors (used when writing JSON) that access properties from objects,

src/main/java/com/cedarsoftware/io/Writers.java

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.io.Writer;
55
import java.math.BigDecimal;
66
import java.math.BigInteger;
7-
import java.sql.Timestamp;
87
import java.text.SimpleDateFormat;
98
import java.time.Instant;
109
import java.time.LocalDate;
@@ -20,8 +19,6 @@
2019
import java.time.format.DateTimeFormatterBuilder;
2120
import java.time.format.SignStyle;
2221
import java.time.temporal.TemporalAccessor;
23-
import java.util.Calendar;
24-
import java.util.Date;
2522
import java.util.Locale;
2623
import java.util.TimeZone;
2724
import java.util.UUID;
@@ -206,40 +203,61 @@ public String extractString(Object o) {
206203

207204
public static class CalendarWriter implements JsonWriter.JsonClassWriter {
208205
@Override
206+
public void writePrimitiveForm(Object o, Writer output, WriterContext context) throws IOException {
207+
String formatted = Converter.convert(o, String.class);
208+
JsonWriter.writeBasicString(output, formatted);
209+
}
210+
209211
public void write(Object obj, boolean showType, Writer output, WriterContext context) throws IOException {
210-
Calendar cal = (Calendar) obj;
211-
// TODO: shouldn't this be the one inside the WriterContext? and shouldn't there be a back up of parseDate() here?
212-
dateFormat.get().setTimeZone(cal.getTimeZone());
213-
output.write("\"time\":\"");
214-
output.write(dateFormat.get().format(cal.getTime()));
215-
output.write("\",\"zone\":\"");
216-
output.write(cal.getTimeZone().getID());
217-
output.write('"');
212+
if (showType) {
213+
JsonWriter.writeBasicString(output, "calendar");
214+
output.write(':');
215+
}
216+
217+
writePrimitiveForm(obj, output, context);
218+
}
219+
220+
public boolean hasPrimitiveForm(WriterContext context) {
221+
return true;
218222
}
219223
}
220224

221225
public static class DateAsLongWriter extends PrimitiveValueWriter {
222226
@Override
223227
public String extractString(Object o) {
224-
return Long.toString(((Date) o).getTime());
228+
if (o instanceof java.sql.Date) {
229+
// Just use the date's built-in toString - it's already in JDBC format
230+
return o.toString();
231+
} else {
232+
return Long.toString(((java.util.Date) o).getTime());
233+
}
225234
}
226235
}
227-
228-
public static class DateWriter extends PrimitiveUtf8StringWriter {
229-
// could change to DateFormatter.ofPattern to keep from creating new objects
230-
private final String dateFormat;
231-
232-
public DateWriter(String format) {
233-
this.dateFormat = format;
236+
237+
public static class DateWriter implements JsonWriter.JsonClassWriter {
238+
@Override
239+
public void writePrimitiveForm(Object o, Writer output, WriterContext context) throws IOException {
240+
String formatted = Converter.convert(o, String.class);
241+
JsonWriter.writeBasicString(output, formatted);
234242
}
235243

236-
public String extractString(Object o) {
237-
Date date = (Date) o;
238-
return new SimpleDateFormat(dateFormat).format(date);
244+
public void write(Object obj, boolean showType, Writer output, WriterContext context) throws IOException {
245+
if (showType) {
246+
String key;
247+
if (obj instanceof java.sql.Date) {
248+
key = "sqlDate";
249+
} else {
250+
key = "date";
251+
}
252+
JsonWriter.writeBasicString(output, key);
253+
output.write(':');
254+
}
255+
256+
writePrimitiveForm(obj, output, context);
239257
}
240258

241-
String getDateFormat() {
242-
return dateFormat;
259+
public boolean hasPrimitiveForm(WriterContext context) {
260+
return true;
243261
}
244262
}
245263

@@ -255,9 +273,6 @@ public LocalDateAsLong() {
255273
}
256274

257275
public void writePrimitiveForm(Object o, Writer output, WriterContext writerContext) throws IOException {
258-
259-
//TODO: Change to using converter and having the writeOptions provide a zoneId;
260-
//TODO: If we're going to provide a LocalDateAsLong we should also provide a LocalDateTimeAsLong
261276
LocalDate localDate = (LocalDate) o;
262277
ZonedDateTime zonedDateTime = localDate.atStartOfDay(zoneId);
263278

@@ -358,15 +373,15 @@ public OffsetDateTimeWriter() {
358373
}
359374

360375
public static class TimestampWriter implements JsonWriter.JsonClassWriter {
376+
@Override
361377
public void writePrimitiveForm(Object o, Writer output, WriterContext context) throws IOException {
362-
Timestamp timestamp = (Timestamp) o;
363-
String ts = Converter.convert(timestamp, String.class);
364-
JsonWriter.writeBasicString(output, ts);
378+
String formatted = Converter.convert(o, String.class);
379+
JsonWriter.writeBasicString(output, formatted);
365380
}
366381

367382
public void write(Object obj, boolean showType, Writer output, WriterContext context) throws IOException {
368383
if (showType) {
369-
JsonWriter.writeBasicString(output, VALUE);
384+
JsonWriter.writeBasicString(output, "timestamp");
370385
output.write(':');
371386
}
372387

src/main/java/com/cedarsoftware/io/factory/TimestampFactory.java

Lines changed: 0 additions & 51 deletions
This file was deleted.

src/main/resources/config/classFactory.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ java.nio.HeapCharBuffer = com.cedarsoftware.io.factory.CharBufferFactory
6060

6161
# java.sql
6262
java.sql.Date = Convertable
63-
java.sql.Timestamp = com.cedarsoftware.io.factory.TimestampFactory
63+
java.sql.Timestamp = Convertable
6464

6565
# java.time
6666
java.time.Duration = Convertable

src/main/resources/config/customWriters.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ java.net.URI = com.cedarsoftware.io.Writers$PrimitiveUtf8StringWriter
3131
java.nio.ByteBuffer = com.cedarsoftware.io.writers.ByteBufferWriter
3232
java.nio.CharBuffer = com.cedarsoftware.io.writers.CharBufferWriter
3333

34-
java.sql.Date = com.cedarsoftware.io.Writers$DateAsLongWriter
34+
java.sql.Date = com.cedarsoftware.io.Writers$DateWriter
3535
java.sql.Timestamp = com.cedarsoftware.io.Writers$TimestampWriter
3636

3737
java.time.Duration = com.cedarsoftware.io.writers.DurationWriter

src/test/java/com/cedarsoftware/io/ArrayTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ void testReconsitutute_withCalendars_whenArrayTypeIsCalendar() {
598598

599599
@Test
600600
void testReconstitute_withGregorianCalendars_whenArrayTypeIsCalendar() {
601-
GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(TimeZone.getTimeZone("GMT-05:00"));
601+
GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
602602
GregorianCalendar[] calendarz = new GregorianCalendar[]{cal, cal};
603603
testReconstituteArrayHelper(calendarz);
604604
}

0 commit comments

Comments
 (0)