Skip to content

Commit 59adfd6

Browse files
authored
feat: differentiate between timestamp formats in json unmarshaller (#2018)
1 parent 73ff8f8 commit 59adfd6

File tree

3 files changed

+150
-8
lines changed

3 files changed

+150
-8
lines changed

aws-android-sdk-core/src/main/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallers.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.amazonaws.AmazonClientException;
1919
import com.amazonaws.util.Base64;
20+
import com.amazonaws.util.DateUtils;
2021

2122
import java.math.BigDecimal;
2223
import java.math.BigInteger;
@@ -244,21 +245,34 @@ public static ByteJsonUnmarshaller getInstance() {
244245
}
245246

246247
/**
247-
* Unmarshaller for Date values - JSON dates come in as epoch seconds.
248+
* Unmarshaller for Date values.
248249
*/
249250
public static class DateJsonUnmarshaller implements Unmarshaller<Date, JsonUnmarshallerContext> {
250-
251251
private static final int DATE_MULTIPLIER = 1000;
252+
private final TimestampFormat format;
253+
254+
private DateJsonUnmarshaller(TimestampFormat format) {
255+
this.format = format;
256+
}
257+
252258
@Override
253259
public Date unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
254260
String dateString = unmarshallerContext.getReader().nextString();
255261
if (dateString == null)
256262
return null;
257263

258264
try {
259-
Number number = NumberFormat.getInstance(new Locale("en")).parse(dateString);
260-
return new Date(number.longValue() * DATE_MULTIPLIER);
261-
} catch (ParseException e) {
265+
switch (format) {
266+
case ISO_8601:
267+
return DateUtils.parseISO8601Date(dateString);
268+
case RFC_822:
269+
return DateUtils.parseRFC822Date(dateString);
270+
case UNIX_TIMESTAMP:
271+
default:
272+
Number number = NumberFormat.getInstance(new Locale("en")).parse(dateString);
273+
return new Date(number.longValue() * DATE_MULTIPLIER);
274+
}
275+
} catch (IllegalArgumentException | ParseException e) {
262276
String errorMessage = "Unable to parse date '" + dateString + "': "
263277
+ e.getMessage();
264278
throw new AmazonClientException(errorMessage, e);
@@ -268,12 +282,25 @@ public Date unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Excep
268282
private static DateJsonUnmarshaller instance;
269283

270284
/**
271-
* Constructor.
285+
* Constructor. Defaults to unix timestamp format.
272286
* @return the instance.
273287
*/
274288
public static DateJsonUnmarshaller getInstance() {
275-
if (instance == null)
276-
instance = new DateJsonUnmarshaller();
289+
if (instance == null) {
290+
instance = new DateJsonUnmarshaller(TimestampFormat.UNIX_TIMESTAMP);
291+
}
292+
return instance;
293+
}
294+
295+
/**
296+
* Constructor.
297+
* @return the instance.
298+
*/
299+
public static DateJsonUnmarshaller getInstance(TimestampFormat format) {
300+
// Create a new on if existing singleton isn't of correct format
301+
if (instance == null || !instance.format.equals(format)) {
302+
instance = new DateJsonUnmarshaller(format);
303+
}
277304
return instance;
278305
}
279306
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazonaws.transform;
17+
18+
import com.amazonaws.util.DateUtils;
19+
20+
/**
21+
* Simple enum to differentiate timestamp format standards.
22+
*/
23+
enum TimestampFormat {
24+
/**
25+
* In epoch seconds.
26+
*/
27+
UNIX_TIMESTAMP,
28+
29+
/**
30+
* In either {@link DateUtils#ISO8601_DATE_PATTERN} or
31+
* {@link DateUtils#ALTERNATE_ISO8601_DATE_PATTERN} pattern.
32+
*/
33+
ISO_8601,
34+
35+
/**
36+
* In {@link DateUtils#RFC822_DATE_PATTERN} pattern.
37+
*/
38+
RFC_822
39+
}

aws-android-sdk-core/src/test/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallerTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.junit.Assert.assertTrue;
2020

2121
import com.amazonaws.util.Base64;
22+
import com.amazonaws.util.DateUtils;
2223
import com.amazonaws.util.StringUtils;
2324
import com.amazonaws.util.json.AwsJsonReader;
2425
import com.amazonaws.util.json.AwsJsonWriter;
@@ -180,6 +181,81 @@ public void testDateJsonUnmarshaller() throws Exception {
180181
assertEquals(unmarshalledDate.getTime(), date.getTime());
181182
}
182183

184+
@Test
185+
public void testDateUnixTimestampJsonUnmarshaller() throws Exception {
186+
Date date = new Date();
187+
date.setTime(1000);
188+
189+
StringWriter sw = new StringWriter();
190+
AwsJsonWriter jw = JsonUtils.getJsonWriter(sw);
191+
jw.beginObject();
192+
jw.name("unix");
193+
jw.value(date);
194+
jw.endObject();
195+
String json = sw.toString();
196+
197+
StringReader sr = new StringReader(json);
198+
AwsJsonReader jr = JsonUtils.getJsonReader(sr);
199+
JsonUnmarshallerContext context = new JsonUnmarshallerContext(jr);
200+
context.getReader().beginObject();
201+
context.getReader().nextName();
202+
203+
SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller dateUnmarshaller = SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller
204+
.getInstance(TimestampFormat.UNIX_TIMESTAMP);
205+
Date unmarshalledDate = dateUnmarshaller.unmarshall(context);
206+
assertEquals(unmarshalledDate.getTime(), date.getTime());
207+
}
208+
209+
@Test
210+
public void testDateIso8601JsonUnmarshaller() throws Exception {
211+
Date date = new Date();
212+
date.setTime(1000);
213+
214+
StringWriter sw = new StringWriter();
215+
AwsJsonWriter jw = JsonUtils.getJsonWriter(sw);
216+
jw.beginObject();
217+
jw.name("iso8601");
218+
jw.value(DateUtils.formatISO8601Date(date));
219+
jw.endObject();
220+
String json = sw.toString();
221+
222+
StringReader sr = new StringReader(json);
223+
AwsJsonReader jr = JsonUtils.getJsonReader(sr);
224+
JsonUnmarshallerContext context = new JsonUnmarshallerContext(jr);
225+
context.getReader().beginObject();
226+
context.getReader().nextName();
227+
228+
SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller dateUnmarshaller = SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller
229+
.getInstance(TimestampFormat.ISO_8601);
230+
Date unmarshalledDate = dateUnmarshaller.unmarshall(context);
231+
assertEquals(unmarshalledDate.getTime(), date.getTime());
232+
}
233+
234+
@Test
235+
public void testDateRfc822JsonUnmarshaller() throws Exception {
236+
Date date = new Date();
237+
date.setTime(1000);
238+
239+
StringWriter sw = new StringWriter();
240+
AwsJsonWriter jw = JsonUtils.getJsonWriter(sw);
241+
jw.beginObject();
242+
jw.name("rfc822");
243+
jw.value(DateUtils.formatRFC822Date(date));
244+
jw.endObject();
245+
String json = sw.toString();
246+
247+
StringReader sr = new StringReader(json);
248+
AwsJsonReader jr = JsonUtils.getJsonReader(sr);
249+
JsonUnmarshallerContext context = new JsonUnmarshallerContext(jr);
250+
context.getReader().beginObject();
251+
context.getReader().nextName();
252+
253+
SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller dateUnmarshaller = SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller
254+
.getInstance(TimestampFormat.RFC_822);
255+
Date unmarshalledDate = dateUnmarshaller.unmarshall(context);
256+
assertEquals(unmarshalledDate.getTime(), date.getTime());
257+
}
258+
183259
@Test
184260
public void testDoubleJsonUnmarshaller() throws Exception {
185261
Double dub = new Double(5.5);

0 commit comments

Comments
 (0)