001: package net.sf.saxon.number;
002:
003: /**
004: * Class Numberer_de is designed simply to demonstrate how to write a number formatter
005: * for a different language. This one will be activated for language="de", format="eins",
006: * letter-value="traditional"
007: * @author Michael H. Kay
008: */
009:
010: public class Numberer_de extends Numberer_en {
011:
012: /**
013: * Construct the ordinal suffix for a number, for example "st", "nd", "rd"
014: * @param ordinalParam the value of the ordinal attribute (used in non-English
015: * language implementations)
016: * @param number the number being formatted
017: * @return the ordinal suffix to be appended to the formatted number
018: */
019:
020: protected String ordinalSuffix(String ordinalParam, long number) {
021: return ".";
022: }
023:
024: /**
025: * Show the number as words in title case. (We choose title case because
026: * the result can then be converted algorithmically to lower case or upper case).
027: */
028:
029: public String toWords(long number) {
030: if (number >= 1000000000) {
031: long rem = number % 1000000000;
032: long n = number / 100000000;
033: String s = (n == 1 ? "Eine" : toWords(n));
034: return s + " Milliarde"
035: + (rem == 0 ? "" : ' ' + toWords(rem));
036: } else if (number >= 1000000) {
037: long rem = number % 1000000;
038: long n = number / 1000000;
039: String s = (n == 1 ? "Eine" : toWords(n));
040: return s + " Million"
041: + (rem == 0 ? "" : ' ' + toWords(rem));
042: } else if (number >= 1000) {
043: long rem = number % 1000;
044: long n = number / 1000;
045: String s = (n == 1 ? "Ein" : toWords(n));
046: return s + "tausend" + (rem == 0 ? "" : ' ' + toWords(rem));
047: } else if (number >= 100) {
048: long rem = number % 100;
049: long n = number / 100;
050: String s = (n == 1 ? "Ein" : toWords(n));
051: return s
052: + "hundert"
053: + (rem == 0 ? "" : (rem > 20 ? "" : "und")
054: + toWords(rem, LOWER_CASE));
055: } else {
056: if (number < 20)
057: return germanUnits[(int) number];
058: int rem = (int) (number % 10);
059: int tens = (int) number / 10;
060: return (germanUnits[rem])
061: + (tens == 0 ? "" : (rem == 0 ? "" : "und")
062: + germanTens[tens]);
063:
064: }
065: }
066:
067: private static String[] germanUnits = { "", "Eins", "Zwei", "Drei",
068: "Vier", "Fünf", "Sechs", "Sieben", "Acht", "Neun", "Zehn",
069: "Elf", "Zwölf", "Dreizehn", "Vierzehn", "Fünfzehn",
070: "Sechszehn", "Siebzehn", "Achtzehn", "Neunzehn" };
071:
072: private static String[] germanTens = { "", "Zehn", "Zwanzig",
073: "Dreißig", "Vierzig", "Fünfzig", "Sechzig", "Siebzig",
074: "Achtzig", "Neunzig" };
075:
076: /**
077: * Show an ordinal number as German words (for example, Einundzwanzigste)
078: */
079:
080: public String toOrdinalWords(String ordinalParam, long number,
081: int wordCase) {
082: String suffix = "e";
083: if (ordinalParam.equalsIgnoreCase("-er")) {
084: suffix = "er";
085: } else if (ordinalParam.equalsIgnoreCase("-es")) {
086: suffix = "es";
087: } else if (ordinalParam.equalsIgnoreCase("-en")) {
088: suffix = "en";
089: }
090: long mod100 = number % 100;
091: if (number < 20) {
092: String ord = germanOrdinalUnits[(int) number] + suffix;
093: if (wordCase == UPPER_CASE) {
094: return ord.toUpperCase();
095: } else if (wordCase == LOWER_CASE) {
096: return ord.toLowerCase();
097: } else {
098: return ord;
099: }
100: } else if (mod100 < 20 && mod100 > 0) {
101: return toWords(number - (mod100), wordCase)
102: + toOrdinalWords(ordinalParam, mod100,
103: (wordCase == TITLE_CASE ? LOWER_CASE
104: : wordCase));
105: } else {
106: String ending = "st" + suffix;
107: if (wordCase == UPPER_CASE) {
108: ending = ending.toUpperCase();
109: }
110: return toWords(number, wordCase)
111: + (wordCase == UPPER_CASE ? ending.toUpperCase()
112: : ending);
113: }
114: }
115:
116: private static String[] germanOrdinalUnits = { "", "Erst", "Zweit",
117: "Dritt", "Viert", "Fünft", "Sechst", "Siebt", "Acht",
118: "Neunt", "Zehnt", "Elft", "Zwölft", "Dreizehnt",
119: "Vierzehnt", "Fünfzehnt", "Sechszehnt", "Siebzehnt",
120: "Achtzehnt", "Neunzehnt" };
121:
122: //
123: // private static String[] germanOrdinalTens = {
124: // "", "Tenth", "Twentieth", "Thirtieth", "Fortieth", "Fiftieth",
125: // "Sixtieth", "Seventieth", "Eightieth", "Ninetieth"};
126:
127: /**
128: * Get a month name or abbreviation
129: * @param month The month number (1=January, 12=December)
130: * @param minWidth The minimum number of characters
131: * @param maxWidth The maximum number of characters
132: */
133:
134: public String monthName(int month, int minWidth, int maxWidth) {
135: String name = germanMonths[month - 1];
136: if (maxWidth < 3) {
137: maxWidth = 3;
138: }
139: if (name.length() > maxWidth) {
140: name = name.substring(0, maxWidth);
141: }
142: while (name.length() < minWidth) {
143: name = name + " ";
144: }
145: return name;
146: }
147:
148: private static String[] germanMonths = { "Januar", "Februar",
149: "März", "April", "Mai", "Juni", "Juli", "August",
150: "September", "Oktober", "November", "Dezember" };
151:
152: /**
153: * Get a day name or abbreviation
154: * @param day The month number (1=Sunday, 7=Saturday)
155: * @param minWidth The minimum number of characters
156: * @param maxWidth The maximum number of characters
157: */
158:
159: public String dayName(int day, int minWidth, int maxWidth) {
160: String name = germanDays[day - 1];
161: if (maxWidth < 10) {
162: name = name.substring(0, 2);
163: }
164: while (name.length() < minWidth) {
165: name = name + ' ';
166: }
167: return name;
168: }
169:
170: private static String[] germanDays = { "Montag", "Dienstag",
171: "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" };
172:
173: /**
174: * Get an ordinal suffix for a particular component of a date/time.
175: *
176: * @param component the component specifier from a format-dateTime picture, for
177: * example "M" for the month or "D" for the day.
178: * @return a string that is acceptable in the ordinal attribute of xsl:number
179: * to achieve the required ordinal representation. For example, "-e" for the day component
180: * in German, to have the day represented as "dritte August".
181: */
182:
183: public String getOrdinalSuffixForDateTime(String component) {
184: return "-e";
185: }
186:
187: /**
188: * Get the name for an era (e.g. "BC" or "AD")
189: * @param year: the proleptic gregorian year, using "0" for the year before 1AD
190: */
191:
192: public String getEraName(int year) {
193: return (year <= 0 ? "v. Chr." : "n. Chr.");
194: }
195:
196: }
197:
198: //
199: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
200: // you may not use this file except in compliance with the License. You may obtain a copy of the
201: // License at http://www.mozilla.org/MPL/
202: //
203: // Software distributed under the License is distributed on an "AS IS" basis,
204: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
205: // See the License for the specific language governing rights and limitations under the License.
206: //
207: // The Original Code is: all this file.
208: //
209: // The Initial Developer of the Original Code is Michael H. Kay.
210: //
211: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
212: //
213: // Contributor(s): none.
214: //
|