/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-qti/src/java/org/sakaiproject/tool/assessment/qti/util/Iso8601DateFormat.java $
* $Id: Iso8601DateFormat.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $
***********************************************************************************
*
* Copyright (c) 2005, 2006, 2008, 2009 The Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.tool.assessment.qti.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.tool.assessment.qti.exception.Iso8601FormatException;
/**
* Based on ISO8601 Specification.
*
* @author <a href="mailto:lance@indiana.edu">Lance Speelmon</a>
* @version $Id: Iso8601DateFormat.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $
*/
public class Iso8601DateFormat
{
public static final String BASIC_FORMAT = "yyyyMMdd'T'HHmmssZ";
private static Log log = LogFactory.getLog(Iso8601DateFormat.class);
private static final String GMT = "GMT";
// 20031107T152420-0500 or
// 2003-11-07T15:24:20-05:00
private static final Pattern PATTERN_MATCH =
Pattern.compile(
"^(?:(\\d{2,4})-?)?" + // year
"(?:(\\d{2})-?)?" + // month
"(\\d{2})?" + // day of month
"T?" + // time separator
"(?:(\\d{2}):?)?" + // hour
"(?:(\\d{2}):?)?" + // minutes
"(\\d{2})?" + // seconds
"(Z?|(?:\\+|-).+)?$"); // timezone: -0500 or +08:00 or -05 or Z
private String pattern;
/**
* Creates a new Iso8601DateFormat object.
*/
public Iso8601DateFormat()
{
log.debug("new Iso8601DateFormat()");
this.pattern = BASIC_FORMAT;
}
/**
* DOCUMENT ME!
*
* @param simpleDateFormatPattern
*
* @see java.text.SimpleDateFormat
*/
public Iso8601DateFormat(String simpleDateFormatPattern)
{
log.debug("new Iso8601DateFormat(String " + simpleDateFormatPattern + ")");
this.pattern = simpleDateFormatPattern;
}
/**
* DOCUMENTATION PENDING
*
* @param date DOCUMENTATION PENDING
*
* @return DOCUMENTATION PENDING
*/
public String format(Date date)
{
log.debug("format(Date " + date + ")");
SimpleDateFormat sdf = null;
if(this.pattern == null)
{
sdf = new SimpleDateFormat();
}
else
{
sdf = new SimpleDateFormat(pattern);
}
return sdf.format(date);
}
/**
* DOCUMENTATION PENDING
*
* @param iso8601String DOCUMENTATION PENDING
*
* @return DOCUMENTATION PENDING
*
* @throws Iso8601FormatException DOCUMENTATION PENDING
*/
public Calendar parse(String iso8601String)
throws Iso8601FormatException
{
log.debug("parse(String " + iso8601String + ")");
if(iso8601String == null)
{
throw new Iso8601FormatException(
"illegal String iso8601TimeInterval argument: iso8601String == null");
}
iso8601String = iso8601String.toUpperCase();
final Matcher matcher = PATTERN_MATCH.matcher(iso8601String);
if(matcher.matches())
{
if(log.isDebugEnabled())
{
for(int i = 0; i <= matcher.groupCount(); i++)
{
log.debug(i + "=" + matcher.group(i));
}
}
String tz = matcher.group(7);
Calendar cal = null;
if((tz != null) && (tz.length() > 0))
{
if("Z".equals(tz))
{
tz = "Zulu";
}
else
{
tz = GMT + tz;
}
if(log.isDebugEnabled())
{
log.debug("tz=" + tz);
log.debug("TimeZone.getID()=" + TimeZone.getTimeZone(tz).getID());
}
cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(tz));
}
else
{
cal = GregorianCalendar.getInstance();
/* data must be zeroed out to counteract now behavior*/
cal.clear();
}
/* year */
if(matcher.group(1) != null)
{
final int year = Integer.parseInt(matcher.group(1));
cal.set(Calendar.YEAR, year);
}
else
{
throw new Iso8601FormatException("Year is required");
}
/* month */
if(matcher.group(2) != null)
{
final int month = Integer.parseInt(matcher.group(2)) - 1; // zero based
cal.set(Calendar.MONTH, month);
}
/* date (day) */
if(matcher.group(3) != null)
{
final int date = Integer.parseInt(matcher.group(3));
cal.set(Calendar.DAY_OF_MONTH, date);
}
/* hour */
if(matcher.group(4) != null)
{
final int hour = Integer.parseInt(matcher.group(4));
cal.set(Calendar.HOUR_OF_DAY, hour);
}
/* minutes */
if(matcher.group(5) != null)
{
final int min = Integer.parseInt(matcher.group(5));
cal.set(Calendar.MINUTE, min);
}
/* seconds */
if(matcher.group(6) != null)
{
final int sec = Integer.parseInt(matcher.group(6));
cal.set(Calendar.SECOND, sec);
}
return cal;
}
throw new Iso8601FormatException("ISO8601 format could not be matched");
}
}