2 *******************************************************************************
\r
3 * Copyright (C) 2007-2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.impl.duration;
\r
9 import java.text.FieldPosition;
\r
10 import java.util.Date;
\r
12 import com.ibm.icu.text.DurationFormat;
\r
13 import com.ibm.icu.util.ULocale;
\r
18 public class BasicDurationFormat extends DurationFormat {
\r
23 private static final long serialVersionUID = -3146984141909457700L;
\r
25 transient DurationFormatter formatter;
\r
26 transient PeriodFormatter pformatter;
\r
27 transient PeriodFormatterService pfs = null;
\r
29 public static BasicDurationFormat getInstance(ULocale locale) {
\r
30 return new BasicDurationFormat(locale);
\r
33 private static boolean checkXMLDuration = true;
\r
35 public StringBuffer format(Object object, StringBuffer toAppend, FieldPosition pos) {
\r
36 if(object instanceof Long) {
\r
37 String res = formatDurationFromNow(((Long)object).longValue());
\r
38 return toAppend.append(res);
\r
39 } else if(object instanceof Date) {
\r
40 String res = formatDurationFromNowTo(((Date)object));
\r
41 return toAppend.append(res);
\r
43 if(checkXMLDuration) try {
\r
44 if(object instanceof javax.xml.datatype.Duration) {
\r
45 String res = formatDuration(object);
\r
46 return toAppend.append(res);
\r
48 } catch ( NoClassDefFoundError ncdfe ) {
\r
49 System.err.println("Skipping XML capability");
\r
50 checkXMLDuration = false; // don't try again
\r
52 throw new IllegalArgumentException("Cannot format given Object as a Duration");
\r
56 public BasicDurationFormat() {
\r
57 pfs = BasicPeriodFormatterService.getInstance();
\r
58 formatter = pfs.newDurationFormatterFactory().getFormatter();
\r
59 pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).getFormatter();
\r
64 public BasicDurationFormat(ULocale locale) {
\r
66 pfs = BasicPeriodFormatterService.getInstance();
\r
67 formatter = pfs.newDurationFormatterFactory().setLocale(locale.getName()).getFormatter();
\r
68 pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).setLocale(locale.getName()).getFormatter();
\r
72 * @see com.ibm.icu.text.DurationFormat#formatDurationFrom(long, long)
\r
74 public String formatDurationFrom(long duration, long referenceDate) {
\r
75 return formatter.formatDurationFrom(duration, referenceDate);
\r
79 * @see com.ibm.icu.text.DurationFormat#formatDurationFromNow(long)
\r
81 public String formatDurationFromNow(long duration) {
\r
82 return formatter.formatDurationFromNow(duration);
\r
86 * @see com.ibm.icu.text.DurationFormat#formatDurationFromNowTo(java.util.Date)
\r
88 public String formatDurationFromNowTo(Date targetDate) {
\r
89 return formatter.formatDurationFromNowTo(targetDate);
\r
94 * @param obj Object being passed.
\r
95 * @return The PeriodFormatter object formatted to the object passed.
\r
96 * @see "http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/datatype/Duration.html"
\r
98 public String formatDuration(Object obj) {
\r
99 javax.xml.datatype.DatatypeConstants.Field inFields[] = {
\r
100 javax.xml.datatype.DatatypeConstants.YEARS,
\r
101 javax.xml.datatype.DatatypeConstants.MONTHS,
\r
102 javax.xml.datatype.DatatypeConstants.DAYS,
\r
103 javax.xml.datatype.DatatypeConstants.HOURS,
\r
104 javax.xml.datatype.DatatypeConstants.MINUTES,
\r
105 javax.xml.datatype.DatatypeConstants.SECONDS,
\r
107 TimeUnit outFields[] = {
\r
116 javax.xml.datatype.Duration inDuration = (javax.xml.datatype.Duration)obj;
\r
118 javax.xml.datatype.Duration duration = inDuration;
\r
119 boolean inPast = false;
\r
120 if(inDuration.getSign()<0) {
\r
121 duration = inDuration.negate();
\r
124 // convert a Duration to a Period
\r
125 boolean sawNonZero = false; // did we have a set, non-zero field?
\r
126 for(int i=0;i<inFields.length;i++) {
\r
127 if(duration.isSet(inFields[i])) {
\r
128 Number n = duration.getField(inFields[i]);
\r
129 if(n.intValue() == 0 && !sawNonZero) {
\r
130 continue; // ignore zero fields larger than the largest nonzero field
\r
134 float floatVal = n.floatValue();
\r
135 // is there a 'secondary' unit to set?
\r
136 TimeUnit alternateUnit = null;
\r
137 float alternateVal = 0;
\r
139 // see if there is a fractional part
\r
140 if(outFields[i]==TimeUnit.SECOND) {
\r
141 double fullSeconds = floatVal;
\r
142 double intSeconds = Math.floor(floatVal);
\r
143 double millis = (fullSeconds-intSeconds)*1000.0;
\r
145 alternateUnit = TimeUnit.MILLISECOND;
\r
146 alternateVal=(float)millis;
\r
147 floatVal=(float)intSeconds;
\r
152 p = Period.at(floatVal, outFields[i]);
\r
154 p = p.and(floatVal, outFields[i]);
\r
157 if(alternateUnit != null) {
\r
158 p = p.and(alternateVal, alternateUnit); // add in MILLISECONDs
\r
164 // no fields set = 0 seconds
\r
165 return formatDurationFromNow(0);
\r
167 if(inPast) {// was negated, above.
\r
175 return pformatter.format(p);
\r