3 *******************************************************************************
4 * Copyright (C) 2007-2009, International Business Machines Corporation and *
5 * others. All Rights Reserved. *
6 *******************************************************************************
8 package com.ibm.icu.impl.duration;
10 import java.text.FieldPosition;
11 import java.util.Date;
13 import com.ibm.icu.text.DurationFormat;
14 import com.ibm.icu.util.ULocale;
19 public class BasicDurationFormat extends DurationFormat {
24 private static final long serialVersionUID = -3146984141909457700L;
26 transient DurationFormatter formatter;
27 transient PeriodFormatter pformatter;
28 transient PeriodFormatterService pfs = null;
30 public static DurationFormat getInstance(ULocale locale) {
31 return new BasicDurationFormat(locale);
34 //#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14)
36 private static boolean checkXMLDuration = true;
39 public StringBuffer format(Object object, StringBuffer toAppend, FieldPosition pos) {
40 if(object instanceof Long) {
41 String res = formatDurationFromNow(((Long)object).longValue());
42 return toAppend.append(res);
43 } else if(object instanceof Date) {
44 String res = formatDurationFromNowTo(((Date)object));
45 return toAppend.append(res);
47 //#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14)
49 if(checkXMLDuration) try {
50 if(object instanceof javax.xml.datatype.Duration) {
51 String res = formatDuration(object);
52 return toAppend.append(res);
54 } catch ( NoClassDefFoundError ncdfe ) {
55 System.err.println("Skipping XML capability");
56 checkXMLDuration = false; // don't try again
59 throw new IllegalArgumentException("Cannot format given Object as a Duration");
63 public BasicDurationFormat() {
64 pfs = BasicPeriodFormatterService.getInstance();
65 formatter = pfs.newDurationFormatterFactory().getFormatter();
66 pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).getFormatter();
71 public BasicDurationFormat(ULocale locale) {
73 pfs = BasicPeriodFormatterService.getInstance();
74 formatter = pfs.newDurationFormatterFactory().setLocale(locale.getName()).getFormatter();
75 pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).setLocale(locale.getName()).getFormatter();
79 * @see com.ibm.icu.text.DurationFormat#formatDurationFrom(long, long)
81 public String formatDurationFrom(long duration, long referenceDate) {
82 return formatter.formatDurationFrom(duration, referenceDate);
86 * @see com.ibm.icu.text.DurationFormat#formatDurationFromNow(long)
88 public String formatDurationFromNow(long duration) {
89 return formatter.formatDurationFromNow(duration);
93 * @see com.ibm.icu.text.DurationFormat#formatDurationFromNowTo(java.util.Date)
95 public String formatDurationFromNowTo(Date targetDate) {
96 return formatter.formatDurationFromNowTo(targetDate);
99 //#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14)
105 * @see http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/datatype/Duration.html
107 public String formatDuration(Object obj) {
108 javax.xml.datatype.DatatypeConstants.Field inFields[] = {
109 javax.xml.datatype.DatatypeConstants.YEARS,
110 javax.xml.datatype.DatatypeConstants.MONTHS,
111 javax.xml.datatype.DatatypeConstants.DAYS,
112 javax.xml.datatype.DatatypeConstants.HOURS,
113 javax.xml.datatype.DatatypeConstants.MINUTES,
114 javax.xml.datatype.DatatypeConstants.SECONDS,
116 TimeUnit outFields[] = {
125 javax.xml.datatype.Duration inDuration = (javax.xml.datatype.Duration)obj;
127 javax.xml.datatype.Duration duration = inDuration;
128 boolean inPast = false;
129 if(inDuration.getSign()<0) {
130 duration = inDuration.negate();
133 // convert a Duration to a Period
134 boolean sawNonZero = false; // did we have a set, non-zero field?
135 for(int i=0;i<inFields.length;i++) {
136 if(duration.isSet(inFields[i])) {
137 Number n = duration.getField(inFields[i]);
138 if(n.intValue() == 0 && !sawNonZero) {
139 continue; // ignore zero fields larger than the largest nonzero field
143 float floatVal = n.floatValue();
144 // is there a 'secondary' unit to set?
145 TimeUnit alternateUnit = null;
146 float alternateVal = 0;
148 // see if there is a fractional part
149 if(outFields[i]==TimeUnit.SECOND) {
150 double fullSeconds = floatVal;
151 double intSeconds = Math.floor(floatVal);
152 double millis = (fullSeconds-intSeconds)*1000.0;
154 alternateUnit = TimeUnit.MILLISECOND;
155 alternateVal=(float)millis;
156 floatVal=(float)intSeconds;
161 p = Period.at(floatVal, outFields[i]);
163 p = p.and(floatVal, outFields[i]);
166 if(alternateUnit != null) {
167 p = p.and(alternateVal, alternateUnit); // add in MILLISECONDs
173 // no fields set = 0 seconds
174 return formatDurationFromNow(0);
176 if(inPast) {// was negated, above.
184 return pformatter.format(p);