All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sakaiproject.tool.assessment.qti.util.Iso8601TimeInterval Maven / Gradle / Ivy

There is a newer version: 23.3
Show newest version
/**********************************************************************************
 * $URL: https://source.sakaiproject.org/svn/sam/tags/sakai-10.2/samigo-qti/src/java/org/sakaiproject/tool/assessment/qti/util/Iso8601TimeInterval.java $
 * $Id: Iso8601TimeInterval.java 106463 2012-04-02 12:20:09Z [email protected] $
 ***********************************************************************************
 *
 * Copyright (c) 2005, 2006, 2007, 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.util.Calendar;
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 Lance Speelmon
 * @version $Id: Iso8601TimeInterval.java 106463 2012-04-02 12:20:09Z [email protected] $
 */
public class Iso8601TimeInterval
{
  private static Log log = LogFactory.getLog(Iso8601TimeInterval.class);
  private static final long SECONDS = 1000L;
  private static final long MINUTES = 60L * SECONDS;
  private static final long HOURS = 60L * MINUTES;
  private static final long DAYS = 24L * HOURS;
  private static final long WEEKS = 7L * DAYS;
  private static final long MONTHS = 30L * DAYS;
  private static final long YEARS = 365L * DAYS;

  //  i.e.: P2Y10M15DT10H30M20S
  private static final Pattern PATTERN =
    Pattern.compile(
      "-?P(?:(\\d*)Y)?(?:(\\d*)M)?(?:(\\d*)W)?(?:(\\d*)D)?T?(?:(\\d*)H)?(?:(\\d*)M)?(?:(\\d*)S)?");

  // one part of the interval has a fixed date/time
  private boolean bounded = false;
  private boolean recurring = false;
  private String iso8601TimeInterval;
  private Long duration;
  private Calendar begin;
  private Calendar end;
  private Integer years;
  private Integer months;
  private Integer weeks;
  private Integer days;
  private Integer hours;
  private Integer minutes;
  private Integer seconds;
  private boolean negative = false;

  /**
   * Creates a new Iso8601TimeInterval object.
   *
   * @param iso8601TimeInterval DOCUMENTATION PENDING
   *
   * @throws Iso8601FormatException DOCUMENTATION PENDING
   */
  public Iso8601TimeInterval(String iso8601TimeInterval)
    throws Iso8601FormatException
  {
    if(log.isDebugEnabled())
    {
      log.debug("new TimeInterval(String " + iso8601TimeInterval + ")");
    }

    this.iso8601TimeInterval = iso8601TimeInterval;
    this.duration =  Long.valueOf(parseLong(iso8601TimeInterval));
  }

  /**
   * Creates a new Iso8601TimeInterval object.
   *
   * @param ms DOCUMENTATION PENDING
   */
  public Iso8601TimeInterval(long ms)
  {
    if(log.isDebugEnabled())
    {
      log.debug("new Iso8601TimeInterval(long " + ms + ")");
    }

    this.duration =  Long.valueOf(ms);
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @param iso8601TimeInterval DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   *
   * @throws Iso8601FormatException DOCUMENTATION PENDING
   */
  private long parseLong(String iso8601TimeInterval)
    throws Iso8601FormatException
  {
    if(log.isDebugEnabled())
    {
      log.debug("parseLong(String " + iso8601TimeInterval + ")");
    }

    if(iso8601TimeInterval == null)
    {
      throw new Iso8601FormatException(
        "illegal String iso8601TimeInterval argument:  iso8601TimeInterval ==null");
    }

    iso8601TimeInterval = iso8601TimeInterval.toUpperCase();
    Matcher matcher = PATTERN.matcher(iso8601TimeInterval);
    if(matcher.matches())
    {
      if(iso8601TimeInterval.indexOf("-") == 0)
      {
        log.debug("negative = true");
        negative = true;
      }

      if(log.isDebugEnabled())
      {
        for(int i = 1; i <= matcher.groupCount(); i++)
        {
          log.debug("matcher.group(" + i + ")=" + matcher.group(i));
        }
      }

      String tmp = null;

      /* years */
      int years = 0;
      tmp = matcher.group(1);
      if(tmp != null)
      {
        years = Integer.parseInt(tmp);
        this.years = new Integer(tmp);
      }

      /* months */
      int months = 0;
      tmp = matcher.group(2);
      if(tmp != null)
      {
        this.months = new Integer(tmp);
        months = this.months.intValue();
      }

      /* weeks */
      int weeks = 0;
      tmp = matcher.group(3);
      if(tmp != null)
      {
        this.weeks = new Integer(tmp);
        weeks = this.weeks.intValue();
      }

      /* days */
      int days = 0;
      tmp = matcher.group(4);
      if(tmp != null)
      {
        this.days = new Integer(tmp);
        days = this.days.intValue();
      }

      /* hours */
      int hours = 0;
      tmp = matcher.group(5);
      if(tmp != null)
      {
        this.hours = new Integer(tmp);
        hours = this.hours.intValue();
      }

      /* minutes */
      int minutes = 0;
      tmp = matcher.group(6);
      if(tmp != null)
      {
        this.minutes = new Integer(tmp);
        minutes = this.minutes.intValue();
      }

      /* seconds */
      int seconds = 0;
      tmp = matcher.group(7);
      if(tmp != null)
      {
        this.seconds = new Integer(tmp);
        seconds = this.seconds.intValue();
      }

      if(log.isDebugEnabled())
      {
        log.debug(
          "years=" + years + ", months=" + months + ", weeks=" + weeks +
          ", days=" + days + ", hours=" + hours + ", minutes=" + minutes +
          ", seconds=" + seconds);
      }

      long durtmp =
        (years * YEARS) + (months * MONTHS) + (weeks * WEEKS) + (days * DAYS) +
        (hours * HOURS) + (minutes * MINUTES) + (seconds * SECONDS);
      if(negative)
      {
        return -durtmp;
      }
      else
      {
        return durtmp;
      }
    }
    else
    {
      throw new Iso8601FormatException(
        "Invalid ISO8601 format: " + iso8601TimeInterval);
    }
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public boolean isBounded()
  {
    log.debug("isBounded()");

    //    return bounded;
    throw new UnsupportedOperationException();
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public boolean isRecurring()
  {
    //    return recurring;
    throw new UnsupportedOperationException();
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public long getDuration()
  {
    log.debug("getDuration()");

    return duration.longValue();
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public Calendar getBegin()
  {
    throw new UnsupportedOperationException();

    //    return begin;
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public Calendar getEnd()
  {
    throw new UnsupportedOperationException();

    //    return end;
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public String toString()
  {
    if(this.iso8601TimeInterval == null)
    {
      this.createIso8601TimeInterval();
    }

    return this.iso8601TimeInterval;
  }

  /**
   * DOCUMENTATION PENDING
   */
  public void createString()
  {
    log.debug("regenerateString()");
    this.reset(); // clear any old bean properties
    this.createIso8601TimeInterval();
  }

  /**
   * DOCUMENTATION PENDING
   */
  private void createIso8601TimeInterval()
  {
    log.debug("createIso8601TimeInterval()");
    if(this.duration == null)
    {
      throw new IllegalStateException("duration is null!");
    }

    if(this.duration.longValue() < 0)
    {
      negative = true;
    }

    long remainder = this.duration.longValue();

    /* anything above weeks incurs a loss of precision */

    //    int years = (int)(remainder / YEARS);
    //    remainder %= YEARS;

    /* anything above weeks incurs a loss of precision */

    //    int months = (int)(remainder / MONTHS);
    //    remainder %= MONTHS;
    int weeks = (int) (remainder / WEEKS);
    remainder %= WEEKS;

    int days = (int) (remainder / DAYS);
    remainder %= DAYS;

    int hours = (int) (remainder / HOURS);
    remainder %= HOURS;

    int minutes = (int) (remainder / MINUTES);
    remainder %= MINUTES;

    int seconds = (int) (remainder / SECONDS);

    StringBuilder sb = new StringBuilder();
    if(negative)
    {
      sb.append("-");
    }

    sb.append("P");
    if(weeks != 0)
    {
      if(negative)
      {
        sb.append(-weeks);
        this.weeks =  Integer.valueOf(-weeks);
      }
      else
      {
        sb.append(weeks);
        this.weeks =  Integer.valueOf(weeks);
      }

      sb.append("W");
    }

    if(days != 0)
    {
      if(negative)
      {
        sb.append(-days);
        this.days = Integer.valueOf(-days);
      }
      else
      {
        sb.append(days);
        this.days = Integer.valueOf(days);
      }

      sb.append("D");
    }

    if((hours != 0) || (minutes != 0) || (seconds != 0))
    {
      sb.append("T");
      if(hours != 0)
      {
        if(negative)
        {
          sb.append(-hours);
          this.hours = Integer.valueOf(-hours);
        }
        else
        {
          sb.append(hours);
          this.hours = Integer.valueOf(hours);
        }

        sb.append("H");
      }

      if(minutes != 0)
      {
        if(negative)
        {
          sb.append(-minutes);
          this.minutes = Integer.valueOf(-minutes);
        }
        else
        {
          sb.append(minutes);
          this.minutes = Integer.valueOf(minutes);
        }

        sb.append("M");
      }

      if(seconds != 0)
      {
        if(negative)
        {
          sb.append(-seconds);
          this.seconds = Integer.valueOf(-seconds);
        }
        else
        {
          sb.append(seconds);
          this.seconds = Integer.valueOf(seconds);
        }

        sb.append("S");
      }
    }

    this.iso8601TimeInterval = sb.toString();
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @param args DOCUMENTATION PENDING
   */
  public static void main(String[] args)
  {
    org.apache.log4j.BasicConfigurator.configure();
    try
    {
      Iso8601TimeInterval ti = new Iso8601TimeInterval("-P2y10m15dT10H30M20S");

      //      Iso8601TimeInterval ti = new Iso8601TimeInterval("PT1S");
      //      Iso8601TimeInterval ti = new Iso8601TimeInterval("P6W");
      //      Iso8601TimeInterval ti = new Iso8601TimeInterval(null);
      long duration = ti.getDuration();
      log.debug("duration=" + duration);
      log.debug("weeks=" + ti.getWeeks());
      log.debug("days=" + ti.getDays());

      Iso8601TimeInterval t2 = new Iso8601TimeInterval(duration);
      log.debug("t2=" + t2);
      log.debug("t2.getWeeks()=" + t2.getWeeks());
      log.debug("t2.getHours()=" + t2.getHours());
    }
    catch(Iso8601FormatException ex)
    {
      log.error(ex.getMessage(), ex);
    }
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getDays()
  {
    return days;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getHours()
  {
    return hours;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getMinutes()
  {
    return minutes;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getMonths()
  {
    return months;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getSeconds()
  {
    return seconds;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getWeeks()
  {
    return weeks;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
   */
  public Integer getYears()
  {
    return years;
  }

  /**
   * DOCUMENTATION PENDING
   *
   * @return DOCUMENTATION PENDING
   */
  public boolean isNegative()
  {
    return this.negative;
  }

  /**
   * DOCUMENTATION PENDING
   */
  private void reset()
  {
    log.debug("reset()");
    this.years = null;
    this.months = null;
    this.weeks = null;
    this.days = null;
    this.hours = null;
    this.minutes = null;
    this.seconds = null;
    this.negative = false;
  }
}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy