// ISODate.java
// $Id: ISODate.java,v 1.1 1997/04/15 20:39:21 yhchu Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.www.dsig;

import java.util.Date;

/**
 * ISO Date
 * <P>
 * NOTE: This class uses methods from java.util.Data which are
 * deprecated in JDK 1.1.
 * <P>
 * WARNING: Time zone offset seems to be incorrect to me.
 * <P>
 * There seem to be more bugs in java.util.Date, probably this class
 * should be rewritten for JDK 1.1 Calendars.
 *
 * @author Yang-hua Chu
 * @author Andreas Sterbenz
 */
public class ISODate
{
  private Date date;
  private String dateString;

  /**
   * constructs an ISODate initialized with current time.
   */
  public ISODate()
  {
    this.date = new Date();
    this.dateString = dateToISODateString(this.date);
  }

  /**
   * Parses a String representation of an ISODate.
   */
  public ISODate(String s)
  {
    this.date = transformISODateToDate(s);
    this.dateString = s;
  }


  /**
   * Constructs an ISODate from java.util.Date
   */
  public ISODate(Date date)
  {
    this.date = date;
    this.dateString = dateToISODateString(this.date);
  }

  /**
   * Returns an equivalent java.util.Date object
   */
  public Date getDate()
  {
    return this.date;
  }

  /**
   * Returns a String representation of the ISODate.
   */
  public String toString()
  {
    return this.dateString;
  }

  /**
   * Returns a String representation of the ISODate for a give Date object
   */
  public static String dateToISODateString(Date date)
  {
    //1994.11.05.T08:15-0500
    String s = "" + (1900 + date.getYear()) + ".";
    s += intPad(date.getMonth()+1) + ".";
    s += intPad(date.getDate());
    s += "T" + intPad(date.getHours()) + ":";
    s += intPad(date.getMinutes());
    int tzofs = date.getTimezoneOffset();
//    System.out.println("timezone: " + tzofs);
    if (tzofs >= 0)
      s += "+";
    else
      s += "-";
    s += intPad( Math.abs(tzofs / 60) );
    s += intPad( Math.abs(tzofs % 60) );
    return s;
  }

  private static String intPad(int i)
  {
    if (i<10)
      return "0" + i;
    else
      return "" + i;
  }


  public static Date transformISODateToDate(String isoDate)
    throws NumberFormatException
  {
    if (  isoDate.length() != 21  ||
        isoDate.charAt( 4) != '.' ||
        isoDate.charAt( 7) != '.' ||
        isoDate.charAt(10) != 'T' ||
        isoDate.charAt(13) != ':')
      throw new NumberFormatException();
    int year       = Integer.parseInt(isoDate.substring(0, 4));
    int month      = Integer.parseInt(isoDate.substring(5, 7));
    int day        = Integer.parseInt(isoDate.substring(8, 10));
    int hour       = Integer.parseInt(isoDate.substring(11, 13));
    int minute     = Integer.parseInt(isoDate.substring(14, 16));
    char zoneSign  = isoDate.charAt(16);
    int zoneHour   = Integer.parseInt(isoDate.substring(17, 19));
    int zoneMinute = Integer.parseInt(isoDate.substring(19));
    if (month < 1 || month > 12 || day < 1 || day > 31 ||
	hour < 0 || hour > 23 || minute < 0 || minute > 60 || // leap-second!!
	(zoneSign != '+' && zoneSign != '-') ||
	zoneHour < 0 || zoneHour > 23 || zoneMinute < 0 || zoneMinute > 59)
      throw new NumberFormatException();
    long utc = Date.UTC(year-1900, month-1, day, hour, minute, 0);
    int offset = 60 * (60 * zoneHour + zoneMinute);
    if (zoneSign == '-')
      utc -= offset;
    else
      utc += offset;
    Date d = new Date(utc);
//    System.out.println("day before: " + day + ", after: " + d.getDate());
//    System.out.println("min before: " + minute + ", after: " + d.getMinutes());
    return d;
//    return new Date(utc);
  }

  public static void main(String argv[])
  {
    Date today1 = new Date();
    ISODate today2 = new ISODate();
    ISODate today3 = new ISODate(today1);
    System.out.println("Today's day from Java:       " + today1.toString());
//    System.out.println("Today's day from Java:       " +
//		       (new Date(today1.toString())).toString());
    System.out.println("Today's day from this class: " + today2.toString());
    System.out.println("Today's day from this class: " + today3.toString());
    System.out.println("Today's day from conversion: " +
		       (new ISODate(today2.toString()).toString()));
    System.out.println("Check: all four should be the same value");
    waitKey();
  }
  static void waitKey()
  {
    System.out.println("Hit the <RETURN> key.");
    try {
      System.in.read();
    } catch( java.io.IOException e ) {
      ;
    }
  }

}
