1 package net.sf.saxon.number; 2 import net.sf.saxon.om.FastStringBuffer; 3 4 import java.io.Serializable ; 5 6 12 13 public class Numberer_en implements Numberer, Serializable { 14 15 public static final int UPPER_CASE = 0; 16 public static final int LOWER_CASE = 1; 17 public static final int TITLE_CASE = 2; 18 19 34 35 public String format(long number, 36 String picture, 37 int groupSize, 38 String groupSeparator, 39 String letterValue, 40 String ordinal) { 41 42 if (number < 0) { 43 return "" + number; 44 } 45 if (picture==null || picture.length()==0) { 46 return "" + number; 47 } 48 49 FastStringBuffer sb = new FastStringBuffer(16); 50 char formchar = picture.charAt(0); 51 52 switch(formchar) { 53 54 case '0': 55 case '1': 56 sb.append(toRadical(number, westernDigits, picture, groupSize, groupSeparator)); 57 if (ordinal != null && ordinal.length() > 0) { 58 sb.append(ordinalSuffix(ordinal, number)); 59 } 60 break; 61 62 case 'A': 63 if (number==0) return "0"; 64 sb.append(toAlphaSequence(number, latinUpper)); 65 break; 66 67 case 'a': 68 if (number==0) return "0"; 69 sb.append(toAlphaSequence(number, latinLower)); 70 break; 71 72 case 'w': 73 case 'W': 74 int wordCase; 75 if (picture.equals("W")) { 76 wordCase = UPPER_CASE; 77 } else if (picture.equals("w")) { 78 wordCase = LOWER_CASE; 79 } else { 80 wordCase = TITLE_CASE; 81 } 82 if (ordinal != null && ordinal.length() > 0) { 83 sb.append(toOrdinalWords(ordinal, number, wordCase)); 84 85 } else { 86 sb.append(toWords(number, wordCase)); 87 } 88 break; 89 90 case 'i': 91 if (number==0) return "0"; 92 if (letterValue==null || letterValue.equals("") || 93 letterValue.equals("traditional")) { 94 sb.append(toRoman(number)); 95 } else { 96 alphaDefault(number, formchar, sb); 97 } 98 break; 99 100 case 'I': 101 if (number==0) return "0"; 102 if (letterValue==null || letterValue.equals("") || 103 letterValue.equals("traditional")) { 104 sb.append(toRoman(number).toUpperCase()); 105 } else { 106 alphaDefault(number, formchar, sb); 107 } 108 break; 109 110 case '\u0391': 111 if (number==0) return "0"; 112 sb.append(toAlphaSequence(number, greekUpper)); 113 break; 114 115 case '\u03b1': 116 if (number==0) return "0"; 117 sb.append(toAlphaSequence(number, greekLower)); 118 break; 119 120 case '\u0410': 121 if (number==0) return "0"; 122 sb.append(toAlphaSequence(number, cyrillicUpper)); 123 break; 124 125 case '\u0430': 126 if (number==0) return "0"; 127 sb.append(toAlphaSequence(number, cyrillicLower)); 128 break; 129 130 case '\u05d0': 131 if (number==0) return "0"; 132 sb.append(toAlphaSequence(number, hebrew)); 133 break; 134 135 case '\u3042': 136 if (number==0) return "0"; 137 sb.append(toAlphaSequence(number, hiraganaA)); 138 break; 139 140 case '\u30a2': 141 if (number==0) return "0"; 142 sb.append(toAlphaSequence(number, katakanaA)); 143 break; 144 145 case '\u3044': 146 if (number==0) return "0"; 147 sb.append(toAlphaSequence(number, hiraganaI)); 148 break; 149 150 case '\u30a4': 151 if (number==0) return "0"; 152 sb.append(toAlphaSequence(number, katakanaI)); 153 break; 154 155 case '\u4e00': 156 if (number==0) return "0"; 157 sb.append(toRadical(number, kanjiDigits, picture, groupSize, groupSeparator)); 158 break; 159 160 default: 161 162 if (Character.isDigit(formchar)) { 163 164 int zero = (int)formchar - Character.getNumericValue(formchar); 165 String digits = "" + 166 (char)(zero) + 167 (char)(zero+1) + 168 (char)(zero+2) + 169 (char)(zero+3) + 170 (char)(zero+4) + 171 (char)(zero+5) + 172 (char)(zero+6) + 173 (char)(zero+7) + 174 (char)(zero+8) + 175 (char)(zero+9); 176 177 sb.append(toRadical(number, digits, picture, groupSize, groupSeparator)); 178 break; 179 180 } else { 181 if (number==0) return "0"; 182 if (formchar < '\u1100') { 183 alphaDefault(number, formchar, sb); 184 } else { 185 sb.append( 187 toRadical(number, westernDigits, picture, groupSize, groupSeparator)); 188 } 189 break; 190 191 } 192 } 193 194 return sb.toString(); 195 } 196 197 204 205 protected String ordinalSuffix(String ordinalParam, long number) { 206 int penult = ((int)(number % 100)) / 10; 207 int ult = (int)(number % 10); 208 if (penult==1) { 209 return "th"; 211 } else { 212 if (ult==1) { 213 return "st"; 214 } else if (ult==2) { 215 return "nd"; 216 } else if (ult==3) { 217 return "rd"; 218 } else { 219 return "th"; 220 } 221 } 222 } 223 224 protected static final String westernDigits = 225 "0123456789"; 226 227 protected static final String latinUpper = 228 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 229 230 protected static final String latinLower = 231 "abcdefghijklmnopqrstuvwxyz"; 232 233 protected static final String greekUpper = 234 "\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a" + 235 "\u039b\u039c\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4" + 236 "\u03a5\u03a6\u03a7\u03a8\u03a9"; 237 238 protected static final String greekLower = 239 "\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba" + 240 "\u03bb\u03bc\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c4" + 241 "\u03c5\u03c6\u03c7\u03c8\u03c9"; 242 243 246 protected static final String cyrillicUpper = 247 "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418" + 248 "\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0421\u0423" + 249 "\u0424\u0425\u0426\u0427\u0428\u0429\u042b\u042d\u042e\u042f"; 250 251 protected static final String cyrillicLower = 252 "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438" + 253 "\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0441\u0443" + 254 "\u0444\u0445\u0446\u0447\u0448\u0449\u044b\u044d\u044e\u044f"; 255 256 protected static final String hebrew = 257 "\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05db\u05dc" + 258 "\u05de\u05e0\u05e1\u05e2\u05e4\u05e6\u05e7\u05e8\u05e9\u05ea"; 259 260 261 264 protected static final String hiraganaA = 265 "\u3042\u3044\u3046\u3048\u304a\u304b\u304d\u304f\u3051\u3053" + 266 "\u3055\u3057\u3059\u305b\u305d\u305f\u3061\u3064\u3066\u3068" + 267 "\u306a\u306b\u306c\u306d\u306e\u306f\u3072\u3075\u3078\u307b" + 268 "\u307e\u307f\u3080\u3081\u3082\u3084\u3086\u3088\u3089\u308a" + 269 "\u308b\u308c\u308d\u308f\u3092\u3093"; 270 271 protected static final String katakanaA = 272 273 "\u30a2\u30a4\u30a6\u30a8\u30aa\u30ab\u30ad\u30af\u30b1\u30b3" + 274 "\u30b5\u30b7\u30b9\u30bb\u30bd\u30bf\u30c1\u30c4\u30c6\u30c8" + 275 "\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\u30d2\u30d5\u30d8\u30db" + 276 "\u30de\u30df\u30e0\u30e1\u30e2\u30e4\u30e6\u30e8\u30e9\u30ea" + 277 "\u30eb\u30ec\u30ed\u30ef\u30f2\u30f3"; 278 279 protected static final String hiraganaI = 280 281 "\u3044\u308d\u306f\u306b\u307b\u3078\u3068\u3061\u308a\u306c" + 282 "\u308b\u3092\u308f\u304b\u3088\u305f\u308c\u305d\u3064\u306d" + 283 "\u306a\u3089\u3080\u3046\u3090\u306e\u304a\u304f\u3084\u307e" + 284 "\u3051\u3075\u3053\u3048\u3066\u3042\u3055\u304d\u3086\u3081" + 285 "\u307f\u3057\u3091\u3072\u3082\u305b\u3059"; 286 287 protected static final String katakanaI = 288 289 "\u30a4\u30ed\u30cf\u30cb\u30db\u30d8\u30c8\u30c1\u30ea\u30cc" + 290 "\u30eb\u30f2\u30ef\u30ab\u30e8\u30bf\u30ec\u30bd\u30c4\u30cd" + 291 "\u30ca\u30e9\u30e0\u30a6\u30f0\u30ce\u30aa\u30af\u30e4\u30de" + 292 "\u30b1\u30d5\u30b3\u30a8\u30c6\u30a2\u30b5\u30ad\u30e6\u30e1" + 293 "\u30df\u30b7\u30f1\u30d2\u30e2\u30bb\u30b9"; 294 295 296 protected static final String kanjiDigits = 297 "\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d"; 298 299 300 304 305 protected void alphaDefault(long number, char formchar, FastStringBuffer sb) { 306 int min = (int)formchar; 307 int max = (int)formchar; 308 while (Character.isLetterOrDigit((char)(max+1))) { 310 max++; 311 } 312 sb.append(toAlpha(number, min, max)); 313 } 314 315 319 320 protected String toAlpha(long number, int min, int max) { 321 if (number<=0) return "" + number; 322 int range = max - min + 1; 323 char last = (char)(((number-1) % range) + min); 324 if (number>range) { 325 return toAlpha((number-1)/range, min, max) + last; 326 } else { 327 return "" + last; 328 } 329 } 330 331 335 336 protected String toAlphaSequence(long number, String alphabet) { 337 if (number<=0) return "" + number; 338 int range = alphabet.length(); 339 char last = alphabet.charAt((int)((number-1) % range)); 340 if (number>range) { 341 return toAlphaSequence((number-1)/range, alphabet) + last; 342 } else { 343 return "" + last; 344 } 345 } 346 347 361 362 private String toRadical(long number, String digits, String picture, 363 int groupSize, String groupSeparator) { 364 365 FastStringBuffer sb = new FastStringBuffer(16); 366 FastStringBuffer temp = new FastStringBuffer(16); 367 int base = digits.length(); 368 369 String s = ""; 370 long n = number; 371 while (n>0) { 372 s = digits.charAt((int)(n % base)) + s; 373 n = n / base; 374 } 375 376 for (int i=0; i<(picture.length()-s.length()); i++) { 377 temp.append(digits.charAt(0)); 378 } 379 temp.append(s); 380 381 if (groupSize>0) { 382 for (int i=0; i<temp.length(); i++) { 383 if (i!=0 && ((temp.length()-i) % groupSize) == 0) { 384 sb.append(groupSeparator); 385 } 386 sb.append(temp.charAt(i)); 387 } 388 } else { 389 sb = temp; 390 } 391 392 return sb.toString(); 393 } 394 395 398 399 public static String toRoman(long n) { 400 if (n<=0 || n>9999) return "" + n; 401 return romanThousands[(int)n/1000] + 402 romanHundreds[((int)n/100) % 10] + 403 romanTens[((int)n/10) % 10] + 404 romanUnits[(int)n % 10]; 405 } 406 407 410 private static String [] romanThousands = 411 {"", "m", "mm", "mmm", "mmmm", "mmmmm", "mmmmmm", "mmmmmmm", "mmmmmmmm", "mmmmmmmmm"}; 412 private static String [] romanHundreds = 413 {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"}; 414 private static String [] romanTens = 415 {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"}; 416 private static String [] romanUnits = 417 {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"}; 418 419 420 424 425 public String toWords(long number) { 426 if (number >= 1000000000) { 427 long rem = number % 1000000000; 428 return toWords(number / 1000000000) + " Billion" + 429 (rem==0 ? "" : (rem < 100 ? " and " : " ") + toWords(rem)); 430 } else if (number >= 1000000) { 431 long rem = number % 1000000; 432 return toWords(number / 1000000) + " Million" + 433 (rem==0 ? "" : (rem < 100 ? " and " : " ") + toWords(rem)); 434 } else if (number >= 1000) { 435 long rem = number % 1000; 436 return toWords(number / 1000) + " Thousand" + 437 (rem==0 ? "" : (rem < 100 ? " and " : " ") + toWords(rem)); 438 } else if (number >= 100) { 439 long rem = number % 100; 440 return toWords(number / 100) + " Hundred" + 441 (rem==0 ? "" : " and " + toWords(rem)); 442 } else { 443 if (number < 20) return englishUnits[(int)number]; 444 int rem = (int)(number % 10); 445 return englishTens[(int)number / 10] + 446 (rem==0 ? "" : ' ' + englishUnits[rem]); 447 } 448 } 449 450 public String toWords(long number, int wordCase) { 451 String s; 452 if (number == 0) { 453 s = "Zero"; 454 } else { 455 s = toWords(number); 456 } 457 if (wordCase == UPPER_CASE) { 458 return s.toUpperCase(); 459 } else if (wordCase == LOWER_CASE) { 460 return s.toLowerCase(); 461 } else { 462 return s; 463 } 464 } 465 466 469 470 public String toOrdinalWords(String ordinalParam, long number, int wordCase) { 471 String s; 472 if (number >= 1000000000) { 473 long rem = number % 1000000000; 474 s = toWords(number / 1000000000) + " Billion" + 475 (rem==0 ? "th" : (rem < 100 ? " and " : " ") + 476 toOrdinalWords(ordinalParam, rem, wordCase)); 477 } else if (number >= 1000000) { 478 long rem = number % 1000000; 479 s = toWords(number / 1000000) + " Million" + 480 (rem==0 ? "th" : (rem < 100 ? " and " : " ") + 481 toOrdinalWords(ordinalParam, rem, wordCase)); 482 } else if (number >= 1000) { 483 long rem = number % 1000; 484 s = toWords(number / 1000) + " Thousand" + 485 (rem==0 ? "th" : (rem < 100 ? " and " : " ") + 486 toOrdinalWords(ordinalParam, rem, wordCase)); 487 } else if (number >= 100) { 488 long rem = number % 100; 489 s = toWords(number / 100) + " Hundred" + 490 (rem==0 ? "th" : " and " + 491 toOrdinalWords(ordinalParam, rem, wordCase)); 492 } else { 493 if (number < 20) { 494 s = englishOrdinalUnits[(int)number]; 495 } else { 496 int rem = (int)(number % 10); 497 if (rem==0) { 498 s = englishOrdinalTens[(int)number / 10]; 499 } else { 500 s = englishTens[(int)number / 10] + '-' + englishOrdinalUnits[rem]; 501 } 502 } 503 } 504 if (wordCase == UPPER_CASE) { 505 return s.toUpperCase(); 506 } else if (wordCase == LOWER_CASE) { 507 return s.toLowerCase(); 508 } else { 509 return s; 510 } 511 } 512 513 private static String [] englishUnits = { 514 "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", 515 "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", 516 "Seventeen", "Eighteen", "Nineteen"}; 517 518 private static String [] englishTens = { 519 "", "Ten", "Twenty", "Thirty", "Forty", "Fifty", 520 "Sixty", "Seventy", "Eighty", "Ninety"}; 521 522 private static String [] englishOrdinalUnits = { 523 "", "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", 524 "Tenth", "Eleventh", "Twelfth", "Thirteenth", "Fourteenth", "Fifteenth", "Sixteenth", 525 "Seventeenth", "Eighteenth", "Nineteenth"}; 526 527 private static String [] englishOrdinalTens = { 528 "", "Tenth", "Twentieth", "Thirtieth", "Fortieth", "Fiftieth", 529 "Sixtieth", "Seventieth", "Eightieth", "Ninetieth"}; 530 531 537 538 public String monthName(int month, int minWidth, int maxWidth) { 539 String name = englishMonths[month-1]; 540 if (maxWidth < 3) { 541 maxWidth = 3; 542 } 543 if (name.length() > maxWidth) { 544 name = name.substring(0, maxWidth); 545 } 546 while (name.length() < minWidth) { 547 name = name + ' '; 548 } 549 return name; 550 } 551 552 private static String [] englishMonths = { 553 "January", "February", "March", "April", "May", "June", 554 "July", "August", "September", "October", "November", "December" 555 }; 556 557 563 564 public String dayName(int day, int minWidth, int maxWidth) { 565 String name = englishDays[day-1]; 566 if (maxWidth < 2) { 567 maxWidth = 2; 568 } 569 if (name.length() > maxWidth) { 570 name = englishDayAbbreviations[day-1]; 571 if (name.length() > maxWidth) { 572 name = name.substring(0, maxWidth); 573 } 574 } 575 while (name.length() < minWidth) { 576 name = name + ' '; 577 } 578 if (minWidth==1 && maxWidth==2) { 579 name = name.substring(0, minUniqueDayLength[day-1]); 581 } 582 return name; 583 } 584 585 private static String [] englishDays = { 586 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 587 }; 588 589 private static String [] englishDayAbbreviations = { 590 "Sun", "Mon", "Tues", "Weds", "Thurs", "Fri", "Sat" 591 }; 592 593 private static int[] minUniqueDayLength = { 594 1, 2, 1, 2, 1, 2, 2 595 }; 596 597 604 605 public String halfDayName(int minutes, int minWidth, int maxWidth) { 606 String s; 607 if (minutes < 12*60) { 608 switch (maxWidth) { 609 case 1: 610 s = "A"; 611 break; 612 case 2: 613 case 3: 614 s = "Am"; 615 break; 616 default: 617 s = "A.M."; 618 } 619 } else { 620 switch (maxWidth) { 621 case 1: 622 s = "P"; 623 break; 624 case 2: 625 case 3: 626 s = "Pm"; 627 break; 628 default: 629 s = "P.M."; 630 } 631 } 632 return s; 633 } 634 635 644 645 public String getOrdinalSuffixForDateTime(String component) { 646 return "yes"; 647 } 648 649 } 650 651 | Popular Tags |