17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert****************************************************************************** 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Copyright (C) 2007-2014, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert****************************************************************************** 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.impl.duration; 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TimeZone; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Core implementation class for DurationFormatter. 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass BasicDurationFormatter implements DurationFormatter { 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private PeriodFormatter formatter; 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private PeriodBuilder builder; 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private DateFormatter fallback; 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private long fallbackLimit; 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String localeName; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private TimeZone timeZone; 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Creates a basic duration formatter with the given formatter, 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * builder, and fallback. It's up to the caller to ensure that 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the locales and timezones of these are in sync. 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public BasicDurationFormatter(PeriodFormatter formatter, 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodBuilder builder, 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DateFormatter fallback, 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long fallbackLimit) { 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.formatter = formatter; 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.builder = builder; 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.fallback = fallback; 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.fallbackLimit = fallbackLimit < 0 ? 0 : fallbackLimit; 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected BasicDurationFormatter(PeriodFormatter formatter, 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodBuilder builder, 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DateFormatter fallback, 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long fallbackLimit, 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String localeName, 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone timeZone) { 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.formatter = formatter; 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.builder = builder; 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.fallback = fallback; 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.fallbackLimit = fallbackLimit; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.localeName = localeName; 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.timeZone = timeZone; 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String formatDurationFromNowTo(Date targetDate) { 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long now = System.currentTimeMillis(); 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long duration = targetDate.getTime() - now; 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return formatDurationFrom(duration, now); 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String formatDurationFromNow(long duration) { 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return formatDurationFrom(duration, System.currentTimeMillis()); 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String formatDurationFrom(long duration, long referenceDate) { 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String s = doFallback(duration, referenceDate); 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s == null) { 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Period p = doBuild(duration, referenceDate); 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert s = doFormat(p); 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return s; 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public DurationFormatter withLocale(String locName) { 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!locName.equals(localeName)) { 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodFormatter newFormatter = formatter.withLocale(locName); 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodBuilder newBuilder = builder.withLocale(locName); 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DateFormatter newFallback = fallback == null 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ? null 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : fallback.withLocale(locName); 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new BasicDurationFormatter(newFormatter, newBuilder, 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newFallback, fallbackLimit, 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert locName, timeZone); 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public DurationFormatter withTimeZone(TimeZone tz) { 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!tz.equals(timeZone)) { 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodBuilder newBuilder = builder.withTimeZone(tz); 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DateFormatter newFallback = fallback == null 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ? null 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : fallback.withTimeZone(tz); 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new BasicDurationFormatter(formatter, newBuilder, 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newFallback, fallbackLimit, 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localeName, tz); 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String doFallback(long duration, long referenceDate) { 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (fallback != null 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && fallbackLimit > 0 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && Math.abs(duration) >= fallbackLimit) { 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return fallback.format(referenceDate + duration); 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Period doBuild(long duration, long referenceDate) { 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return builder.createWithReferenceDate(duration, referenceDate); 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String doFormat(Period period) { 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!period.isSet()) { 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("period is not set"); 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return formatter.format(period); 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 119