17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert****************************************************************************** 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Copyright (C) 2007-2011, 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.TimeZone; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.duration.impl.DataRecord; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.duration.impl.PeriodFormatterData; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.duration.impl.PeriodFormatterDataService; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Default implementation of PeriodBuilderFactory. This creates builders that 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * use approximate durations. 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass BasicPeriodBuilderFactory implements PeriodBuilderFactory { 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private PeriodFormatterDataService ds; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Settings settings; 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final short allBits = 0xff; 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BasicPeriodBuilderFactory(PeriodFormatterDataService ds) { 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.ds = ds; 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.settings = new Settings(); 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static long approximateDurationOf(TimeUnit unit) { 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return TimeUnit.approxDurations[unit.ordinal]; 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert class Settings { 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inUse; 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert short uset = allBits; 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit maxUnit = TimeUnit.YEAR; 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit minUnit = TimeUnit.MILLISECOND; 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int maxLimit; 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int minLimit; 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean allowZero = true; 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean weeksAloneOnly; 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean allowMillis = true; 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setUnits(int uset) { 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this.uset == uset) { 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.uset = (short)uset; 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ((uset & allBits) == allBits) { 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.uset = allBits; 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.maxUnit = TimeUnit.YEAR; 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minUnit = TimeUnit.MILLISECOND; 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int lastUnit = -1; 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < TimeUnit.units.length; ++i) { 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (0 != (uset & (1 << i))) { 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (lastUnit == -1) { 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.maxUnit = TimeUnit.units[i]; 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert lastUnit = i; 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (lastUnit == -1) { 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // currently empty, but this might be transient so no fail 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minUnit = result.maxUnit = null; 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minUnit = TimeUnit.units[lastUnit]; 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert short effectiveSet() { 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (allowMillis) { 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return uset; 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (short)(uset & ~(1 << TimeUnit.MILLISECOND.ordinal)); 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit effectiveMinUnit() { 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (allowMillis || minUnit != TimeUnit.MILLISECOND) { 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return minUnit; 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -1 to skip millisecond 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = TimeUnit.units.length - 1; --i >= 0;) { 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (0 != (uset & (1 << i))) { 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return TimeUnit.units[i]; 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return TimeUnit.SECOND; // default for pathological case 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setMaxLimit(float maxLimit) { 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int val = maxLimit <= 0 ? 0 : (int)(maxLimit*1000); 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maxLimit == val) { 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.maxLimit = val; 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setMinLimit(float minLimit) { 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int val = minLimit <= 0 ? 0 : (int)(minLimit*1000); 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (minLimit == val) { 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minLimit = val; 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setAllowZero(boolean allow) { 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this.allowZero == allow) { 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.allowZero = allow; 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setWeeksAloneOnly(boolean weeksAlone) { 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this.weeksAloneOnly == weeksAlone) { 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.weeksAloneOnly = weeksAlone; 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setAllowMilliseconds(boolean allowMillis) { 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this.allowMillis == allowMillis) { 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = inUse ? copy() : this; 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.allowMillis = allowMillis; 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setLocale(String localeName) { 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PeriodFormatterData data = ds.get(localeName); 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .setAllowZero(data.allowZero()) 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .setWeeksAloneOnly(data.weeksAloneOnly()) 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .setAllowMilliseconds(data.useMilliseconds() != DataRecord.EMilliSupport.NO); 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings setInUse() { 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert inUse = true; 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Period createLimited(long duration, boolean inPast) { 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maxLimit > 0) { 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long maxUnitDuration = approximateDurationOf(maxUnit); 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (duration * 1000 > maxLimit * maxUnitDuration) { 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Period.moreThan(maxLimit/1000f, maxUnit).inPast(inPast); 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (minLimit > 0) { 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit emu = effectiveMinUnit(); 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long emud = approximateDurationOf(emu); 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long eml = (emu == minUnit) ? minLimit : 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Math.max(1000, (approximateDurationOf(minUnit) * minLimit) / emud); 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (duration * 1000 < eml * emud) { 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Period.lessThan(eml/1000f, emu).inPast(inPast); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Settings copy() { 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Settings result = new Settings(); 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.inUse = inUse; 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.uset = uset; 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.maxUnit = maxUnit; 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minUnit = minUnit; 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.maxLimit = maxLimit; 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.minLimit = minLimit; 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.allowZero = allowZero; 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.weeksAloneOnly = weeksAloneOnly; 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.allowMillis = allowMillis; 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setAvailableUnitRange(TimeUnit minUnit, 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit maxUnit) { 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int uset = 0; 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = maxUnit.ordinal; i <= minUnit.ordinal; ++i) { 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert uset |= 1 << i; 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (uset == 0) { 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("range " + minUnit + " to " + maxUnit + " is empty"); 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setUnits(uset); 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setUnitIsAvailable(TimeUnit unit, 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean available) { 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int uset = settings.uset; 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (available) { 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert uset |= 1 << unit.ordinal; 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert uset &= ~(1 << unit.ordinal); 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setUnits(uset); 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setMaxLimit(float maxLimit) { 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setMaxLimit(maxLimit); 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setMinLimit(float minLimit) { 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setMinLimit(minLimit); 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setAllowZero(boolean allow) { 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setAllowZero(allow); 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setWeeksAloneOnly(boolean aloneOnly) { 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setWeeksAloneOnly(aloneOnly); 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setAllowMilliseconds(boolean allow) { 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setAllowMilliseconds(allow); 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setLocale(String localeName) { 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = settings.setLocale(localeName); 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilderFactory setTimeZone(TimeZone timeZone) { 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // ignore this 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Settings getSettings() { 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (settings.effectiveSet() == 0) { 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return settings.setInUse(); 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a builder that represents relative time in terms of the single 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given TimeUnit 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param unit the single TimeUnit with which to represent times 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a builder 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder getFixedUnitBuilder(TimeUnit unit) { 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return FixedUnitBuilder.get(unit, getSettings()); 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a builder that represents relative time in terms of the 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * largest period less than or equal to the duration. 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a builder 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder getSingleUnitBuilder() { 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return SingleUnitBuilder.get(getSettings()); 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a builder that formats the largest one or two periods, 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Starting with the largest period less than or equal to the duration. 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * It formats two periods if the first period has a count < 2 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and the next period has a count >= 1. 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a builder 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder getOneOrTwoUnitBuilder() { 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return OneOrTwoUnitBuilder.get(getSettings()); 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a builder that formats the given number of periods, 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * starting with the largest period less than or equal to the 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * duration. 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a builder 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder getMultiUnitBuilder(int periodCount) { 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return MultiUnitBuilder.get(periodCount, getSettings()); 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertabstract class PeriodBuilderImpl implements PeriodBuilder { 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected BasicPeriodBuilderFactory.Settings settings; 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Period create(long duration) { 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return createWithReferenceDate(duration, System.currentTimeMillis()); 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public long approximateDurationOf(TimeUnit unit) { 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return BasicPeriodBuilderFactory.approximateDurationOf(unit); 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Period createWithReferenceDate(long duration, long referenceDate) { 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast = duration < 0; 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inPast) { 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert duration = -duration; 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Period ts = settings.createLimited(duration, inPast); 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ts == null) { 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ts = handleCreate(duration, referenceDate, inPast); 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ts == null) { 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ts = Period.lessThan(1, settings.effectiveMinUnit()).inPast(inPast); 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ts; 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder withTimeZone(TimeZone timeZone) { 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // ignore the time zone 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PeriodBuilder withLocale(String localeName) { 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BasicPeriodBuilderFactory.Settings newSettings = settings.setLocale(localeName); 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (newSettings != settings) { 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return withSettings(newSettings); 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected abstract PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse); 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected abstract Period handleCreate(long duration, long referenceDate, 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast); 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected PeriodBuilderImpl(BasicPeriodBuilderFactory.Settings settings) { 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.settings = settings; 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass FixedUnitBuilder extends PeriodBuilderImpl { 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private TimeUnit unit; 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static FixedUnitBuilder get(TimeUnit unit, BasicPeriodBuilderFactory.Settings settingsToUse) { 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (settingsToUse != null && (settingsToUse.effectiveSet() & (1 << unit.ordinal)) != 0) { 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new FixedUnitBuilder(unit, settingsToUse); 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert FixedUnitBuilder(TimeUnit unit, BasicPeriodBuilderFactory.Settings settings) { 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(settings); 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.unit = unit; 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) { 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return get(unit, settingsToUse); 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Period handleCreate(long duration, long referenceDate, 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast) { 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (unit == null) { 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long unitDuration = approximateDurationOf(unit); 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Period.at((float)((double)duration/unitDuration), unit) 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .inPast(inPast); 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass SingleUnitBuilder extends PeriodBuilderImpl { 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SingleUnitBuilder(BasicPeriodBuilderFactory.Settings settings) { 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(settings); 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static SingleUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) { 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (settings == null) { 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new SingleUnitBuilder(settings); 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) { 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return SingleUnitBuilder.get(settingsToUse); 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Period handleCreate(long duration, long referenceDate, 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast) { 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert short uset = settings.effectiveSet(); 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < TimeUnit.units.length; ++i) { 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (0 != (uset & (1 << i))) { 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit unit = TimeUnit.units[i]; 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long unitDuration = approximateDurationOf(unit); 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (duration >= unitDuration) { 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Period.at((float)((double)duration/unitDuration), unit) 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .inPast(inPast); 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass OneOrTwoUnitBuilder extends PeriodBuilderImpl { 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert OneOrTwoUnitBuilder(BasicPeriodBuilderFactory.Settings settings) { 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(settings); 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static OneOrTwoUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) { 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (settings == null) { 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new OneOrTwoUnitBuilder(settings); 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) { 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return OneOrTwoUnitBuilder.get(settingsToUse); 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Period handleCreate(long duration, long referenceDate, 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast) { 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Period period = null; 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert short uset = settings.effectiveSet(); 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < TimeUnit.units.length; ++i) { 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (0 != (uset & (1 << i))) { 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit unit = TimeUnit.units[i]; 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long unitDuration = approximateDurationOf(unit); 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (duration >= unitDuration || period != null) { 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double count = (double)duration/unitDuration; 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (period == null) { 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (count >= 2) { 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert period = Period.at((float)count, unit); 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert period = Period.at(1, unit).inPast(inPast); 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert duration -= unitDuration; 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (count >= 1) { 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert period = period.and((float)count, unit); 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return period; 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertclass MultiUnitBuilder extends PeriodBuilderImpl { 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int nPeriods; 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert MultiUnitBuilder(int nPeriods, BasicPeriodBuilderFactory.Settings settings) { 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(settings); 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.nPeriods = nPeriods; 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static MultiUnitBuilder get(int nPeriods, BasicPeriodBuilderFactory.Settings settings) { 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (nPeriods > 0 && settings != null) { 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new MultiUnitBuilder(nPeriods, settings); 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) { 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return MultiUnitBuilder.get(nPeriods, settingsToUse); 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Period handleCreate(long duration, long referenceDate, 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean inPast) { 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Period period = null; 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int n = 0; 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert short uset = settings.effectiveSet(); 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < TimeUnit.units.length; ++i) { 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (0 != (uset & (1 << i))) { 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeUnit unit = TimeUnit.units[i]; 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (n == nPeriods) { 4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long unitDuration = approximateDurationOf(unit); 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (duration >= unitDuration || n > 0) { 4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++n; 4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double count = (double)duration / unitDuration; 4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (n < nPeriods) { 5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = Math.floor(count); 5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert duration -= (long)(count * unitDuration); 5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (period == null) { 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert period = Period.at((float)count, unit).inPast(inPast); 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert period = period.and((float)count, unit); 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return period; 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 515