jdk/test/sun/util/calendar/zi/Rule.java
changeset 15658 55b829ca2334
child 17464 268d3ce75045
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/calendar/zi/Rule.java	Tue Feb 12 09:25:43 2013 -0800
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Rule manipulates Rule records.
+ *
+ * @since 1.4
+ */
+class Rule {
+
+    private List<RuleRec> list;
+    private String name;
+
+    /**
+     * Constructs a Rule which consists of a Rule record list. The
+     * specified name is given to this Rule.
+     * @param name the Rule name
+     */
+    Rule(String name) {
+        this.name = name;
+        list = new ArrayList<RuleRec>();
+    }
+
+    /**
+     * Added a RuleRec to the Rule record list.
+     */
+    void add(RuleRec rec) {
+        list.add(rec);
+    }
+
+    /**
+     * @return the Rule name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Gets all rule records that cover the given year.
+     *
+     * @param year the year number for which the rule is applicable.
+     * @return rules in List that are collated in time. If no rule is found, an empty
+     * List is returned.
+     */
+    List<RuleRec> getRules(int year) {
+        List<RuleRec> rules = new ArrayList<RuleRec>(3);
+        for (RuleRec rec : list) {
+            if (year >= rec.getFromYear() && year <= rec.getToYear()) {
+                if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1))
+                    continue;
+                rules.add(rec);
+            }
+        }
+        int n = rules.size();
+        if (n <= 1) {
+            return rules;
+        }
+        if (n == 2) {
+            RuleRec rec1 = rules.get(0);
+            RuleRec rec2 = rules.get(1);
+            if (rec1.getMonthNum() > rec2.getMonthNum()) {
+                rules.set(0, rec2);
+                rules.set(1, rec1);
+            } else if (rec1.getMonthNum() == rec2.getMonthNum()) {
+                // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
+                long t1 = Time.getLocalTime(year, rec1.getMonth(),
+                                            rec1.getDay(), rec1.getTime().getTime());
+                long t2 = Time.getLocalTime(year, rec2.getMonth(),
+                                            rec2.getDay(), rec2.getTime().getTime());
+                if (t1 > t2) {
+                    rules.set(0, rec2);
+                    rules.set(1, rec1);
+                }
+            }
+            return rules;
+        }
+
+        final int y = year;
+        RuleRec[] recs = new RuleRec[rules.size()];
+        rules.toArray(recs);
+        Arrays.sort(recs, new Comparator<RuleRec>() {
+                public int compare(RuleRec r1, RuleRec r2) {
+                    int n = r1.getMonthNum() - r2.getMonthNum();
+                    if (n != 0) {
+                        return n;
+                    }
+                    // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
+                    long t1 = Time.getLocalTime(y, r1.getMonth(),
+                                                r1.getDay(), r1.getTime().getTime());
+                    long t2 = Time.getLocalTime(y, r2.getMonth(),
+                                                r2.getDay(), r2.getTime().getTime());
+                    return (int)(t1 - t2);
+                }
+                public boolean equals(Object o) {
+                    return this == o;
+                }
+            });
+        rules.clear();
+        for (int i = 0; i < n; i++) {
+            rules.add(recs[i]);
+        }
+        return rules;
+    }
+
+    /**
+     * Gets rule records that have either "max" or cover the endYear
+     * value in its DST schedule.
+     *
+     * @return rules that contain last DST schedule. An empty
+     * ArrayList is returned if no last rules are found.
+     */
+    List<RuleRec> getLastRules() {
+        RuleRec start = null;
+        RuleRec end = null;
+
+        for (int i = 0; i < list.size(); i++) {
+            RuleRec rec = list.get(i);
+            if (rec.isLastRule()) {
+                if (rec.getSave() > 0) {
+                    start = rec;
+                } else {
+                    end = rec;
+                }
+            }
+        }
+        if (start == null || end == null) {
+            int endYear = Zoneinfo.getEndYear();
+            for (int i  = 0; i < list.size(); i++) {
+                RuleRec rec = list.get(i);
+                if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) {
+                    if (start == null && rec.getSave() > 0) {
+                        start = rec;
+                    } else {
+                        if (end == null && rec.getSave() == 0) {
+                            end = rec;
+                        }
+                    }
+                }
+            }
+        }
+
+        List<RuleRec> r = new ArrayList<RuleRec>(2);
+        if (start == null || end == null) {
+            if (start != null || end != null) {
+                Main.warning("found last rules for "+name+" inconsistent.");
+            }
+            return r;
+        }
+
+        r.add(start);
+        r.add(end);
+        return r;
+    }
+}