Package org.xmlBlaster.util

Source Code of org.xmlBlaster.util.IsoDateParser

// IsoDateParser.java
// $Id: IsoDateParser.java,v 1.5 2005/05/16 10:19:19 ylafon Exp $
// (c) COPYRIGHT MIT, INRIA and Keio, 2000.
// Please first read the full copyright statement in file COPYRIGHT.html
//package org.w3c.util;
package org.xmlBlaster.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.ReadableDuration;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

/*
* ISO 8601 date time formatting.
* http://www.w3.org/TR/NOTE-datetime
* http://en.wikipedia.org/wiki/ISO_8601
* http://www.probabilityof.com/ISO8601.shtml
* <pre>
* YYYY-MM-DDThh:mm:ss.fTZD (eg 1997-07-16T19:20:30.45+01:00)
* f can be one f to ffffffff (fraction of seconds)
* 1994-11-05T13:15:30Z  (Z stands for UTC==GMT)
* </pre>
* If no time zone information is given with a time, the time zone is assumed to be in some conventional local timezone.
* <br />
* Note that the "T" appears literally in the string, to indicate the beginning of the time element, as specified in ISO 8601.
* <br />
* The standard allows the replacement of T with a space if no misunderstanding arises.
* @return The ISO 8601 UTC-time string, precision is currently millis (three fraction digits)
* "2006-02-21 14:05:51.703+0000"
*/

/**
* Date parser for ISO 8601 format
* http://www.w3.org/TR/1998/NOTE-datetime-19980827
* @version $Revision: 1.5 $
* @author  Beno�t Mah� (bmahe@w3.org)
* @author  Yves Lafon (ylafon@w3.org)
*/
public class IsoDateParser {

   public final static SimpleDateFormat utcFmt;
   public final static SimpleDateFormat utcFmtT;
   static {
      // Creates 2006-07-16 21:20:30.450+0000: illegal , must be +00:00
      //utcFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SZ", Locale.US);
      utcFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S", Locale.US);
      utcFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
      utcFmtT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S", Locale.US);
      utcFmtT.setTimeZone(TimeZone.getTimeZone("GMT"));
      //Calendar utcCal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
   }

   /**
    * @return The ISO 8601 UTC-time string
    * "2006-02-21"
    */
   public static String getCurrentUTCDate() {
      return getUTCTimestamp(new Date()).substring(0, 10);
   }

   /**
    * @return The ISO 8601 UTC-time string
    * "2006-02-21"
    */
   public static String getCurrentUTCTime() {
      return getUTCTimestamp(new Date()).substring(11);
   }

   /**
    * @return The ISO 8601 UTC-time string, precision is currently millis (three fraction digits)
    * "2006-02-21 14:05:51.703Z"
    */
   public static String getCurrentUTCTimestamp() {
      return getUTCTimestamp(new Date());
   }

   /**
    * Returns currently milli precission or an increment counter if called more than once per milli.
    * @return e.g. "2007-07-09 10:35:43.946Z" or "2007-07-09 10:36:38.180000005Z"
    */
   public static String getCurrentUTCTimestampNanos() {
    //Timestamp ts = new Timestamp(1183977398180000005L); // org.xmlBlaster.util.Timestamp
    Timestamp ts = new Timestamp();
    String tmp = getUTCTimestamp(ts.getMillis());
    int i = tmp.indexOf(".");
    if (i<0) return tmp;
    if ((ts.getNanosOnly() % 1000) > 0) {
      tmp = tmp.substring(0,i);
      tmp += "."+ts.getNanosOnly();
      tmp += "Z";
    }
      return tmp;
   }

   public static String getUTCTimestamp(Date date) {
      synchronized (utcFmt) {
         return utcFmt.format(date)+"Z";
      }
   }

   public static String getUTCTimestamp(long millis) {
      return IsoDateParser.getUTCTimestamp(new Date(millis));
   }

   /**
    * @return The ISO 8601 UTC-time string, precision is currently millis (three fraction digits)
    * "2006-02-21T14:05:51.703Z"
    */
   public static String getCurrentUTCTimestampT() {
      return getUTCTimestampT(new Date());
   }

   public static String getUTCTimestampT(Date date) {
      synchronized (utcFmtT) {
         return utcFmtT.format(date)+"Z";
      }
   }
  
  
   /**
    * Calculate the difference from the given time to now.
    * ISO 8601 states: Durations are represented by the format P[n]Y[n]M[n]DT[n]H[n]M[n]S
    * @param utc Given time, e.g. "1997-07-16T19:20:30.45+01:00"
    * @return The ISO 8601 Period like "P3Y6M4DT12H30M17S"
    */
   public static String getDifferenceToNow(String utc) {
     if (utc == null) return "";
     utc = ReplaceVariable.replaceAll(utc, " ", "T");
     DateTime now = new DateTime();
     DateTimeFormatter f = ISODateTimeFormat.dateTimeParser();
     DateTime other = f.parseDateTime(utc);
     Period period = new Period(other, now); // Period(ReadableInstant startInstant, ReadableInstant endInstant)
     return period.toString();
   }

   /**
    * @param utc "2001-02-03 04:05:06.7"
   public static Date getParseUTC(String utc) {
      synchronized (utcFmt) {
         try {
            return utcFmt.parse(utc);
         } catch (ParseException e) {
            throw new IllegalArgumentException("getParseUTC("+utc+"): " + e.toString());
         }
      }
   }
    */

    private static boolean check(StringTokenizer st, String token)
   throws IllegalArgumentException
    {
   try {
       if (st.nextToken().equals(token)) {
      return true;
       } else {
      throw new IllegalArgumentException("Missing ["+token+"]");
       }
   } catch (NoSuchElementException ex) {
       return false;
   }
    }

    public static Calendar getCalendar(String isodate)
      throws IllegalArgumentException
    {
   // YYYY-MM-DDThh:mm:ss.sTZD
       // Marcel: Added ' ' to T replacement (ISO allows blanks)
   int index = isodate.indexOf(' ');
   if (index > 0)
      isodate = isodate.substring(0, index) + "T" + isodate.substring(index+1);
   StringTokenizer st = new StringTokenizer(isodate, "-T:.+Z", true);

   Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
   calendar.clear();
   try {
       // Year
       if (st.hasMoreTokens()) {
      int year = Integer.parseInt(st.nextToken());
      calendar.set(Calendar.YEAR, year);
       } else {
      return calendar;
       }
       // Month
       if (check(st, "-") && (st.hasMoreTokens())) {
      int month = Integer.parseInt(st.nextToken()) -1;
      calendar.set(Calendar.MONTH, month);
       } else {
      return calendar;
       }
       // Day
       if (check(st, "-") && (st.hasMoreTokens())) {
      int day = Integer.parseInt(st.nextToken());
      calendar.set(Calendar.DAY_OF_MONTH, day);
       } else {
      return calendar;
       }
       // Hour
       if (check(st, "T") && (st.hasMoreTokens())) {
      int hour = Integer.parseInt(st.nextToken());
      calendar.set(Calendar.HOUR_OF_DAY, hour);
       } else {
      calendar.set(Calendar.HOUR_OF_DAY, 0);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return calendar;
       }
       // Minutes
       if (check(st, ":") && (st.hasMoreTokens())) {
      int minutes = Integer.parseInt(st.nextToken());
      calendar.set(Calendar.MINUTE, minutes);
       } else {
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return calendar;
       }

       //
       // Not mandatory now
       //

       // Secondes
       if (! st.hasMoreTokens()) {
      return calendar;
       }
       String tok = st.nextToken();
       if (tok.equals(":")) { // secondes
      if (st.hasMoreTokens()) {
          int secondes = Integer.parseInt(st.nextToken());
          calendar.set(Calendar.SECOND, secondes);
          if (! st.hasMoreTokens()) {
         return calendar;
          }
          // frac sec
          tok = st.nextToken();
          if (tok.equals(".")) {
         // bug fixed, thx to Martin Bottcher
         String nt = st.nextToken();
         while(nt.length() < 3) {
             nt += "0";
         }
         nt = nt.substring( 0, 3 ); //Cut trailing chars..
         int millisec = Integer.parseInt(nt);
         //int millisec = Integer.parseInt(st.nextToken()) * 10;
         calendar.set(Calendar.MILLISECOND, millisec);
         if (! st.hasMoreTokens()) {
             return calendar;
         }
         tok = st.nextToken();
          } else {
         calendar.set(Calendar.MILLISECOND, 0);
          }
      } else {
          throw new IllegalArgumentException("No secondes specified");
      }
       } else {
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
       }
       // Timezone
       if (! tok.equals("Z")) { // UTC
      if (! (tok.equals("+") || tok.equals("-"))) {
          throw new IllegalArgumentException("only Z, + or - allowed");
      }
      boolean plus = tok.equals("+");
      if (! st.hasMoreTokens()) {
          throw new IllegalArgumentException("Missing hour field");
      }
      int tzhour = Integer.parseInt(st.nextToken());
      int tzmin  = 0;
      if (check(st, ":") && (st.hasMoreTokens())) {
          tzmin = Integer.parseInt(st.nextToken());
      } else {
          throw new IllegalArgumentException("Missing minute field");
      }
      if (plus) {
          calendar.add(Calendar.HOUR, -tzhour);
          calendar.add(Calendar.MINUTE, -tzmin);
      } else {
          calendar.add(Calendar.HOUR, tzhour);
          calendar.add(Calendar.MINUTE, tzmin);
      }
       }
   } catch (NumberFormatException ex) {
       throw new IllegalArgumentException("["+ex.getMessage()+
                  "] is not an integer");
   }
   return calendar;
    }

    /**
     * Parse the given string in ISO 8601 format and build a Date object.
     * @param isodate the date in ISO 8601 format
     * @return a Date instance
     * @exception IllegalArgumentException if the date is not valid
     */
    public static Date parse(String isodate)
      throws IllegalArgumentException
    {
   Calendar calendar = getCalendar(isodate);
   return calendar.getTime();
    }

    private static String twoDigit(int i) {
   if (i >=0 && i < 10) {
       return "0"+String.valueOf(i);
   }
   return String.valueOf(i);
    }

    /**
     * Generate a ISO 8601 date
     * @param date a Date instance
     * @return a string representing the date in the ISO 8601 format
     */
    public static String getIsoDate(Date date) {
   Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
   calendar.setTime(date);
   StringBuffer buffer = new StringBuffer();
   buffer.append(calendar.get(Calendar.YEAR));
   buffer.append("-");
   buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1));
   buffer.append("-");
   buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH)));
   buffer.append("T");
   buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY)));
   buffer.append(":");
   buffer.append(twoDigit(calendar.get(Calendar.MINUTE)));
   buffer.append(":");
   buffer.append(twoDigit(calendar.get(Calendar.SECOND)));
   buffer.append(".");
   buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10));
   buffer.append("Z");
   return buffer.toString();
    }

    /**
     * Generate a ISO 8601 date
     * @param date a Date instance
     * @return a string representing the date in the ISO 8601 format
     */
    public static String getIsoDateNoMillis(Date date) {
   Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
   calendar.setTime(date);
   StringBuffer buffer = new StringBuffer();
   buffer.append(calendar.get(Calendar.YEAR));
   buffer.append("-");
   buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1));
   buffer.append("-");
   buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH)));
   buffer.append("T");
   buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY)));
   buffer.append(":");
   buffer.append(twoDigit(calendar.get(Calendar.MINUTE)));
   buffer.append(":");
   buffer.append(twoDigit(calendar.get(Calendar.SECOND)));
   buffer.append("Z");
   return buffer.toString();
    }

    public static void test(String isodate) {
   System.out.println("----------------------------------");
   try {
       Date date = parse(isodate);
       System.out.println("GIVEN >> "+isodate);
       System.out.println("LOCAL >> "+date.toString()+" ["+date.getTime()+"]");
       System.out.println("UTC   >> "+ getUTCTimestamp(date));
       System.out.println("UTCT  >> "+ getUTCTimestampT(date));
       System.out.println("ISO   >> "+getIsoDate(date));
   } catch (IllegalArgumentException ex) {
       System.err.println(isodate+" is invalid");
       System.err.println(ex.getMessage());
   }
   System.out.println("----------------------------------");
    }

    public static void test(Date date) {
   String isodate = null;
   System.out.println("----------------------------------");
   try {
       System.out.println("GIVEN >> "+date.toString()+" ["+date.getTime()+"]");
       isodate = getIsoDate(date);
       System.out.println("ISO   >> "+isodate);
       date = parse(isodate);
       System.out.println("PARSED>> "+date.toString()+" ["+date.getTime()+"]");
   } catch (IllegalArgumentException ex) {
       System.err.println(isodate+" is invalid");
       System.err.println(ex.getMessage());
   }
   System.out.println("----------------------------------");
    }

    // java org.xmlBlaster.util.IsoDateParser
   public static void main(String args[]) {
    {
      String utc = "1997-07-16T19:20:30.45+01:00";
      String period = getDifferenceToNow(utc);
      System.out.println("now - " + utc + " = " + period);
    }
      {
      String utc = "1997-07-16 19:20:30.45+01:00";
      String period = getDifferenceToNow(utc);
      System.out.println("now - " + utc + " = " + period);
      }

   test("1997-07-16T19:20:30.45-02:00");
   test("1997-07-16T19:20:30.678Z");
   test("2006-07-16T21:20:30.450+00:00");
   //test("2006-07-16T21:20:30.450+0000"); invalid

   test("1997-07-16 19:20:30.45-02:00");
   test("1997-07-16 19:20:30.678Z");
   test("2006-07-16 21:20:30.450+00:00");

   test("1997-07-16T19:20:30+01:00");
   test("1997-07-16T19:20:30+01:00");
   test("1997-07-16T12:20:30-06:00");
   test("1997-07-16T19:20");
   test("1997-07-16");
   test("1997-07");
   test("1997");
   test(new Date());
    }

}
TOP

Related Classes of org.xmlBlaster.util.IsoDateParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.