1 package org.unicode.cldr.tool; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.text.ParseException; 6 import java.util.Arrays; 7 import java.util.Collection; 8 import java.util.Comparator; 9 import java.util.Iterator; 10 import java.util.Map; 11 import java.util.Set; 12 import java.util.TreeMap; 13 import java.util.TreeSet; 14 15 import org.unicode.cldr.draft.FileUtilities; 16 import org.unicode.cldr.util.ArrayComparator; 17 import org.unicode.cldr.util.CLDRPaths; 18 import org.unicode.cldr.util.CldrUtility; 19 import org.unicode.cldr.util.Factory; 20 import org.unicode.cldr.util.ICUServiceBuilder; 21 import org.unicode.cldr.util.StandardCodes; 22 import org.unicode.cldr.util.Tabber; 23 import org.unicode.cldr.util.TimezoneFormatter; 24 import org.unicode.cldr.util.ZoneInflections; 25 26 import com.ibm.icu.util.TimeZone; 27 28 public class ShowZoneEquivalences { 29 main(String[] args)30 public static void main(String[] args) throws Exception { 31 double deltaTime = System.currentTimeMillis(); 32 try { 33 ShowZoneEquivalences.getZoneEquivalences(); 34 } finally { 35 deltaTime = System.currentTimeMillis() - deltaTime; 36 System.out.println("Elapsed: " + deltaTime / 1000.0 + " seconds"); 37 System.out.println("Done"); 38 } 39 } 40 getZoneEquivalences()41 public static void getZoneEquivalences() throws IOException, ParseException { 42 // String tzid = "America/Argentina/ComodRivadavia"; 43 // TimeZone tz = TimeZone.getTimeZone(tzid); 44 // int offset = tz.getOffset(new Date().getTime()); 45 // System.out.println(tzid + ":\t" + offset); 46 // System.out.println("in available? " + Arrays.asList(TimeZone.getAvailableIDs()).contains(tzid)); 47 // System.out.println(new TreeSet(Arrays.asList(TimeZone.getAvailableIDs()))); 48 49 Set<String> needsTranslation = new TreeSet<>(Arrays.asList(CountItems.needsTranslationString 50 .split("[,]?\\s+"))); 51 Set<String> singleCountries = new TreeSet<>( 52 Arrays 53 .asList( 54 "Africa/Bamako America/Godthab America/Santiago America/Guayaquil Asia/Shanghai Asia/Tashkent Asia/Kuala_Lumpur Europe/Madrid Europe/Lisbon Europe/London Pacific/Auckland Pacific/Tahiti" 55 .split("\\s"))); 56 Set<String> defaultItems = new TreeSet<>( 57 Arrays 58 .asList( 59 "Antarctica/McMurdo America/Buenos_Aires Australia/Sydney America/Sao_Paulo America/Toronto Africa/Kinshasa America/Santiago Asia/Shanghai America/Guayaquil Europe/Madrid Europe/London America/Godthab Asia/Jakarta Africa/Bamako America/Mexico_City Asia/Kuala_Lumpur Pacific/Auckland Europe/Lisbon Europe/Moscow Europe/Kiev America/New_York Asia/Tashkent Pacific/Tahiti Pacific/Kosrae Pacific/Tarawa Asia/Almaty Pacific/Majuro Asia/Ulaanbaatar Arctic/Longyearbyen Pacific/Midway" 60 .split("\\s"))); 61 62 StandardCodes sc = StandardCodes.make(); 63 Collection<String> codes = sc.getGoodAvailableCodes("tzid"); 64 TreeSet<String> extras = new TreeSet<>(); 65 Map<String, Set<String>> m = sc.getZoneLinkNew_OldSet(); 66 for (String code : codes) { 67 Collection<String> s = m.get(code); 68 if (s == null) 69 continue; 70 extras.addAll(s); 71 } 72 extras.addAll(codes); 73 Set<String> icu4jTZIDs = new TreeSet<>(Arrays.asList(TimeZone.getAvailableIDs())); 74 Set<String> diff2 = new TreeSet<>(icu4jTZIDs); 75 diff2.removeAll(extras); 76 System.out.println("icu4jTZIDs - StandardCodes: " + diff2); 77 diff2 = new TreeSet<>(extras); 78 diff2.removeAll(icu4jTZIDs); 79 System.out.println("StandardCodes - icu4jTZIDs: " + diff2); 80 ArrayComparator ac = new ArrayComparator(new Comparator[] { 81 ArrayComparator.COMPARABLE, ArrayComparator.COMPARABLE, 82 ArrayComparator.COMPARABLE }); 83 Map<String, String> zone_countries = sc.getZoneToCounty(); 84 85 TreeSet<Object[]> country_inflection_names = new TreeSet<Object[]>(ac); 86 PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "inflections.txt"); 87 88 TreeMap<Integer, TreeSet<String>> minOffsetMap = new TreeMap<>(); 89 TreeMap<Integer, TreeSet<String>> maxOffsetMap = new TreeMap<>(); 90 91 for (Iterator<String> it = codes.iterator(); it.hasNext();) { 92 String zoneID = it.next(); 93 String country = zone_countries.get(zoneID); 94 TimeZone zone = TimeZone.getTimeZone(zoneID); 95 ZoneInflections zip = new ZoneInflections(zone); 96 out.println(zoneID + "\t" + zip); 97 country_inflection_names.add(new Object[] { country, zip, zoneID }); 98 99 TreeSet<String> s = minOffsetMap.get(zip.getMinOffset()); 100 if (s == null) 101 minOffsetMap.put(zip.getMinOffset(), s = new TreeSet<>()); 102 s.add(zone.getID()); 103 104 s = maxOffsetMap.get(zip.getMaxOffset()); 105 if (s == null) 106 maxOffsetMap.put(zip.getMaxOffset(), s = new TreeSet<>()); 107 s.add(zone.getID()); 108 109 } 110 System.out.println("Minimum Offset: " + minOffsetMap); 111 System.out.println("Maximum Offset: " + maxOffsetMap); 112 out.close(); 113 114 out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "modernTimezoneEquivalents.html"); 115 out.println("<html>" + "<head>" 116 + "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" 117 + "<title>Modern Equivalent Timezones</title><style>"); 118 out.println("td.top,td.topr { background-color: #EEEEFF }"); 119 out.println("td.r,td.topr { text-align:right }"); 120 out 121 .println("td.gap { font-weight:bold; border-top: 3px solid #0000FF; border-bottom: 3px solid #0000FF; background-color: #CCCCCC }"); 122 out 123 .println("</style>" 124 + "</head>" 125 + "<body>" 126 + "<table border='1' cellspacing='0' cellpadding='2' style='border-collapse: collapse'>"); 127 Tabber.HTMLTabber tabber1 = new Tabber.HTMLTabber(); 128 tabber1.setParameters(4, "class='r'"); 129 tabber1.setParameters(5, "class='r'"); 130 Tabber.HTMLTabber tabber2 = new Tabber.HTMLTabber(); 131 tabber2.setParameters(0, "class='top'"); 132 tabber2.setParameters(1, "class='top'"); 133 tabber2.setParameters(2, "class='top'"); 134 tabber2.setParameters(3, "class='top'"); 135 tabber2.setParameters(4, "class='topr'"); 136 tabber2.setParameters(5, "class='topr'"); 137 Tabber.HTMLTabber tabber3 = new Tabber.HTMLTabber(); 138 tabber3.setParameters(0, "class='gap'"); 139 tabber3.setParameters(1, "class='gap'"); 140 tabber3.setParameters(2, "class='gap'"); 141 tabber3.setParameters(3, "class='gap'"); 142 tabber3.setParameters(4, "class='gap'"); 143 tabber3.setParameters(5, "class='gap'"); 144 145 long minimumDate = ICUServiceBuilder.isoDateParse("2000-1-1T00:00:00Z") 146 .getTime(); 147 out 148 .println("<h1>Modern Equivalent Timezones: <a target='_blank' href='instructions.html'>Instructions</a></h1>"); 149 out.println(ShowData.dateFooter()); 150 out.println("<p>Zones identical after: " 151 + ICUServiceBuilder.isoDateFormat(minimumDate) + "</p>"); 152 String lastCountry = ""; 153 ZoneInflections.OutputLong diff = new ZoneInflections.OutputLong(0); 154 Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*"); 155 TimezoneFormatter tzf = new TimezoneFormatter(cldrFactory, "en", true); 156 Map<String, Set<String>> country_zoneSet = sc.getCountryToZoneSet(); 157 boolean shortList = true; 158 boolean first = true; 159 int category = 1; 160 Tabber tabber = tabber1; 161 for (Iterator<Object[]> it = country_inflection_names.iterator(); it.hasNext();) { 162 Object[] row = it.next(); 163 String country = (String) row[0]; 164 if (country.equals("001")) 165 continue; 166 if (shortList && (country_zoneSet.get(country)).size() < 2) 167 continue; 168 ZoneInflections zip = (ZoneInflections) row[1]; 169 String zoneID = (String) row[2]; 170 171 if (!country.equals(lastCountry)) { 172 if (first) 173 first = false; 174 category = 1; 175 CountItems.subheader(out, tabber3); 176 } else if (diff.value >= minimumDate) { 177 // out.println(tabber.process("\tDiffers at:\t" + ICUServiceBuilder.isoDateFormat(diff.value))); 178 tabber = tabber == tabber1 ? tabber2 : tabber1; 179 ++category; 180 } 181 String zoneIDShown = zoneID; 182 if (needsTranslation.contains(zoneID)) { 183 zoneIDShown = "<b>" + zoneIDShown + "\u00B9</b>"; 184 } 185 if (singleCountries.contains(zoneID)) { 186 zoneIDShown = "<i>" + zoneIDShown + "</i> \u00B2"; 187 } 188 if (defaultItems.contains(zoneID)) { 189 zoneIDShown = "<span style='background-color: #FFFF00'>" + zoneIDShown 190 + "</span> ?"; 191 } 192 // if (country.equals(lastCountry) && diff.value >= minimumDate) System.out.print("X"); 193 String newCountry = country; 194 String mapLink = CountItems.country_map.get(country); 195 if (mapLink != null) { 196 newCountry = "<a target='map' href='" + mapLink + "'>" + country 197 + "</a>"; 198 } 199 String minOffset = ZoneInflections.formatHours(zip.getMinOffset(minimumDate)); 200 String maxOffset = ZoneInflections.formatHours(zip.getMaxOffset(minimumDate)); 201 if (!icu4jTZIDs.contains(zoneID)) { 202 minOffset = maxOffset = "??"; 203 } 204 205 out.println(tabber.process(newCountry + "\t" + "<b>" + category + "</b>" 206 + "\t" + zoneIDShown + "\t" 207 + tzf.getFormattedZone(zoneID, "vvvv", minimumDate, false) + "\t" 208 + minOffset + "\t" + maxOffset)); 209 lastCountry = country; 210 } 211 CountItems.subheader(out, tabber3); 212 out.println("</table>"); 213 out.println(CldrUtility.ANALYTICS); 214 out.println("</body></html>"); 215 out.close(); 216 } 217 218 } 219