Issue 574: work around bad date format

This commit is contained in:
Adrian Cole 2011-06-01 11:52:56 -07:00
parent 3526cdc4c5
commit 140dd8711c
4 changed files with 89 additions and 73 deletions

View File

@ -0,0 +1,52 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.jclouds.date.internal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author Adrian Cole
*/
public class DateUtils {
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
public static final Pattern TZ_PATTERN = Pattern.compile("(.*)[+-][0-9][0-9]:?[0-9][0-9]Z?");
public static String trimNanosToMillis(String toParse) {
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
return toParse;
}
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
public static String trimTZ(String toParse) {
Matcher matcher = TZ_PATTERN.matcher(toParse);
if (matcher.find()) {
toParse = matcher.group(1) + 'Z';
}
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
return toParse;
}
}

View File

@ -17,18 +17,16 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.date.internal; package org.jclouds.date.internal;
import static org.jclouds.date.internal.DateUtils.trimNanosToMillis;
import static org.jclouds.date.internal.DateUtils.trimTZ;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.logging.Logger;
/** /**
* *
@ -39,8 +37,6 @@ import org.jclouds.logging.Logger;
*/ */
public class SimpleDateFormatDateService implements DateService { public class SimpleDateFormatDateService implements DateService {
@Resource
protected Logger logger = Logger.NULL;
/* /*
* Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to * Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to
* guard against the lack of thread safety. * guard against the lack of thread safety.
@ -50,16 +46,16 @@ public class SimpleDateFormatDateService implements DateService {
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
// @GuardedBy("this") // @GuardedBy("this")
private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat( private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); Locale.US);
// @GuardedBy("this") // @GuardedBy("this")
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat( private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US); Locale.US);
// @GuardedBy("this") // @GuardedBy("this")
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat( private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss '+0000' yyyy",
"EEE MMM dd HH:mm:ss '+0000' yyyy", Locale.US); Locale.US);
static { static {
iso8601SimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT")); iso8601SimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
@ -138,29 +134,6 @@ public class SimpleDateFormatDateService implements DateService {
} }
} }
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern
.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
public static final Pattern TZ_PATTERN = Pattern.compile(".*[+-][0-9][0-9]:?[0-9][0-9]");
private String trimNanosToMillis(String toParse) {
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
return toParse;
}
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
private String trimTZ(String toParse) {
if (TZ_PATTERN.matcher(toParse).matches()) {
logger.trace("trimming tz from %s", toParse);
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
}
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
return toParse;
}
public final Date iso8601SecondsDateParse(String toParse) { public final Date iso8601SecondsDateParse(String toParse) {
toParse = trimTZ(toParse); toParse = trimTZ(toParse);
synchronized (iso8601SecondsSimpleDateFormat) { synchronized (iso8601SecondsSimpleDateFormat) {

View File

@ -162,6 +162,14 @@ public class DateServiceTest extends PerformanceTest {
assertEquals(dateService.rfc822DateFormat(date), "Sat, 26 Sep 2009 23:37:05 GMT"); assertEquals(dateService.rfc822DateFormat(date), "Sat, 26 Sep 2009 23:37:05 GMT");
} }
@Test
void testTzWithExtraZ() throws ExecutionException, InterruptedException {
assertEquals(dateService.iso8601SecondsDateParse("2011-05-26T06:14:13-04:00").toString(),
"Wed May 25 23:14:13 PDT 2011");
assertEquals(dateService.iso8601SecondsDateParse("2011-05-26T06:14:13-04:00Z").toString(),
"Wed May 25 23:14:13 PDT 2011");
}
@Test @Test
void testRfc822DateFormatResponseTime() throws ExecutionException, InterruptedException { void testRfc822DateFormatResponseTime() throws ExecutionException, InterruptedException {
for (int i = 0; i < LOOP_COUNT; i++) for (int i = 0; i < LOOP_COUNT; i++)

View File

@ -18,9 +18,11 @@
*/ */
package org.jclouds.date.joda; package org.jclouds.date.joda;
import static org.jclouds.date.internal.DateUtils.trimNanosToMillis;
import static org.jclouds.date.internal.DateUtils.trimTZ;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Pattern;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -39,19 +41,16 @@ import org.joda.time.format.DateTimeFormatter;
public class JodaDateService implements DateService { public class JodaDateService implements DateService {
private static final DateTimeFormatter rfc822DateFormatter = DateTimeFormat.forPattern( private static final DateTimeFormatter rfc822DateFormatter = DateTimeFormat.forPattern(
"EEE, dd MMM yyyy HH:mm:ss 'GMT'").withLocale(Locale.US).withZone( "EEE, dd MMM yyyy HH:mm:ss 'GMT'").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
DateTimeZone.forID("GMT"));
private static final DateTimeFormatter cDateFormatter = DateTimeFormat.forPattern( private static final DateTimeFormatter cDateFormatter = DateTimeFormat
"EEE MMM dd HH:mm:ss '+0000' yyyy").withLocale(Locale.US).withZone( .forPattern("EEE MMM dd HH:mm:ss '+0000' yyyy").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
DateTimeZone.forID("GMT"));
private static final DateTimeFormatter iso8601SecondsDateFormatter = DateTimeFormat.forPattern( private static final DateTimeFormatter iso8601SecondsDateFormatter = DateTimeFormat.forPattern(
"yyyy-MM-dd'T'HH:mm:ss'Z'").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT")); "yyyy-MM-dd'T'HH:mm:ss'Z'").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
private static final DateTimeFormatter iso8601DateFormatter = DateTimeFormat.forPattern( private static final DateTimeFormatter iso8601DateFormatter = DateTimeFormat.forPattern(
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withLocale(Locale.US).withZone( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
DateTimeZone.forID("GMT"));
public final Date fromSeconds(long seconds) { public final Date fromSeconds(long seconds) {
return new Date(seconds * 1000); return new Date(seconds * 1000);
@ -98,27 +97,11 @@ public class JodaDateService implements DateService {
} }
public final Date iso8601DateParse(String toParse) { public final Date iso8601DateParse(String toParse) {
toParse = trimTZ(toParse);
toParse = trimNanosToMillis(toParse); toParse = trimNanosToMillis(toParse);
return iso8601DateFormatter.parseDateTime(toParse).toDate(); return iso8601DateFormatter.parseDateTime(toParse).toDate();
} }
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern
.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
private String trimNanosToMillis(String toParse) {
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
return toParse;
}
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
private String trimTZ(String toParse) {
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
return toParse;
}
public final Date iso8601SecondsDateParse(String toParse) { public final Date iso8601SecondsDateParse(String toParse) {
toParse = trimTZ(toParse); toParse = trimTZ(toParse);
return iso8601SecondsDateFormatter.parseDateTime(toParse).toDate(); return iso8601SecondsDateFormatter.parseDateTime(toParse).toDate();