2 *******************************************************************************
\r
3 * Copyright (C) 1996-2008, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
9 package com.ibm.icu.dev.tool.timescale;
\r
11 import com.ibm.icu.math.BigDecimal;
\r
12 import com.ibm.icu.text.MessageFormat;
\r
13 import com.ibm.icu.util.UniversalTimeScale;
\r
16 * This class calculates the minimum and maximum values which can be
\r
17 * used as arguments to <code>toLong</code> and <code>from</code>.
\r
19 * NOTE: If you change the way in which these values are calculated, it
\r
20 * may be necessary to disable to <code>toRangeCheck()</code> and
\r
21 * <code>fromRangeCheck()</code> methods in the <code>UniversalTimeScale</code>
\r
22 * for all of the calculations to run without throwing an error.
\r
24 * @see com.ibm.icu.util.UniversalTimeScale
\r
26 public class CalculateLimits {
\r
29 * The default constructor.
\r
31 public CalculateLimits()
\r
36 * This method first calculates the <code>from</code> limits by
\r
37 * passing <code>Long.MIN_VALUE</code> and <code>Long.MAX_VALUE</code> to
\r
38 * the (internal) <code>toBigDecimalTrunc()</code> method. Any values outside
\r
39 * of the range of a <code>long</code> are pinned.
\r
41 * The mimimum and maximum values for <code>toLong</code> are calulated by passing
\r
42 * the min and max values calculated above to <code>BigDecimalFrom()</code>. Because
\r
43 * this method will round, the returned values are adjusted to take this into account.
\r
45 * @see com.ibm.icu.util.UniversalTimeScale
\r
47 * @param args - the command line arugments
\r
49 public static void main(String[] args)
\r
51 MessageFormat fmt = new MessageFormat("{0}L, {1}L, {2}L, {3}L");
\r
52 BigDecimal universalMin = new BigDecimal(Long.MIN_VALUE);
\r
53 BigDecimal universalMax = new BigDecimal(Long.MAX_VALUE);
\r
54 Object limitArgs[] = {null, null, null, null};
\r
56 System.out.println("\nTo, From limits:");
\r
59 for(int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) {
\r
60 BigDecimal min = UniversalTimeScale.toBigDecimalTrunc(universalMin, scale).max(universalMin);
\r
61 BigDecimal max = UniversalTimeScale.toBigDecimalTrunc(universalMax, scale).min(universalMax);
\r
62 long minLong = min.longValue();
\r
63 long maxLong = max.longValue();
\r
65 limitArgs[2] = min.toString();
\r
66 limitArgs[3] = max.toString();
\r
69 BigDecimal minTrunc = UniversalTimeScale.bigDecimalFrom(min, scale);
\r
70 BigDecimal maxTrunc = UniversalTimeScale.bigDecimalFrom(max, scale);
\r
71 BigDecimal minResidue = minTrunc.subtract(universalMin);
\r
72 BigDecimal maxResidue = universalMax.subtract(maxTrunc);
\r
73 long units = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.UNITS_VALUE);
\r
74 BigDecimal half = new BigDecimal(units == 1? 0: units / 2 - 1);
\r
76 min = minTrunc.subtract(minResidue.min(half));
\r
77 max = maxTrunc.add(maxResidue.min(half));
\r
78 limitArgs[0] = min.toString();
\r
79 limitArgs[1] = max.toString();
\r
81 System.out.println(fmt.format(limitArgs));
\r
83 // round-trip test the from limits
\r
84 if(UniversalTimeScale.toLong(UniversalTimeScale.from(minLong, scale), scale) != minLong) {
\r
85 System.out.println("OOPS: min didn't round trip!");
\r
88 if(UniversalTimeScale.toLong(UniversalTimeScale.from(maxLong, scale), scale) != maxLong) {
\r
89 System.out.println("OOPS: max didn't round trip!");
\r
92 // make sure that the to limits convert to the from limits
\r
93 if(UniversalTimeScale.toLong(min.longValue(), scale) != minLong) {
\r
94 System.out.println("OOPS: toLong(toMin) != fromMin");
\r
97 if(UniversalTimeScale.toLong(max.longValue(), scale) != maxLong) {
\r
98 System.out.println("OOPS: toLong(toMax) != fromMax");
\r