• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  *******************************************************************************
5  * Copyright (C) 2004-2008, International Business Machines Corporation and    *
6  * others. All Rights Reserved.                                                *
7  *******************************************************************************
8  *
9  */
10 
11 package com.ibm.icu.dev.tool.timescale;
12 
13 import java.util.Date;
14 import java.util.Locale;
15 
16 import com.ibm.icu.text.MessageFormat;
17 import com.ibm.icu.util.Calendar;
18 import com.ibm.icu.util.GregorianCalendar;
19 import com.ibm.icu.util.SimpleTimeZone;
20 import com.ibm.icu.util.TimeZone;
21 
22 /**
23  * This tool calculates the numeric values of the epoch offsets
24  * used in UniversalTimeScale.
25  *
26  * @see com.ibm.icu.util.UniversalTimeScale
27  */
28 public class EpochOffsets
29 {
30 
31     /**
32      * The default constructor.
33      */
EpochOffsets()34     public EpochOffsets()
35     {
36     }
37 
38     private static final long ticks        = 1;
39     private static final long microseconds = ticks * 10;
40     private static final long milliseconds = microseconds * 1000;
41     private static final long seconds      = milliseconds * 1000;
42     private static final long minutes      = seconds * 60;
43     private static final long hours        = minutes * 60;
44     private static final long days         = hours * 24;
45     // Java measures time in milliseconds, not in 100ns ticks.
46     private static final long javaDays     = days / milliseconds;
47 
48     private static int[][] epochDates = {
49             {   1, Calendar.JANUARY,   1},
50             {1970, Calendar.JANUARY,   1},
51             {1601, Calendar.JANUARY,   1},
52             {1904, Calendar.JANUARY,   1},
53             {2001, Calendar.JANUARY,   1},
54             {1899, Calendar.DECEMBER, 31},
55             {1900, Calendar.MARCH,     1}
56     };
57 
58     /**
59      * The <code>main()</code> method calculates the epoch offsets used by the
60      * <code>UniversalTimeScale</code> class.
61      *
62      * The calculations are done using an ICU <code>Calendar</code> object. The first step is
63      * to calculate the Universal Time Scale's epoch date. Then the epoch offsets are calculated
64      * by calculating each epoch date, subtracting the universal epoch date from it, and converting
65      * that value to ticks.
66      *
67      * @param args - the command line arguments.
68      */
main(String[] args)69     public static void main(String[] args)
70     {
71         TimeZone utc = new SimpleTimeZone(0, "UTC");
72 
73         // Jitterbug 5211: .Net System.DateTime uses the proleptic calendar,
74         // while ICU by default uses the Julian calendar before 1582.
75         // Original code: Calendar cal = Calendar.getInstance(utc, Locale.ENGLISH);
76         // Use a proleptic Gregorian calendar for 0001AD and later by setting
77         // the Gregorian change date before 0001AD with a value
78         // that is safely before that date by any measure, i.e.,
79         // more than 719164 days before 1970.
80         long before0001AD = -1000000 * javaDays;
81         GregorianCalendar cal = new GregorianCalendar(utc, Locale.ENGLISH);
82         cal.setGregorianChange(new Date(before0001AD));
83 
84         MessageFormat fmt = new MessageFormat("{0, date, full} {0, time, full} = {1}");
85         Object arguments[] = {cal, null};
86 
87         System.out.println("Epoch offsets:");
88 
89         // January 1, 0001 00:00:00 is the universal epoch date...
90         cal.set(1, Calendar.JANUARY, 1, 0, 0, 0);
91 
92         long universalEpoch = cal.getTimeInMillis();
93 
94         for (int i = 0; i < epochDates.length; i += 1) {
95             int[] date = epochDates[i];
96 
97             cal.set(date[0], date[1], date[2]);
98 
99             long millis = cal.getTimeInMillis();
100 
101             arguments[1] = Long.toString((millis - universalEpoch) * milliseconds);
102 
103             System.out.println(fmt.format(arguments));
104          }
105     }
106 }
107