/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights
* Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is
* distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either
* express or implied. See the License for the specific language
* governing
* permissions and limitations under the License.
*/
package com.amazonaws.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import com.amazonaws.protocol.json.SdkJsonGenerator;
import com.amazonaws.protocol.json.StructuredJsonGenerator;
import com.fasterxml.jackson.core.JsonFactory;
import org.joda.time.DateTime;
import org.joda.time.IllegalFieldValueException;
import org.junit.Test;
public class DateUtilsTest {
private static final boolean DEBUG = false;
@Test
public void tt0031561767() throws ParseException {
String input = "Fri, 16 May 2014 23:56:46 GMT";
Date date = DateUtils.parseRFC822Date(input);
assertEquals(input, DateUtils.formatRFC822Date(date));
}
@Test
public void formatIso8601Date() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String expected = sdf.format(date);
String actual = DateUtils.formatISO8601Date(date);
assertEquals(expected, actual);
Date expectedDate = sdf.parse(expected);
Date actualDate = DateUtils.parseISO8601Date(actual);
assertEquals(expectedDate, actualDate);
}
@Test
public void formatRfc822Date() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String expected = sdf.format(date);
String actual = DateUtils.formatRFC822Date(date);
assertEquals(expected, actual);
Date expectedDate = sdf.parse(expected);
Date actualDate = DateUtils.parseRFC822Date(actual);
assertEquals(expectedDate, actualDate);
}
@Test
public void parseCompressedIso8601Date() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String formatted = sdf.format(date);
Date expected = sdf.parse(formatted);
Date actual = DateUtils.parseCompressedISO8601Date(formatted);
assertEquals(expected, actual);
}
@Test
public void parseRfc822Date() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String formatted = sdf.format(date);
Date expected = sdf.parse(formatted);
Date actual = DateUtils.parseRFC822Date(formatted);
assertEquals(expected, actual);
}
@Test
public void parseIso8601Date() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String formatted = sdf.format(date);
String alternative = DateUtils.iso8601DateFormat.print(date.getTime());
assertEquals(formatted, alternative);
Date expectedDate = sdf.parse(formatted);
Date actualDate = DateUtils.parseISO8601Date(formatted);
assertEquals(expectedDate, actualDate);
}
@Test
public void parseIso8601Date_usingAlternativeFormat() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String formatted = sdf.format(date);
String alternative = DateUtils.alternateIso8601DateFormat.print(date.getTime());
assertEquals(formatted, alternative);
Date expectedDate = sdf.parse(formatted);
Date actualDate = DateUtils.parseISO8601Date(formatted);
assertEquals(expectedDate, actualDate);
}
@Test
public void alternateIso8601DateFormat() throws ParseException {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String expected = sdf.format(date);
String actual = DateUtils.alternateIso8601DateFormat.print(date.getTime());
assertEquals(expected, actual);
Date expectedDate = sdf.parse(expected);
DateTime actualDateTime = DateUtils.alternateIso8601DateFormat.parseDateTime(actual);
assertEquals(expectedDate, new Date(actualDateTime.getMillis()));
}
@Test
public void legacyHandlingOfInvalidDate() throws ParseException {
final String input = "2014-03-06T14:28:58.000Z.000Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
sdf.parse(input);
}
@Test(expected=IllegalArgumentException.class)
public void invalidDate() throws ParseException {
final String input = "2014-03-06T14:28:58.000Z.000Z";
DateUtils.parseISO8601Date(input);
}
@Test
public void test() throws ParseException {
Date date = new Date();
System.out.println(" formatISO8601Date: " + DateUtils.formatISO8601Date(date));
System.out.println("alternateIso8601DateFormat: " + DateUtils.alternateIso8601DateFormat.print(date.getTime()));
}
@Test
public void testIssue233() throws ParseException {
// https://github.com/aws/aws-sdk-java/issues/233
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
final String edgeCase = "292278994-08-17T07:12:55.807Z";
Date expected = sdf.parse(edgeCase);
if (DEBUG)
System.out.println("date: " + expected);
String formatted = DateUtils.formatISO8601Date(expected);
if (DEBUG)
System.out.println("formatted: " + formatted);
assertEquals(edgeCase, formatted);
Date parsed = DateUtils.parseISO8601Date(edgeCase);
if (DEBUG)
System.out.println("parsed: " + parsed);
assertEquals(expected, parsed);
String reformatted = DateUtils.formatISO8601Date(parsed);
assertEquals(edgeCase, reformatted);
}
@Test(expected=IllegalFieldValueException.class)
public void testIssue233JodaTimeLimit() throws ParseException {
// https://github.com/aws/aws-sdk-java/issues/233
String s = DateUtils.iso8601DateFormat.print(Long.MAX_VALUE);
System.out.println("s: " + s);
try {
DateTime dt = DateUtils.iso8601DateFormat.parseDateTime(s);
fail("Unexpected success: " + dt);
} catch(IllegalFieldValueException ex) {
// expected
throw ex;
}
}
@Test
public void testIssueDaysDiff() throws ParseException {
// https://github.com/aws/aws-sdk-java/issues/233
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
String edgeCase = "292278994-08-17T07:12:55.807Z";
String testCase = "292278993-08-17T07:12:55.807Z";
Date od = sdf.parse(edgeCase);
Date testd = sdf.parse(testCase);
long diff = od.getTime() - testd.getTime();
assertTrue(diff == 365L*24*60*60*1000);
}
@Test
public void testIssue233Overflows() throws ParseException {
String[] cases = {
// 1 milli second passed the max time
"292278994-08-17T07:12:55.808Z",
// 1 year passed the max year
"292278995-01-17T07:12:55.807Z", };
for (String edgeCase : cases) {
try {
Date parsed = DateUtils.parseISO8601Date(edgeCase);
fail("Unexpected success: " + parsed);
} catch (IllegalArgumentException ex) {
String msg = ex.getMessage();
assertTrue(msg
.contains("must be in the range [-292275054,292278993]"));
}
}
}
/**
* Tests the Date marshalling and unmarshalling. Asserts that the value is
* same before and after marshalling/unmarshalling
*/
@Test
public void testAWSFormatDateUtils() throws Exception {
testDate(System.currentTimeMillis());
testDate(1L);
testDate(0L);
}
private void testDate(long dateInMilliSeconds) {
String serverSpecificDateFormat = DateUtils
.formatServiceSpecificDate(new Date(dateInMilliSeconds));
Date parsedDate = DateUtils.parseServiceSpecificDate(String
.valueOf(serverSpecificDateFormat));
assertEquals(Long.valueOf(dateInMilliSeconds),
Long.valueOf(parsedDate.getTime()));
}
// See https://forums.aws.amazon.com/thread.jspa?threadID=158756
@Test
public void testNumericNoQuote() {
StructuredJsonGenerator jw = new SdkJsonGenerator(new JsonFactory(), null);
jw.writeStartObject();
jw.writeFieldName("foo").writeValue(new Date());
jw.writeEndObject();
String s = new String(jw.getBytes(), Charset.forName("UTF-8"));
// Something like: {"foo":1408378076.135}.
// Note prior to the changes, it was {"foo":1408414571}
// (with no decimal point nor places.)
System.out.println(s);
final String prefix = "{\"foo\":";
assertTrue(s, s.startsWith(prefix));
final int startPos = prefix.length();
// verify no starting quote for the value
assertFalse(s, s.startsWith("{\"foo\":\""));
assertTrue(s, s.endsWith("}"));
// Not: {"foo":"1408378076.135"}.
// verify no ending quote for the value
assertFalse(s, s.endsWith("\"}"));
final int endPos = s.indexOf("}");
final int dotPos = s.length()-5;
assertTrue(s, s.charAt(dotPos) == '.');
// verify all numeric before '.'
char[] a = s.toCharArray();
for (int i=startPos; i < dotPos; i++)
assertTrue(a[i] <= '9' && a[i] >= '0' );
int j=0;
// verify all numeric after '.'
for (int i=dotPos+1; i < endPos; i++) {
assertTrue(a[i] <= '9' && a[i] >= '0' );
j++;
}
// verify decimal precision of exactly 3
assertTrue(j == 3);
}
@Test
public void numberOfDaysSinceEpoch() {
final long now = System.currentTimeMillis();
final long days = DateUtils.numberOfDaysSinceEpoch(now);
final int oneDayMilli = 24*60*60*1000;
assertTrue(now > days*oneDayMilli);
assertTrue((now - days*oneDayMilli) <= oneDayMilli);
}
}