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