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