2using System.Collections.Generic;
8using System.Xml.Schema;
12 private static string app = AppDomain.CurrentDomain.FriendlyName;
13 private static TextWriter stderr = Console.Error;
14 private static TextWriter stdout = Console.Out;
16 private static void usage()
18 stderr.WriteLine(
"Usage:");
19 stderr.WriteLine(app +
" <path to output files>");
23 private static bool writeZoneMapC(
string path)
25 string fname =
"TimeZoneNameMap";
26 string fpath = Path.Combine(path, fname +
"_static.h");
28 using (StreamWriter fs =
new StreamWriter(fpath))
30 fs.WriteLine(
"/* Automatically generated by " + app +
" */");
32 fs.WriteLine(
"#include \"" + fname +
".h\"");
34 fs.WriteLine(
"static const " + fname +
"Entry " + fname +
"[] ={");
37 foreach (System.TimeZoneInfo tz in System.TimeZoneInfo.GetSystemTimeZones())
40 System.TimeZoneInfo.TryConvertWindowsIdToIanaId(tz.Id, out iana);
42 StringBuilder sb =
new StringBuilder();
49 sb.Append(tz.StandardName);
51 sb.Append(tz.DisplayName);
53 sb.Append(tz.DaylightName);
57 fs.WriteLine(sb.ToString());
62 fs.WriteLine(
"static const size_t " + fname +
"Size = ARRAYSIZE(" + fname +
");");
67 private static bool writeZoneMapJSON(
string path)
69 string fname =
"TimeZoneNameMap";
70 string fpath = Path.Combine(path, fname +
".json");
72 using (StreamWriter fs =
new StreamWriter(fpath))
75 fs.WriteLine(
"\"TimeZoneNameMap\": [");
78 foreach (System.TimeZoneInfo tz in System.TimeZoneInfo.GetSystemTimeZones())
81 System.TimeZoneInfo.TryConvertWindowsIdToIanaId(tz.Id, out iana);
83 StringBuilder sb =
new StringBuilder();
88 sb.Append(
"\"Id\": \"");
90 sb.Append(
"\", \"StandardName\": \"");
91 sb.Append(tz.StandardName);
92 sb.Append(
"\", \"DisplayName\": \"");
93 sb.Append(tz.DisplayName);
94 sb.Append(
"\", \"DaylightName\": \"");
95 sb.Append(tz.DaylightName);
96 sb.Append(
"\", \"Iana\": \"");
99 fs.WriteLine(sb.ToString());
108 private static bool writeZoneMap(
string path)
110 if (!writeZoneMapC(path))
112 if (!writeZoneMapJSON(path))
117 private static void onValidation(
object sender, ValidationEventArgs e)
121 case XmlSeverityType.Warning:
122 case XmlSeverityType.Error:
123 stderr.WriteLine(e.ToString());
129 private static bool updateWindowsIanaMap(
string path)
132 "https://raw.githubusercontent.com/unicode-org/cldr/main/common/supplemental/windowsZones.xml";
133 string fname =
"WindowsZones";
134 string fpath = Path.Combine(path, fname +
".c");
136 XmlDocument doc =
new XmlDocument();
139 stdout.WriteLine(
"Downloaded and parsed XML from '" + url +
"'");
141 ValidationEventHandler handler =
new ValidationEventHandler(onValidation);
144 XmlNodeList versions = doc.SelectNodes(
"//supplementalData/version");
145 XmlNodeList zones = doc.SelectNodes(
"//supplementalData/windowsZones/mapTimezones");
147 doc.SelectNodes(
"//supplementalData/windowsZones/mapTimezones/mapZone");
149 using (StreamWriter fs =
new StreamWriter(fpath))
151 fs.WriteLine(
"/* Automatically generated by " + app);
153 fs.WriteLine(
" * url " + url);
155 foreach (XmlNode version
in versions)
157 XmlNode nr = version.Attributes.GetNamedItem(
"number");
158 fs.WriteLine(
" * version: " + nr.InnerText);
161 foreach (XmlNode node
in zones)
163 XmlNode over = node.Attributes.GetNamedItem(
"otherVersion");
164 XmlNode tver = node.Attributes.GetNamedItem(
"typeVersion");
165 fs.WriteLine(
" * mapTimezones: otherVersion: " + over.InnerText +
166 ", typeVersion: " + tver.InnerText);
171 fs.WriteLine(
"#include \"" + fname +
".h\"");
173 fs.WriteLine(
"const WINDOWS_TZID_ENTRY " + fname +
"[] = {");
175 foreach (XmlNode mzone
in mzones)
177 XmlAttributeCollection attrs = mzone.Attributes;
178 XmlNode wzid = attrs.GetNamedItem(
"other");
179 XmlNode territory = attrs.GetNamedItem(
"territory");
180 XmlNode iana = attrs.GetNamedItem(
"type");
181 fs.WriteLine(
"\t{ \"" + iana.InnerText +
"\", \"" + wzid.InnerText +
"\" }, // " +
182 territory.InnerText);
187 fs.WriteLine(
"const size_t " + fname +
"NrElements = ARRAYSIZE(" + fname +
");");
189 stdout.WriteLine(
"Finished update");
193 private static bool writeIanaAliasesC(
string path,
string url, XmlNodeList versions,
194 List<
string[]> aliases)
196 string fname =
"TimeZoneIanaAliases";
197 string fpath = Path.Combine(path, fname +
"_static.h");
199 using (StreamWriter fs =
new StreamWriter(fpath))
201 fs.WriteLine(
"/* Automatically generated by " + app);
203 fs.WriteLine(
" * url " + url);
205 foreach (XmlNode version
in versions)
207 XmlNode nr = version.Attributes.GetNamedItem(
"number");
208 fs.WriteLine(
" * version: " + nr.InnerText);
213 fs.WriteLine(
"#include \"" + fname +
".h\"");
215 fs.WriteLine(
"static const TimeZoneIanaAliasEntry " + fname +
"[] = {");
217 foreach (
string[] alias
in aliases)
218 fs.WriteLine(
"\t{ \"" + alias[0] +
"\", \"" + alias[1] +
"\" },");
222 fs.WriteLine(
"static const size_t " + fname +
"Size = ARRAYSIZE(" + fname +
");");
227 private static bool writeIanaAliasesJSON(
string path, List<
string[]> aliases)
229 string fname =
"TimeZoneIanaAliases";
230 string fpath = Path.Combine(path, fname +
".json");
232 using (StreamWriter fs =
new StreamWriter(fpath))
235 fs.WriteLine(
"\"" + fname +
"\": [");
238 foreach (
string[] alias
in aliases)
240 StringBuilder sb =
new StringBuilder();
244 sb.Append(
"{ \"Current\": \"");
246 sb.Append(
"\", \"Legacy\": \"");
249 fs.WriteLine(sb.ToString());
258 private static bool updateIanaAliases(
string path)
261 "https://raw.githubusercontent.com/unicode-org/cldr/main/common/bcp47/timezone.xml";
263 XmlDocument doc =
new XmlDocument();
266 stdout.WriteLine(
"Downloaded and parsed XML from '" + url +
"'");
268 XmlNodeList versions = doc.SelectNodes(
"//ldmlBCP47/version");
269 XmlNodeList types = doc.SelectNodes(
"//ldmlBCP47/keyword/key[@name='tz']/type[@iana]");
271 List<string[]> aliases =
new List<string[]>();
272 foreach (XmlNode type
in types)
274 XmlAttributeCollection attrs = type.Attributes;
275 string iana = attrs.GetNamedItem(
"iana").InnerText;
278 string legacy = attrs.GetNamedItem(
"alias").InnerText.Split(
' ')[0];
280 aliases.Add(
new string[] { iana, legacy });
283 if (!writeIanaAliasesC(path, url, versions, aliases))
285 if (!writeIanaAliasesJSON(path, aliases))
288 stdout.WriteLine(
"Finished update");
292 private static void Main(
string[] args)
296 if (args.Length == 0)
298 stderr.WriteLine(
"Missing arguments!");
302 DirectoryInfo info =
new DirectoryInfo(args[0]);
305 stderr.WriteLine(
"Path '" + info.FullName +
"' does not exist");
309 if (!writeZoneMap(info.FullName))
312 updateWindowsIanaMap(info.FullName);
313 updateIanaAliases(info.FullName);
317 stderr.WriteLine(e.ToString());
318 Environment.Exit(-23);