Ok, kinda lengthy, but I think this bit of code should solve everyone's use case.... Feel free to scavenge it for JAXB :)
package com.temporalwave.util;
import java.util.*;
/**
* Parse or Create XML Schema dataType "duration"
*/
public class XSDuration
{
public static final int YEARS = 0;
public static final int MONTHS = 1;
public static final int DAYS = 2;
public static final int HOURS = 3;
public static final int MINUTES = 4;
public static final int SECONDS = 5;
protected int years = 0;
protected int months = 0;
protected int days = 0;
protected int hours = 0;
protected int minutes = 0;
protected int seconds = 0;
public XSDuration()
{
}
public XSDuration(String duration)
{
this();
parse(duration);
}
public void parse(String duration)
{
int tNdx = duration.indexOf("T");
String date, time;
if(tNdx == -1)
{
date = duration.substring(1);
time = "";
}else{
date = duration.substring(1,tNdx);
time = duration.substring(tNdx + 1);
}
int num = 0;
char c;
for(int pos=0; pos<date.length(); pos++)
{
c = date.charAt(pos);
if(Character.isDigit(c))
{
num = (num * 10) + Integer.parseInt("" + c);
}else{
if( (c == 'Y') || (c == 'y') )
years = num;
else if( (c == 'M') || (c == 'm') )
months = num;
else if( (c == 'D') || (c == 'd') )
days = num;
num = 0;
}
}
for(int pos=0; pos<time.length(); pos++)
{
c = time.charAt(pos);
if(Character.isDigit(c))
{
num = (num * 10) + Integer.parseInt("" + c);
}else{
if( (c == 'H') || (c == 'h') )
hours = num;
else if( (c == 'M') || (c == 'm') )
minutes = num;
else if( (c == 'S') || (c == 's') )
seconds = num;
num = 0;
}
}
}
public String format()
{
StringBuffer buf = new StringBuffer();
buf.append("P");
if(years >0) buf.append(years + "Y");
if(months >0) buf.append(months + "M");
if(days >0) buf.append(days + "D");
if( (hours+minutes+seconds) > 0)
{
buf.append("T");
if(hours > 0) buf.append(hours + "H");
if(minutes > 0) buf.append(minutes + "M");
if(seconds > 0) buf.append(seconds + "S");
}
return buf.toString();
}
public void set(int field, int value)
{
switch(field)
{
case YEARS: years=value;break;
case MONTHS: months=value;break;
case DAYS: days=value;break;
case HOURS: hours=value;break;
case MINUTES: minutes=value;break;
case SECONDS: seconds=value;break;
}
}
public int get(int field)
{
switch(field)
{
case YEARS: return years;
case MONTHS: return months;
case DAYS: return days;
case HOURS: return hours;
case MINUTES: return minutes;
case SECONDS: return seconds;
}
return -1;
}
public void addTo(Calendar cal)
{
cal.add(cal.YEAR, years);
cal.add(cal.MONTH, months);
cal.add(cal.DAY_OF_MONTH, days);
cal.add(cal.HOUR, hours);
cal.add(cal.MINUTE, minutes);
cal.add(cal.SECOND, seconds);
}
public long getMilliseconds()
{
Calendar now = Calendar.getInstance();
long current = now.getTimeInMillis();
addTo(now);
long future = now.getTimeInMillis();
return future-current;
}
public String toString(){return format();}
public static void main(String[] args)
{
if(args.length != 1)
{
System.out.println("USAGE: java -cp TWCommon.jar com.temporalwave.util.XSDuration PERIOD");
System.out.println("Where PERIOD is something like 'P5Y2M10DT15H3M20S'");
System.exit(1);
}
XSDuration duration = new XSDuration(args[0]);
System.out.println(args[0]);
System.out.println("----------------------------------");
System.out.println("YEARS:\t\t" + duration.get(YEARS));
System.out.println("MONTHS:\t\t"+ duration.get(MONTHS));
System.out.println("DAYS:\t\t" + duration.get(DAYS));
System.out.println("HOURS:\t\t" + duration.get(HOURS));
System.out.println("MINUTES:\t" + duration.get(MINUTES));
System.out.println("SECONDS:\t" + duration.get(SECONDS));
System.out.println("----------------------------------");
System.out.println("Total Milliseconds: " + duration.getMilliseconds());
Calendar now = Calendar.getInstance();
System.out.println("NOW:\t\t" + now.getTime());
duration.addTo(now);
System.out.println("+Duration:\t" + now.getTime());
System.out.println("----------------------------------");
System.out.println(duration);
}
}