/* ******************************************************************************* * Copyright (C) 1996-2008, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* * */ package com.ibm.icu.dev.tool.timescale; import com.ibm.icu.math.BigDecimal; import com.ibm.icu.text.MessageFormat; import com.ibm.icu.util.UniversalTimeScale; /** * This class calculates the minimum and maximum values which can be * used as arguments to toLong and from. * * NOTE: If you change the way in which these values are calculated, it * may be necessary to disable to toRangeCheck() and * fromRangeCheck() methods in the UniversalTimeScale * for all of the calculations to run without throwing an error. * * @see com.ibm.icu.util.UniversalTimeScale */ public class CalculateLimits { /** * The default constructor. */ public CalculateLimits() { } /** * This method first calculates the from limits by * passing Long.MIN_VALUE and Long.MAX_VALUE to * the (internal) toBigDecimalTrunc() method. Any values outside * of the range of a long are pinned. * * The mimimum and maximum values for toLong are calulated by passing * the min and max values calculated above to BigDecimalFrom(). Because * this method will round, the returned values are adjusted to take this into account. * * @see com.ibm.icu.util.UniversalTimeScale * * @param args - the command line arugments */ public static void main(String[] args) { MessageFormat fmt = new MessageFormat("{0}L, {1}L, {2}L, {3}L"); BigDecimal universalMin = new BigDecimal(Long.MIN_VALUE); BigDecimal universalMax = new BigDecimal(Long.MAX_VALUE); Object limitArgs[] = {null, null, null, null}; System.out.println("\nTo, From limits:"); // from limits for(int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) { BigDecimal min = UniversalTimeScale.toBigDecimalTrunc(universalMin, scale).max(universalMin); BigDecimal max = UniversalTimeScale.toBigDecimalTrunc(universalMax, scale).min(universalMax); long minLong = min.longValue(); long maxLong = max.longValue(); limitArgs[2] = min.toString(); limitArgs[3] = max.toString(); // to limits BigDecimal minTrunc = UniversalTimeScale.bigDecimalFrom(min, scale); BigDecimal maxTrunc = UniversalTimeScale.bigDecimalFrom(max, scale); BigDecimal minResidue = minTrunc.subtract(universalMin); BigDecimal maxResidue = universalMax.subtract(maxTrunc); long units = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.UNITS_VALUE); BigDecimal half = new BigDecimal(units == 1? 0: units / 2 - 1); min = minTrunc.subtract(minResidue.min(half)); max = maxTrunc.add(maxResidue.min(half)); limitArgs[0] = min.toString(); limitArgs[1] = max.toString(); System.out.println(fmt.format(limitArgs)); // round-trip test the from limits if(UniversalTimeScale.toLong(UniversalTimeScale.from(minLong, scale), scale) != minLong) { System.out.println("OOPS: min didn't round trip!"); } if(UniversalTimeScale.toLong(UniversalTimeScale.from(maxLong, scale), scale) != maxLong) { System.out.println("OOPS: max didn't round trip!"); } // make sure that the to limits convert to the from limits if(UniversalTimeScale.toLong(min.longValue(), scale) != minLong) { System.out.println("OOPS: toLong(toMin) != fromMin"); } if(UniversalTimeScale.toLong(max.longValue(), scale) != maxLong) { System.out.println("OOPS: toLong(toMax) != fromMax"); } } } }