2 *******************************************************************************
\r
3 * Copyright (C) 2004-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
9 package com.ibm.icu.dev.test.timescale;
\r
11 import java.util.Date;
\r
12 import java.util.Locale;
\r
14 import com.ibm.icu.dev.test.TestFmwk;
\r
15 import com.ibm.icu.util.GregorianCalendar;
\r
16 import com.ibm.icu.util.SimpleTimeZone;
\r
17 import com.ibm.icu.util.TimeZone;
\r
18 import com.ibm.icu.util.UniversalTimeScale;
\r
23 * TODO To change the template for this generated type comment go to
\r
24 * Window - Preferences - Java - Code Style - Code Templates
\r
26 public class TimeScaleDataTest extends TestFmwk
\r
30 * Default contstructor.
\r
32 public TimeScaleDataTest()
\r
36 private void roundTripTest(long value, int scale)
\r
38 long rt = UniversalTimeScale.toLong(UniversalTimeScale.from(value, scale), scale);
\r
41 errln("Round-trip error: time scale = " + scale + ", value = " + value + ", round-trip = " + rt);
\r
45 private void toLimitTest(long toLimit, long fromLimit, int scale)
\r
47 long result = UniversalTimeScale.toLong(toLimit, scale);
\r
49 if (result != fromLimit) {
\r
50 errln("toLimit failure: scale = " + scale + ", toLimit = " + toLimit +
\r
51 ", toLong(toLimit, scale) = " + result + ", fromLimit = " + fromLimit);
\r
55 private void epochOffsetTest(long epochOffset, long units, int scale)
\r
57 long universalEpoch = epochOffset * units;
\r
58 long local = UniversalTimeScale.toLong(universalEpoch, scale);
\r
61 errln("toLong(epochOffset, scale): scale = " + scale + ", epochOffset = " + universalEpoch +
\r
62 ", result = " + local);
\r
65 local = UniversalTimeScale.toLong(0, scale);
\r
67 if (local != -epochOffset) {
\r
68 errln("toLong(0, scale): scale = " + scale + ", result = " + local);
\r
71 long universal = UniversalTimeScale.from(-epochOffset, scale);
\r
73 if (universal != 0) {
\r
74 errln("from(-epochOffest, scale): scale = " + scale + ", epochOffset = " + epochOffset +
\r
75 ", result = " + universal);
\r
78 universal = UniversalTimeScale.from(0, scale);
\r
80 if (universal != universalEpoch) {
\r
81 errln("from(0, scale): scale = " + scale + ", result = " + universal);
\r
85 public void TestEpochOffsets()
\r
87 for (int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) {
\r
88 long units = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.UNITS_VALUE);
\r
89 long epochOffset = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.EPOCH_OFFSET_VALUE);
\r
91 epochOffsetTest(epochOffset, units, scale);
\r
95 public void TestFromLimits()
\r
97 for (int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) {
\r
98 long fromMin = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.FROM_MIN_VALUE);
\r
99 long fromMax = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.FROM_MAX_VALUE);
\r
101 roundTripTest(fromMin, scale);
\r
102 roundTripTest(fromMax, scale);
\r
106 public void TestToLimits()
\r
108 for (int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) {
\r
109 long fromMin = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.FROM_MIN_VALUE);
\r
110 long fromMax = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.FROM_MAX_VALUE);
\r
111 long toMin = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.TO_MIN_VALUE);
\r
112 long toMax = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.TO_MAX_VALUE);
\r
114 toLimitTest(toMin, fromMin, scale);
\r
115 toLimitTest(toMax, fromMax, scale);
\r
119 // Test with data from .Net System.DateTime ---------------------------- ***
\r
122 * This data was generated by C++.Net code like
\r
123 * Console::WriteLine(L" {{ {0}, 1, 1, INT64_C({1}) }},", year, DateTime(year, 1, 1).Ticks);
\r
124 * with the DateTime constructor taking int values for year, month, and date.
\r
126 static private final long dotNetDateTimeTicks[] = {
\r
127 /* year, month, day, ticks */
\r
128 100, 1, 1, 31241376000000000L,
\r
129 100, 3, 1, 31292352000000000L,
\r
130 200, 1, 1, 62798112000000000L,
\r
131 200, 3, 1, 62849088000000000L,
\r
132 300, 1, 1, 94354848000000000L,
\r
133 300, 3, 1, 94405824000000000L,
\r
134 400, 1, 1, 125911584000000000L,
\r
135 400, 3, 1, 125963424000000000L,
\r
136 500, 1, 1, 157469184000000000L,
\r
137 500, 3, 1, 157520160000000000L,
\r
138 600, 1, 1, 189025920000000000L,
\r
139 600, 3, 1, 189076896000000000L,
\r
140 700, 1, 1, 220582656000000000L,
\r
141 700, 3, 1, 220633632000000000L,
\r
142 800, 1, 1, 252139392000000000L,
\r
143 800, 3, 1, 252191232000000000L,
\r
144 900, 1, 1, 283696992000000000L,
\r
145 900, 3, 1, 283747968000000000L,
\r
146 1000, 1, 1, 315253728000000000L,
\r
147 1000, 3, 1, 315304704000000000L,
\r
148 1100, 1, 1, 346810464000000000L,
\r
149 1100, 3, 1, 346861440000000000L,
\r
150 1200, 1, 1, 378367200000000000L,
\r
151 1200, 3, 1, 378419040000000000L,
\r
152 1300, 1, 1, 409924800000000000L,
\r
153 1300, 3, 1, 409975776000000000L,
\r
154 1400, 1, 1, 441481536000000000L,
\r
155 1400, 3, 1, 441532512000000000L,
\r
156 1500, 1, 1, 473038272000000000L,
\r
157 1500, 3, 1, 473089248000000000L,
\r
158 1600, 1, 1, 504595008000000000L,
\r
159 1600, 3, 1, 504646848000000000L,
\r
160 1700, 1, 1, 536152608000000000L,
\r
161 1700, 3, 1, 536203584000000000L,
\r
162 1800, 1, 1, 567709344000000000L,
\r
163 1800, 3, 1, 567760320000000000L,
\r
164 1900, 1, 1, 599266080000000000L,
\r
165 1900, 3, 1, 599317056000000000L,
\r
166 2000, 1, 1, 630822816000000000L,
\r
167 2000, 3, 1, 630874656000000000L,
\r
168 2100, 1, 1, 662380416000000000L,
\r
169 2100, 3, 1, 662431392000000000L,
\r
170 2200, 1, 1, 693937152000000000L,
\r
171 2200, 3, 1, 693988128000000000L,
\r
172 2300, 1, 1, 725493888000000000L,
\r
173 2300, 3, 1, 725544864000000000L,
\r
174 2400, 1, 1, 757050624000000000L,
\r
175 2400, 3, 1, 757102464000000000L,
\r
176 2500, 1, 1, 788608224000000000L,
\r
177 2500, 3, 1, 788659200000000000L,
\r
178 2600, 1, 1, 820164960000000000L,
\r
179 2600, 3, 1, 820215936000000000L,
\r
180 2700, 1, 1, 851721696000000000L,
\r
181 2700, 3, 1, 851772672000000000L,
\r
182 2800, 1, 1, 883278432000000000L,
\r
183 2800, 3, 1, 883330272000000000L,
\r
184 2900, 1, 1, 914836032000000000L,
\r
185 2900, 3, 1, 914887008000000000L,
\r
186 3000, 1, 1, 946392768000000000L,
\r
187 3000, 3, 1, 946443744000000000L,
\r
189 1601, 1, 1, 504911232000000000L,
\r
190 1899, 12, 31, 599265216000000000L,
\r
191 1904, 1, 1, 600527520000000000L,
\r
192 1970, 1, 1, 621355968000000000L,
\r
193 2001, 1, 1, 631139040000000000L,
\r
194 9900, 3, 1, 3123873216000000000L,
\r
195 9999, 12, 31, 3155378112000000000L
\r
199 * ICU's Universal Time Scale is designed to be tick-for-tick compatible with
\r
200 * .Net System.DateTime. Verify that this is so for the
\r
201 * .Net-supported date range (years 1-9999 AD).
\r
202 * This requires a proleptic Gregorian calendar because that's what .Net uses.
\r
203 * Proleptic: No Julian/Gregorian switchover, or a switchover before
\r
204 * any date that we test, that is, before 0001 AD.
\r
206 public void TestDotNet() {
\r
208 final long dayMillis = 86400 * 1000L; /* 1 day = 86400 seconds */
\r
209 final long dayTicks = 86400 * 10000000L;
\r
210 final int kYear = 0; // offset for dotNetDateTimeTicks[] field
\r
211 final int kMonth = 1;
\r
212 final int kDay = 2;
\r
213 final int kTicks = 3;
\r
214 final int kIncrement = 4;
\r
215 GregorianCalendar cal;
\r
217 long ticks, millis;
\r
220 /* Open a proleptic Gregorian calendar. */
\r
221 long before0001AD = -1000000 * dayMillis;
\r
222 utc = new SimpleTimeZone(0, "UTC");
\r
223 cal = new GregorianCalendar(utc, Locale.ENGLISH);
\r
224 cal.setGregorianChange(new Date(before0001AD));
\r
225 for(i = 0; i < dotNetDateTimeTicks.length; i += kIncrement) {
\r
226 /* Test conversion from .Net/Universal time to ICU time. */
\r
227 millis = UniversalTimeScale.toLong(dotNetDateTimeTicks[i + kTicks], UniversalTimeScale.ICU4C_TIME);
\r
229 cal.set((int)dotNetDateTimeTicks[i + kYear],
\r
230 (int)dotNetDateTimeTicks[i + kMonth] - 1, /* Java & ICU use January = month 0. */
\r
231 (int)dotNetDateTimeTicks[i + kDay]);
\r
232 icuDate = cal.getTimeInMillis();
\r
233 if(millis != icuDate) {
\r
234 /* Print days not millis. */
\r
235 errln("UniversalTimeScale.toLong(ticks[" + i + "], ICU4C)=" +
\r
236 (millis/dayMillis) + " != " + (icuDate/dayMillis) +
\r
237 "=ucal_getMillis(" + dotNetDateTimeTicks[i + kYear] +
\r
238 "-" + dotNetDateTimeTicks[i + kMonth] +
\r
239 "-" + dotNetDateTimeTicks[i + kDay] + ")");
\r
242 /* Test conversion from ICU time to .Net/Universal time. */
\r
243 ticks = UniversalTimeScale.from(icuDate, UniversalTimeScale.ICU4C_TIME);
\r
244 if(ticks != dotNetDateTimeTicks[i + kTicks]) {
\r
245 /* Print days not ticks. */
\r
246 errln("UniversalTimeScale.from(date[" + i + "], ICU4C)=" +
\r
247 (ticks/dayTicks) + " != " + dotNetDateTimeTicks[i + kTicks]/dayTicks +
\r
248 "=.Net System.DateTime(" + dotNetDateTimeTicks[i + kYear] +
\r
249 "-" + dotNetDateTimeTicks[i + kMonth] +
\r
250 "-" + dotNetDateTimeTicks[i + kDay] + ").Ticks");
\r
255 public static void main(String[] args)
\r
257 new TimeScaleDataTest().run(args);
\r