1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ****************************************************************************** 5 * Copyright (C) 2007-2014, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ****************************************************************************** 8 */ 9 10 package com.ibm.icu.impl.duration; 11 12 import java.util.Date; 13 import java.util.TimeZone; 14 15 /** 16 * Core implementation class for DurationFormatter. 17 */ 18 class BasicDurationFormatter implements DurationFormatter { 19 private PeriodFormatter formatter; 20 private PeriodBuilder builder; 21 private DateFormatter fallback; 22 private long fallbackLimit; 23 private String localeName; 24 private TimeZone timeZone; 25 26 /** 27 * Creates a basic duration formatter with the given formatter, 28 * builder, and fallback. It's up to the caller to ensure that 29 * the locales and timezones of these are in sync. 30 */ BasicDurationFormatter(PeriodFormatter formatter, PeriodBuilder builder, DateFormatter fallback, long fallbackLimit)31 public BasicDurationFormatter(PeriodFormatter formatter, 32 PeriodBuilder builder, 33 DateFormatter fallback, 34 long fallbackLimit) { 35 this.formatter = formatter; 36 this.builder = builder; 37 this.fallback = fallback; 38 this.fallbackLimit = fallbackLimit < 0 ? 0 : fallbackLimit; 39 } 40 41 protected BasicDurationFormatter(PeriodFormatter formatter, 42 PeriodBuilder builder, 43 DateFormatter fallback, 44 long fallbackLimit, 45 String localeName, 46 TimeZone timeZone) { 47 this.formatter = formatter; 48 this.builder = builder; 49 this.fallback = fallback; 50 this.fallbackLimit = fallbackLimit; 51 this.localeName = localeName; 52 this.timeZone = timeZone; 53 } 54 55 @Override 56 public String formatDurationFromNowTo(Date targetDate) { 57 long now = System.currentTimeMillis(); 58 long duration = targetDate.getTime() - now; 59 return formatDurationFrom(duration, now); 60 } 61 62 @Override 63 public String formatDurationFromNow(long duration) { 64 return formatDurationFrom(duration, System.currentTimeMillis()); 65 } 66 67 @Override 68 public String formatDurationFrom(long duration, long referenceDate) { 69 String s = doFallback(duration, referenceDate); 70 if (s == null) { 71 Period p = doBuild(duration, referenceDate); 72 s = doFormat(p); 73 } 74 return s; 75 } 76 77 @Override 78 public DurationFormatter withLocale(String locName) { 79 if (!locName.equals(localeName)) { 80 PeriodFormatter newFormatter = formatter.withLocale(locName); 81 PeriodBuilder newBuilder = builder.withLocale(locName); 82 DateFormatter newFallback = fallback == null 83 ? null 84 : fallback.withLocale(locName); 85 return new BasicDurationFormatter(newFormatter, newBuilder, 86 newFallback, fallbackLimit, 87 locName, timeZone); 88 } 89 return this; 90 } 91 92 @Override 93 public DurationFormatter withTimeZone(TimeZone tz) { 94 if (!tz.equals(timeZone)) { 95 PeriodBuilder newBuilder = builder.withTimeZone(tz); 96 DateFormatter newFallback = fallback == null 97 ? null 98 : fallback.withTimeZone(tz); 99 return new BasicDurationFormatter(formatter, newBuilder, 100 newFallback, fallbackLimit, 101 localeName, tz); 102 } 103 return this; 104 } 105 106 protected String doFallback(long duration, long referenceDate) { 107 if (fallback != null 108 && fallbackLimit > 0 109 && Math.abs(duration) >= fallbackLimit) { 110 return fallback.format(referenceDate + duration); 111 } 112 return null; 113 } 114 doBuild(long duration, long referenceDate)115 protected Period doBuild(long duration, long referenceDate) { 116 return builder.createWithReferenceDate(duration, referenceDate); 117 } 118 doFormat(Period period)119 protected String doFormat(Period period) { 120 if (!period.isSet()) { 121 throw new IllegalArgumentException("period is not set"); 122 } 123 return formatter.format(period); 124 } 125 } 126