| // © 2016 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| /* |
| ******************************************************************************* |
| * Copyright (C) 2007-2013, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| package com.ibm.icu.impl.duration; |
| |
| import java.text.FieldPosition; |
| import java.util.Date; |
| |
| import com.ibm.icu.text.DurationFormat; |
| import com.ibm.icu.util.ULocale; |
| |
| /** |
| * @author srl |
| */ |
| public class BasicDurationFormat extends DurationFormat { |
| |
| /** |
| * |
| */ |
| private static final long serialVersionUID = -3146984141909457700L; |
| |
| transient DurationFormatter formatter; |
| transient PeriodFormatter pformatter; |
| transient PeriodFormatterService pfs = null; |
| |
| public static BasicDurationFormat getInstance(ULocale locale) { |
| return new BasicDurationFormat(locale); |
| } |
| |
| public StringBuffer format(Object object, StringBuffer toAppend, FieldPosition pos) { |
| if(object instanceof Long) { |
| String res = formatDurationFromNow(((Long)object).longValue()); |
| return toAppend.append(res); |
| } else if(object instanceof Date) { |
| String res = formatDurationFromNowTo(((Date)object)); |
| return toAppend.append(res); |
| } else if (object instanceof javax.xml.datatype.Duration) { |
| String res = formatDuration(object); |
| return toAppend.append(res); |
| } |
| throw new IllegalArgumentException("Cannot format given Object as a Duration"); |
| |
| } |
| |
| public BasicDurationFormat() { |
| pfs = BasicPeriodFormatterService.getInstance(); |
| formatter = pfs.newDurationFormatterFactory().getFormatter(); |
| pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).getFormatter(); |
| } |
| /** |
| * |
| */ |
| public BasicDurationFormat(ULocale locale) { |
| super(locale); |
| pfs = BasicPeriodFormatterService.getInstance(); |
| formatter = pfs.newDurationFormatterFactory().setLocale(locale.getName()).getFormatter(); |
| pformatter = pfs.newPeriodFormatterFactory().setDisplayPastFuture(false).setLocale(locale.getName()).getFormatter(); |
| } |
| |
| /* (non-Javadoc) |
| * @see com.ibm.icu.text.DurationFormat#formatDurationFrom(long, long) |
| */ |
| public String formatDurationFrom(long duration, long referenceDate) { |
| return formatter.formatDurationFrom(duration, referenceDate); |
| } |
| |
| /* (non-Javadoc) |
| * @see com.ibm.icu.text.DurationFormat#formatDurationFromNow(long) |
| */ |
| public String formatDurationFromNow(long duration) { |
| return formatter.formatDurationFromNow(duration); |
| } |
| |
| /* (non-Javadoc) |
| * @see com.ibm.icu.text.DurationFormat#formatDurationFromNowTo(java.util.Date) |
| */ |
| public String formatDurationFromNowTo(Date targetDate) { |
| return formatter.formatDurationFromNowTo(targetDate); |
| } |
| |
| /** |
| * JDK 1.5+ only |
| * @param obj Object being passed. |
| * @return The PeriodFormatter object formatted to the object passed. |
| * @see "http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/datatype/Duration.html" |
| */ |
| public String formatDuration(Object obj) { |
| javax.xml.datatype.DatatypeConstants.Field inFields[] = { |
| javax.xml.datatype.DatatypeConstants.YEARS, |
| javax.xml.datatype.DatatypeConstants.MONTHS, |
| javax.xml.datatype.DatatypeConstants.DAYS, |
| javax.xml.datatype.DatatypeConstants.HOURS, |
| javax.xml.datatype.DatatypeConstants.MINUTES, |
| javax.xml.datatype.DatatypeConstants.SECONDS, |
| }; |
| TimeUnit outFields[] = { |
| TimeUnit.YEAR, |
| TimeUnit.MONTH, |
| TimeUnit.DAY, |
| TimeUnit.HOUR, |
| TimeUnit.MINUTE, |
| TimeUnit.SECOND, |
| }; |
| |
| javax.xml.datatype.Duration inDuration = (javax.xml.datatype.Duration)obj; |
| Period p = null; |
| javax.xml.datatype.Duration duration = inDuration; |
| boolean inPast = false; |
| if(inDuration.getSign()<0) { |
| duration = inDuration.negate(); |
| inPast = true; |
| } |
| // convert a Duration to a Period |
| boolean sawNonZero = false; // did we have a set, non-zero field? |
| for(int i=0;i<inFields.length;i++) { |
| if(duration.isSet(inFields[i])) { |
| Number n = duration.getField(inFields[i]); |
| if(n.intValue() == 0 && !sawNonZero) { |
| continue; // ignore zero fields larger than the largest nonzero field |
| } else { |
| sawNonZero = true; |
| } |
| float floatVal = n.floatValue(); |
| // is there a 'secondary' unit to set? |
| TimeUnit alternateUnit = null; |
| float alternateVal = 0; |
| |
| // see if there is a fractional part |
| if(outFields[i]==TimeUnit.SECOND) { |
| double fullSeconds = floatVal; |
| double intSeconds = Math.floor(floatVal); |
| double millis = (fullSeconds-intSeconds)*1000.0; |
| if(millis > 0.0) { |
| alternateUnit = TimeUnit.MILLISECOND; |
| alternateVal=(float)millis; |
| floatVal=(float)intSeconds; |
| } |
| } |
| |
| if(p == null) { |
| p = Period.at(floatVal, outFields[i]); |
| } else { |
| p = p.and(floatVal, outFields[i]); |
| } |
| |
| if(alternateUnit != null) { |
| p = p.and(alternateVal, alternateUnit); // add in MILLISECONDs |
| } |
| } |
| } |
| |
| if(p == null) { |
| // no fields set = 0 seconds |
| return formatDurationFromNow(0); |
| } else { |
| if(inPast) {// was negated, above. |
| p = p.inPast(); |
| } else { |
| p = p.inFuture(); |
| } |
| } |
| |
| // now, format it. |
| return pformatter.format(p); |
| } |
| } |