DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
********************************************************************************
*   Copyright (C) 1997-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
********************************************************************************
*
* File CALENDAR.H
*
* Modification History:
*
*   Date        Name        Description
*   04/22/97    aliu        Expanded and corrected comments and other header
*                           contents.
*   05/01/97    aliu        Made equals(), before(), after() arguments const.
*   05/20/97    aliu        Replaced fAreFieldsSet with fAreFieldsInSync and
*                           fAreAllFieldsSet.
*   07/27/98    stephen     Sync up with JDK 1.2
*   11/15/99    weiv        added YEAR_WOY and DOW_LOCAL
*                           to EDateFields
*    8/19/2002  srl         Removed Javaisms
*   11/07/2003  srl         Update, clean up documentation.
********************************************************************************
*/

#ifndef CALENDAR_H
#define CALENDAR_H

#include "unicode/utypes.h"

/**
 * \file
 * \brief C++ API: Calendar object
 */
#if !UCONFIG_NO_FORMATTING

#include "unicode/uobject.h"
#include "unicode/locid.h"
#include "unicode/timezone.h"
#include "unicode/ucal.h"
#include "unicode/umisc.h"

U_NAMESPACE_BEGIN

class ICUServiceFactory;

/**
 * @internal
 */
typedef int32_t UFieldResolutionTable[12][8];

class BasicTimeZone;
/**
 * `Calendar` is an abstract base class for converting between
 * a `UDate` object and a set of integer fields such as
 * `YEAR`, `MONTH`, `DAY`, `HOUR`, and so on.
 * (A `UDate` object represents a specific instant in
 * time with millisecond precision. See UDate
 * for information about the `UDate` class.)
 *
 * Subclasses of `Calendar` interpret a `UDate`
 * according to the rules of a specific calendar system.
 * The most commonly used subclass of `Calendar` is
 * `GregorianCalendar`. Other subclasses could represent
 * the various types of lunar calendars in use in many parts of the world.
 *
 * **NOTE**: (ICU 2.6) The subclass interface should be considered unstable -
 * it WILL change.
 *
 * Like other locale-sensitive classes, `Calendar` provides a
 * static method, `createInstance`, for getting a generally useful
 * object of this type. `Calendar`'s `createInstance` method
 * returns the appropriate `Calendar` subclass whose
 * time fields have been initialized with the current date and time:
 *
 *     Calendar *rightNow = Calendar::createInstance(errCode);
 *
 * A `Calendar` object can produce all the time field values
 * needed to implement the date-time formatting for a particular language
 * and calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
 *
 * When computing a `UDate` from time fields, some special circumstances
 * may arise: there may be insufficient information to compute the
 * `UDate` (such as only year and month but no day in the month),
 * there may be inconsistent information (such as "Tuesday, July 15, 1996"
 * -- July 15, 1996 is actually a Monday), or the input time might be ambiguous
 * because of time zone transition.
 *
 * **Insufficient information.** The calendar will use default
 * information to specify the missing fields. This may vary by calendar; for
 * the Gregorian calendar, the default for a field is the same as that of the
 * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
 *
 * **Inconsistent information.** If fields conflict, the calendar
 * will give preference to fields set more recently. For example, when
 * determining the day, the calendar will look for one of the following
 * combinations of fields.  The most recent combination, as determined by the
 * most recently set single field, will be used.
 *
 *     MONTH + DAY_OF_MONTH
 *     MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
 *     MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
 *     DAY_OF_YEAR
 *     DAY_OF_WEEK + WEEK_OF_YEAR
 *
 * For the time of day:
 *
 *     HOUR_OF_DAY
 *     AM_PM + HOUR
 *
 * **Ambiguous Wall Clock Time.** When time offset from UTC has
 * changed, it produces an ambiguous time slot around the transition. For example,
 * many US locations observe daylight saving time. On the date switching to daylight
 * saving time in US, wall clock time jumps from 12:59 AM (standard) to 2:00 AM
 * (daylight). Therefore, wall clock time from 1:00 AM to 1:59 AM do not exist on
 * the date. When the input wall time fall into this missing time slot, the ICU
 * Calendar resolves the time using the UTC offset before the transition by default.
 * In this example, 1:30 AM is interpreted as 1:30 AM standard time (non-exist),
 * so the final result will be 2:30 AM daylight time.
 *
 * On the date switching back to standard time, wall clock time is moved back one
 * hour at 2:00 AM. So wall clock time from 1:00 AM to 1:59 AM occur twice. In this
 * case, the ICU Calendar resolves the time using the UTC offset after the transition
 * by default. For example, 1:30 AM on the date is resolved as 1:30 AM standard time.
 *
 * Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs
 * {@link #setRepeatedWallTimeOption} and {@link #setSkippedWallTimeOption}.
 * These methods are available in ICU 49 or later versions.
 *
 * **Note:** for some non-Gregorian calendars, different
 * fields may be necessary for complete disambiguation. For example, a full
 * specification of the historical Arabic astronomical calendar requires year,
 * month, day-of-month *and* day-of-week in some cases.
 *
 * **Note:** There are certain possible ambiguities in
 * interpretation of certain singular times, which are resolved in the
 * following ways:
 *
 *   1. 24:00:00 "belongs" to the following day. That is,
 *      23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970
 *   2. Although historically not precise, midnight also belongs to "am",
 *      and noon belongs to "pm", so on the same day,
 *      12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
 *
 * The date or time format strings are not part of the definition of a
 * calendar, as those must be modifiable or overridable by the user at
 * runtime. Use `DateFormat` to format dates.
 *
 * `Calendar` provides an API for field "rolling", where fields
 * can be incremented or decremented, but wrap around. For example, rolling the
 * month up in the date December 12, **1996** results in
 * January 12, **1996**.
 *
 * `Calendar` also provides a date arithmetic function for
 * adding the specified (signed) amount of time to a particular time field.
 * For example, subtracting 5 days from the date `September 12, 1996`
 * results in `September 7, 1996`.
 *
 * ***Supported range***
 *
 * The allowable range of `Calendar` has been narrowed. `GregorianCalendar` used
 * to attempt to support the range of dates with millisecond values from
 * `Long.MIN_VALUE` to `Long.MAX_VALUE`. The new `Calendar` protocol specifies the
 * maximum range of supportable dates as those having Julian day numbers
 * of `-0x7F000000` to `+0x7F000000`. This corresponds to years from ~5,800,000 BCE
 * to ~5,800,000 CE. Programmers should use the protected constants in `Calendar` to
 * specify an extremely early or extremely late date.
 *
 * <p>
 * The Japanese calendar uses a combination of era name and year number.
 * When an emperor of Japan abdicates and a new emperor ascends the throne,
 * a new era is declared and year number is reset to 1. Even if the date of
 * abdication is scheduled ahead of time, the new era name might not be
 * announced until just before the date. In such case, ICU4C may include
 * a start date of future era without actual era name, but not enabled
 * by default. ICU4C users who want to test the behavior of the future era
 * can enable the tentative era by:
 * <ul>
 * <li>Environment variable <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
 * </ul>
 *
 * @stable ICU 2.0
 */
class U_I18N_API Calendar : public UObject {
public:

    /**
     * Field IDs for date and time. Used to specify date/time fields. ERA is calendar
     * specific. Example ranges given are for illustration only; see specific Calendar
     * subclasses for actual ranges.
     * @deprecated ICU 2.6. Use C enum UCalendarDateFields defined in ucal.h
     */
    enum EDateFields {
#ifndef U_HIDE_DEPRECATED_API
/*
 * ERA may be defined on other platforms. To avoid any potential problems undefined it here.
 */
#ifdef ERA
#undef ERA
#endif
        ERA,                  // Example: 0..1
        YEAR,                 // Example: 1..big number
        MONTH,                // Example: 0..11
        WEEK_OF_YEAR,         // Example: 1..53
        WEEK_OF_MONTH,        // Example: 1..4
        DATE,                 // Example: 1..31
        DAY_OF_YEAR,          // Example: 1..365
        DAY_OF_WEEK,          // Example: 1..7
        DAY_OF_WEEK_IN_MONTH, // Example: 1..4, may be specified as -1
        AM_PM,                // Example: 0..1
        HOUR,                 // Example: 0..11
        HOUR_OF_DAY,          // Example: 0..23
        MINUTE,               // Example: 0..59
        SECOND,               // Example: 0..59
        MILLISECOND,          // Example: 0..999
        ZONE_OFFSET,          // Example: -12*U_MILLIS_PER_HOUR..12*U_MILLIS_PER_HOUR
        DST_OFFSET,           // Example: 0 or U_MILLIS_PER_HOUR
        YEAR_WOY,             // 'Y' Example: 1..big number - Year of Week of Year
        DOW_LOCAL,            // 'e' Example: 1..7 - Day of Week / Localized

        EXTENDED_YEAR,
        JULIAN_DAY,
        MILLISECONDS_IN_DAY,
        IS_LEAP_MONTH,

        FIELD_COUNT = UCAL_FIELD_COUNT // See ucal.h for other fields.
#endif /* U_HIDE_DEPRECATED_API */
    };

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Useful constant for days of week. Note: Calendar day-of-week is 1-based. Clients
     * who create locale resources for the field of first-day-of-week should be aware of
     * this. For instance, in US locale, first-day-of-week is set to 1, i.e., SUNDAY.
     * @deprecated ICU 2.6. Use C enum UCalendarDaysOfWeek defined in ucal.h
     */
    enum EDaysOfWeek {
        SUNDAY = 1,
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY
    };

    /**
     * Useful constants for month. Note: Calendar month is 0-based.
     * @deprecated ICU 2.6. Use C enum UCalendarMonths defined in ucal.h
     */
    enum EMonths {
        JANUARY,
        FEBRUARY,
        MARCH,
        APRIL,
        MAY,
        JUNE,
        JULY,
        AUGUST,
        SEPTEMBER,
        OCTOBER,
        NOVEMBER,
        DECEMBER,
        UNDECIMBER
    };

    /**
     * Useful constants for hour in 12-hour clock. Used in GregorianCalendar.
     * @deprecated ICU 2.6. Use C enum UCalendarAMPMs defined in ucal.h
     */
    enum EAmpm {
        AM,
        PM
    };
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * destructor
     * @stable ICU 2.0
     */
    virtual ~Calendar();

    /**
     * Create and return a polymorphic copy of this calendar.
     *
     * @return    a polymorphic copy of this calendar.
     * @stable ICU 2.0
     */
    virtual Calendar* clone(void) const = 0;

    /**
     * Creates a Calendar using the default timezone and locale. Clients are responsible
     * for deleting the object returned.
     *
     * @param success  Indicates the success/failure of Calendar creation. Filled in
     *                 with U_ZERO_ERROR if created successfully, set to a failure result
     *                 otherwise. U_MISSING_RESOURCE_ERROR will be returned if the resource data
     *                 requests a calendar type which has not been installed.
     * @return         A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(UErrorCode& success);

    /**
     * Creates a Calendar using the given timezone and the default locale.
     * The Calendar takes ownership of zoneToAdopt; the
     * client must not delete it.
     *
     * @param zoneToAdopt  The given timezone to be adopted.
     * @param success      Indicates the success/failure of Calendar creation. Filled in
     *                     with U_ZERO_ERROR if created successfully, set to a failure result
     *                     otherwise.
     * @return             A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(TimeZone* zoneToAdopt, UErrorCode& success);

    /**
     * Creates a Calendar using the given timezone and the default locale.  The TimeZone
     * is _not_ adopted; the client is still responsible for deleting it.
     *
     * @param zone  The timezone.
     * @param success      Indicates the success/failure of Calendar creation. Filled in
     *                     with U_ZERO_ERROR if created successfully, set to a failure result
     *                     otherwise.
     * @return             A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(const TimeZone& zone, UErrorCode& success);

    /**
     * Creates a Calendar using the default timezone and the given locale.
     *
     * @param aLocale  The given locale.
     * @param success  Indicates the success/failure of Calendar creation. Filled in
     *                 with U_ZERO_ERROR if created successfully, set to a failure result
     *                 otherwise.
     * @return         A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(const Locale& aLocale, UErrorCode& success);

    /**
     * Creates a Calendar using the given timezone and given locale.
     * The Calendar takes ownership of zoneToAdopt; the
     * client must not delete it.
     *
     * @param zoneToAdopt  The given timezone to be adopted.
     * @param aLocale      The given locale.
     * @param success      Indicates the success/failure of Calendar creation. Filled in
     *                     with U_ZERO_ERROR if created successfully, set to a failure result
     *                     otherwise.
     * @return             A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(TimeZone* zoneToAdopt, const Locale& aLocale, UErrorCode& success);

    /**
     * Gets a Calendar using the given timezone and given locale.  The TimeZone
     * is _not_ adopted; the client is still responsible for deleting it.
     *
     * @param zone         The given timezone.
     * @param aLocale      The given locale.
     * @param success      Indicates the success/failure of Calendar creation. Filled in
     *                     with U_ZERO_ERROR if created successfully, set to a failure result
     *                     otherwise.
     * @return             A Calendar if created successfully. NULL otherwise.
     * @stable ICU 2.0
     */
    static Calendar* U_EXPORT2 createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode& success);

    /**
     * Returns a list of the locales for which Calendars are installed.
     *
     * @param count  Number of locales returned.
     * @return       An array of Locale objects representing the set of locales for which
     *               Calendars are installed.  The system retains ownership of this list;
     *               the caller must NOT delete it. Does not include user-registered Calendars.
     * @stable ICU 2.0
     */
    static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count);


    /**
     * Given a key and a locale, returns an array of string values in a preferred
     * order that would make a difference. These are all and only those values where
     * the open (creation) of the service with the locale formed from the input locale
     * plus input keyword and that value has different behavior than creation with the
     * input locale alone.
     * @param key           one of the keys supported by this service.  For now, only
     *                      "calendar" is supported.
     * @param locale        the locale
     * @param commonlyUsed  if set to true it will return only commonly used values
     *                      with the given locale in preferred order.  Otherwise,
     *                      it will return all the available values for the locale.
     * @param status        ICU Error Code
     * @return a string enumeration over keyword values for the given key and the locale.
     * @stable ICU 4.2
     */
    static StringEnumeration* U_EXPORT2 getKeywordValuesForLocale(const char* key,
                    const Locale& locale, UBool commonlyUsed, UErrorCode& status);

    /**
     * Returns the current UTC (GMT) time measured in milliseconds since 0:00:00 on 1/1/70
     * (derived from the system time).
     *
     * @return   The current UTC time in milliseconds.
     * @stable ICU 2.0
     */
    static UDate U_EXPORT2 getNow(void);

    /**
     * Gets this Calendar's time as milliseconds. May involve recalculation of time due
     * to previous calls to set time field values. The time specified is non-local UTC
     * (GMT) time. Although this method is const, this object may actually be changed
     * (semantically const).
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @return        The current time in UTC (GMT) time, or zero if the operation
     *                failed.
     * @stable ICU 2.0
     */
    inline UDate getTime(UErrorCode& status) const { return getTimeInMillis(status); }

    /**
     * Sets this Calendar's current time with the given UDate. The time specified should
     * be in non-local UTC (GMT) time.
     *
     * @param date  The given UDate in UTC (GMT) time.
     * @param status  Output param set to success/failure code on exit. If any value
     *                set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.0
     */
    inline void setTime(UDate date, UErrorCode& status) { setTimeInMillis(date, status); }

    /**
     * Compares the equality of two Calendar objects. Objects of different subclasses
     * are considered unequal. This comparison is very exacting; two Calendar objects
     * must be in exactly the same state to be considered equal. To compare based on the
     * represented time, use equals() instead.
     *
     * @param that  The Calendar object to be compared with.
     * @return      True if the given Calendar is the same as this Calendar; false
     *              otherwise.
     * @stable ICU 2.0
     */
    virtual UBool operator==(const Calendar& that) const;

    /**
     * Compares the inequality of two Calendar objects.
     *
     * @param that  The Calendar object to be compared with.
     * @return      True if the given Calendar is not the same as this Calendar; false
     *              otherwise.
     * @stable ICU 2.0
     */
    UBool operator!=(const Calendar& that) const {return !operator==(that);}

    /**
     * Returns TRUE if the given Calendar object is equivalent to this
     * one.  An equivalent Calendar will behave exactly as this one
     * does, but it may be set to a different time.  By contrast, for
     * the operator==() method to return TRUE, the other Calendar must
     * be set to the same time.
     *
     * @param other the Calendar to be compared with this Calendar
     * @stable ICU 2.4
     */
    virtual UBool isEquivalentTo(const Calendar& other) const;

    /**
     * Compares the Calendar time, whereas Calendar::operator== compares the equality of
     * Calendar objects.
     *
     * @param when    The Calendar to be compared with this Calendar. Although this is a
     *                const parameter, the object may be modified physically
     *                (semantically const).
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @return        True if the current time of this Calendar is equal to the time of
     *                Calendar when; false otherwise.
     * @stable ICU 2.0
     */
    UBool equals(const Calendar& when, UErrorCode& status) const;

    /**
     * Returns true if this Calendar's current time is before "when"'s current time.
     *
     * @param when    The Calendar to be compared with this Calendar. Although this is a
     *                const parameter, the object may be modified physically
     *                (semantically const).
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @return        True if the current time of this Calendar is before the time of
     *                Calendar when; false otherwise.
     * @stable ICU 2.0
     */
    UBool before(const Calendar& when, UErrorCode& status) const;

    /**
     * Returns true if this Calendar's current time is after "when"'s current time.
     *
     * @param when    The Calendar to be compared with this Calendar. Although this is a
     *                const parameter, the object may be modified physically
     *                (semantically const).
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @return        True if the current time of this Calendar is after the time of
     *                Calendar when; false otherwise.
     * @stable ICU 2.0
     */
    UBool after(const Calendar& when, UErrorCode& status) const;

    /**
     * UDate Arithmetic function. Adds the specified (signed) amount of time to the given
     * time field, based on the calendar's rules. For example, to subtract 5 days from
     * the current time of the calendar, call add(Calendar::DATE, -5). When adding on
     * the month or Calendar::MONTH field, other fields like date might conflict and
     * need to be changed. For instance, adding 1 month on the date 01/31/96 will result
     * in 02/29/96.
     * Adding a positive value always means moving forward in time, so for the Gregorian calendar,
     * starting with 100 BC and adding +1 to year results in 99 BC (even though this actually reduces
     * the numeric value of the field itself).
     *
     * @param field   Specifies which date field to modify.
     * @param amount  The amount of time to be added to the field, in the natural unit
     *                for that field (e.g., days for the day fields, hours for the hour
     *                field.)
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @deprecated ICU 2.6. use add(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
     */
    virtual void add(EDateFields field, int32_t amount, UErrorCode& status);

    /**
     * UDate Arithmetic function. Adds the specified (signed) amount of time to the given
     * time field, based on the calendar's rules. For example, to subtract 5 days from
     * the current time of the calendar, call add(Calendar::DATE, -5). When adding on
     * the month or Calendar::MONTH field, other fields like date might conflict and
     * need to be changed. For instance, adding 1 month on the date 01/31/96 will result
     * in 02/29/96.
     * Adding a positive value always means moving forward in time, so for the Gregorian calendar,
     * starting with 100 BC and adding +1 to year results in 99 BC (even though this actually reduces
     * the numeric value of the field itself).
     *
     * @param field   Specifies which date field to modify.
     * @param amount  The amount of time to be added to the field, in the natural unit
     *                for that field (e.g., days for the day fields, hours for the hour
     *                field.)
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.6.
     */
    virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode& status);

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Time Field Rolling function. Rolls (up/down) a single unit of time on the given
     * time field. For example, to roll the current date up by one day, call
     * roll(Calendar::DATE, true). When rolling on the year or Calendar::YEAR field, it
     * will roll the year value in the range between getMinimum(Calendar::YEAR) and the
     * value returned by getMaximum(Calendar::YEAR). When rolling on the month or
     * Calendar::MONTH field, other fields like date might conflict and, need to be
     * changed. For instance, rolling the month up on the date 01/31/96 will result in
     * 02/29/96. Rolling up always means rolling forward in time (unless the limit of the
     * field is reached, in which case it may pin or wrap), so for Gregorian calendar,
     * starting with 100 BC and rolling the year up results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch).
     * When rolling on the hour-in-day or Calendar::HOUR_OF_DAY field, it will roll the
     * hour value in the range between 0 and 23, which is zero-based.
     * <P>
     * NOTE: Do not use this method -- use roll(EDateFields, int, UErrorCode&) instead.
     *
     * @param field   The time field.
     * @param up      Indicates if the value of the specified time field is to be rolled
     *                up or rolled down. Use true if rolling up, false otherwise.
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, UBool up, UErrorCode& status) instead.
     */
    inline void roll(EDateFields field, UBool up, UErrorCode& status);
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Time Field Rolling function. Rolls (up/down) a single unit of time on the given
     * time field. For example, to roll the current date up by one day, call
     * roll(Calendar::DATE, true). When rolling on the year or Calendar::YEAR field, it
     * will roll the year value in the range between getMinimum(Calendar::YEAR) and the
     * value returned by getMaximum(Calendar::YEAR). When rolling on the month or
     * Calendar::MONTH field, other fields like date might conflict and, need to be
     * changed. For instance, rolling the month up on the date 01/31/96 will result in
     * 02/29/96. Rolling up always means rolling forward in time (unless the limit of the
     * field is reached, in which case it may pin or wrap), so for Gregorian calendar,
     * starting with 100 BC and rolling the year up results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch).
     * When rolling on the hour-in-day or Calendar::HOUR_OF_DAY field, it will roll the
     * hour value in the range between 0 and 23, which is zero-based.
     * <P>
     * NOTE: Do not use this method -- use roll(UCalendarDateFields, int, UErrorCode&) instead.
     *
     * @param field   The time field.
     * @param up      Indicates if the value of the specified time field is to be rolled
     *                up or rolled down. Use true if rolling up, false otherwise.
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.6.
     */
    inline void roll(UCalendarDateFields field, UBool up, UErrorCode& status);

    /**
     * Time Field Rolling function. Rolls by the given amount on the given
     * time field. For example, to roll the current date up by one day, call
     * roll(Calendar::DATE, +1, status). When rolling on the month or
     * Calendar::MONTH field, other fields like date might conflict and, need to be
     * changed. For instance, rolling the month up on the date 01/31/96 will result in
     * 02/29/96. Rolling by a positive value always means rolling forward in time (unless
     * the limit of the field is reached, in which case it may pin or wrap), so for
     * Gregorian calendar, starting with 100 BC and rolling the year by + 1 results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch).
     * When rolling on the hour-in-day or Calendar::HOUR_OF_DAY field, it will roll the
     * hour value in the range between 0 and 23, which is zero-based.
     * <P>
     * The only difference between roll() and add() is that roll() does not change
     * the value of more significant fields when it reaches the minimum or maximum
     * of its range, whereas add() does.
     *
     * @param field   The time field.
     * @param amount  Indicates amount to roll.
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid, this will be set to
     *                an error status.
     * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
     */
    virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);

    /**
     * Time Field Rolling function. Rolls by the given amount on the given
     * time field. For example, to roll the current date up by one day, call
     * roll(Calendar::DATE, +1, status). When rolling on the month or
     * Calendar::MONTH field, other fields like date might conflict and, need to be
     * changed. For instance, rolling the month up on the date 01/31/96 will result in
     * 02/29/96. Rolling by a positive value always means rolling forward in time (unless
     * the limit of the field is reached, in which case it may pin or wrap), so for
     * Gregorian calendar, starting with 100 BC and rolling the year by + 1 results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch).
     * When rolling on the hour-in-day or Calendar::HOUR_OF_DAY field, it will roll the
     * hour value in the range between 0 and 23, which is zero-based.
     * <P>
     * The only difference between roll() and add() is that roll() does not change
     * the value of more significant fields when it reaches the minimum or maximum
     * of its range, whereas add() does.
     *
     * @param field   The time field.
     * @param amount  Indicates amount to roll.
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid, this will be set to
     *                an error status.
     * @stable ICU 2.6.
     */
    virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status);

    /**
     * Return the difference between the given time and the time this
     * calendar object is set to.  If this calendar is set
     * <em>before</em> the given time, the returned value will be
     * positive.  If this calendar is set <em>after</em> the given
     * time, the returned value will be negative.  The
     * <code>field</code> parameter specifies the units of the return
     * value.  For example, if <code>fieldDifference(when,
     * Calendar::MONTH)</code> returns 3, then this calendar is set to
     * 3 months before <code>when</code>, and possibly some addition
     * time less than one month.
     *
     * <p>As a side effect of this call, this calendar is advanced
     * toward <code>when</code> by the given amount.  That is, calling
     * this method has the side effect of calling <code>add(field,
     * n)</code>, where <code>n</code> is the return value.
     *
     * <p>Usage: To use this method, call it first with the largest
     * field of interest, then with progressively smaller fields.  For
     * example:
     *
     * <pre>
     * int y = cal->fieldDifference(when, Calendar::YEAR, err);
     * int m = cal->fieldDifference(when, Calendar::MONTH, err);
     * int d = cal->fieldDifference(when, Calendar::DATE, err);</pre>
     *
     * computes the difference between <code>cal</code> and
     * <code>when</code> in years, months, and days.
     *
     * <p>Note: <code>fieldDifference()</code> is
     * <em>asymmetrical</em>.  That is, in the following code:
     *
     * <pre>
     * cal->setTime(date1, err);
     * int m1 = cal->fieldDifference(date2, Calendar::MONTH, err);
     * int d1 = cal->fieldDifference(date2, Calendar::DATE, err);
     * cal->setTime(date2, err);
     * int m2 = cal->fieldDifference(date1, Calendar::MONTH, err);
     * int d2 = cal->fieldDifference(date1, Calendar::DATE, err);</pre>
     *
     * one might expect that <code>m1 == -m2 && d1 == -d2</code>.
     * However, this is not generally the case, because of
     * irregularities in the underlying calendar system (e.g., the
     * Gregorian calendar has a varying number of days per month).
     *
     * @param when the date to compare this calendar's time to
     * @param field the field in which to compute the result
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid, this will be set to
     *                an error status.
     * @return the difference, either positive or negative, between
     * this calendar's time and <code>when</code>, in terms of
     * <code>field</code>.
     * @deprecated ICU 2.6. Use fieldDifference(UDate when, UCalendarDateFields field, UErrorCode& status).
     */
    virtual int32_t fieldDifference(UDate when, EDateFields field, UErrorCode& status);

    /**
     * Return the difference between the given time and the time this
     * calendar object is set to.  If this calendar is set
     * <em>before</em> the given time, the returned value will be
     * positive.  If this calendar is set <em>after</em> the given
     * time, the returned value will be negative.  The
     * <code>field</code> parameter specifies the units of the return
     * value.  For example, if <code>fieldDifference(when,
     * Calendar::MONTH)</code> returns 3, then this calendar is set to
     * 3 months before <code>when</code>, and possibly some addition
     * time less than one month.
     *
     * <p>As a side effect of this call, this calendar is advanced
     * toward <code>when</code> by the given amount.  That is, calling
     * this method has the side effect of calling <code>add(field,
     * n)</code>, where <code>n</code> is the return value.
     *
     * <p>Usage: To use this method, call it first with the largest
     * field of interest, then with progressively smaller fields.  For
     * example:
     *
     * <pre>
     * int y = cal->fieldDifference(when, Calendar::YEAR, err);
     * int m = cal->fieldDifference(when, Calendar::MONTH, err);
     * int d = cal->fieldDifference(when, Calendar::DATE, err);</pre>
     *
     * computes the difference between <code>cal</code> and
     * <code>when</code> in years, months, and days.
     *
     * <p>Note: <code>fieldDifference()</code> is
     * <em>asymmetrical</em>.  That is, in the following code:
     *
     * <pre>
     * cal->setTime(date1, err);
     * int m1 = cal->fieldDifference(date2, Calendar::MONTH, err);
     * int d1 = cal->fieldDifference(date2, Calendar::DATE, err);
     * cal->setTime(date2, err);
     * int m2 = cal->fieldDifference(date1, Calendar::MONTH, err);
     * int d2 = cal->fieldDifference(date1, Calendar::DATE, err);</pre>
     *
     * one might expect that <code>m1 == -m2 && d1 == -d2</code>.
     * However, this is not generally the case, because of
     * irregularities in the underlying calendar system (e.g., the
     * Gregorian calendar has a varying number of days per month).
     *
     * @param when the date to compare this calendar's time to
     * @param field the field in which to compute the result
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid, this will be set to
     *                an error status.
     * @return the difference, either positive or negative, between
     * this calendar's time and <code>when</code>, in terms of
     * <code>field</code>.
     * @stable ICU 2.6.
     */
    virtual int32_t fieldDifference(UDate when, UCalendarDateFields field, UErrorCode& status);

    /**
     * Sets the calendar's time zone to be the one passed in. The Calendar takes ownership
     * of the TimeZone; the caller is no longer responsible for deleting it.  If the
     * given time zone is NULL, this function has no effect.
     *
     * @param value  The given time zone.
     * @stable ICU 2.0
     */
    void adoptTimeZone(TimeZone* value);

    /**
     * Sets the calendar's time zone to be the same as the one passed in. The TimeZone
     * passed in is _not_ adopted; the client is still responsible for deleting it.
     *
     * @param zone  The given time zone.
     * @stable ICU 2.0
     */
    void setTimeZone(const TimeZone& zone);

    /**
     * Returns a reference to the time zone owned by this calendar. The returned reference
     * is only valid until clients make another call to adoptTimeZone or setTimeZone,
     * or this Calendar is destroyed.
     *
     * @return   The time zone object associated with this calendar.
     * @stable ICU 2.0
     */
    const TimeZone& getTimeZone(void) const;

    /**
     * Returns the time zone owned by this calendar. The caller owns the returned object
     * and must delete it when done.  After this call, the new time zone associated
     * with this Calendar is the default TimeZone as returned by TimeZone::createDefault().
     *
     * @return   The time zone object which was associated with this calendar.
     * @stable ICU 2.0
     */
    TimeZone* orphanTimeZone(void);

    /**
     * Queries if the current date for this Calendar is in Daylight Savings Time.
     *
     * @param status Fill-in parameter which receives the status of this operation.
     * @return   True if the current date for this Calendar is in Daylight Savings Time,
     *           false, otherwise.
     * @stable ICU 2.0
     */
    virtual UBool inDaylightTime(UErrorCode& status) const = 0;

    /**
     * Specifies whether or not date/time interpretation is to be lenient. With lenient
     * interpretation, a date such as "February 942, 1996" will be treated as being
     * equivalent to the 941st day after February 1, 1996. With strict interpretation,
     * such dates will cause an error when computing time from the time field values
     * representing the dates.
     *
     * @param lenient  True specifies date/time interpretation to be lenient.
     *
     * @see            DateFormat#setLenient
     * @stable ICU 2.0
     */
    void setLenient(UBool lenient);

    /**
     * Tells whether date/time interpretation is to be lenient.
     *
     * @return   True tells that date/time interpretation is to be lenient.
     * @stable ICU 2.0
     */
    UBool isLenient(void) const;

    /**
     * Sets the behavior for handling wall time repeating multiple times
     * at negative time zone offset transitions. For example, 1:30 AM on
     * November 6, 2011 in US Eastern time (America/New_York) occurs twice;
     * 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>UCAL_WALLTIME_FIRST</code>
     * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
     * (first occurrence). When <code>UCAL_WALLTIME_LAST</code> is used, it will be
     * interpreted as 1:30 AM EST (last occurrence). The default value is
     * <code>UCAL_WALLTIME_LAST</code>.
     * <p>
     * <b>Note:</b>When <code>UCAL_WALLTIME_NEXT_VALID</code> is not a valid
     * option for this. When the argument is neither <code>UCAL_WALLTIME_FIRST</code>
     * nor <code>UCAL_WALLTIME_LAST</code>, this method has no effect and will keep
     * the current setting.
     *
     * @param option the behavior for handling repeating wall time, either
     * <code>UCAL_WALLTIME_FIRST</code> or <code>UCAL_WALLTIME_LAST</code>.
     * @see #getRepeatedWallTimeOption
     * @stable ICU 49
     */
    void setRepeatedWallTimeOption(UCalendarWallTimeOption option);

    /**
     * Gets the behavior for handling wall time repeating multiple times
     * at negative time zone offset transitions.
     *
     * @return the behavior for handling repeating wall time, either
     * <code>UCAL_WALLTIME_FIRST</code> or <code>UCAL_WALLTIME_LAST</code>.
     * @see #setRepeatedWallTimeOption
     * @stable ICU 49
     */
    UCalendarWallTimeOption getRepeatedWallTimeOption(void) const;

    /**
     * Sets the behavior for handling skipped wall time at positive time zone offset
     * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York)
     * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When
     * <code>UCAL_WALLTIME_FIRST</code> is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM
     * EDT, therefore, it will be resolved as 1:30 AM EST. When <code>UCAL_WALLTIME_LAST</code>
     * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be
     * resolved as 3:30 AM EDT. When <code>UCAL_WALLTIME_NEXT_VALID</code> is used, 2:30 AM will
     * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is
     * <code>UCAL_WALLTIME_LAST</code>.
     * <p>
     * <b>Note:</b>This option is effective only when this calendar is lenient.
     * When the calendar is strict, such non-existing wall time will cause an error.
     *
     * @param option the behavior for handling skipped wall time at positive time zone
     * offset transitions, one of <code>UCAL_WALLTIME_FIRST</code>, <code>UCAL_WALLTIME_LAST</code> and
     * <code>UCAL_WALLTIME_NEXT_VALID</code>.
     * @see #getSkippedWallTimeOption
     *
     * @stable ICU 49
     */
    void setSkippedWallTimeOption(UCalendarWallTimeOption option);

    /**
     * Gets the behavior for handling skipped wall time at positive time zone offset
     * transitions.
     *
     * @return the behavior for handling skipped wall time, one of
     * <code>UCAL_WALLTIME_FIRST</code>, <code>UCAL_WALLTIME_LAST</code>
     * and <code>UCAL_WALLTIME_NEXT_VALID</code>.
     * @see #setSkippedWallTimeOption
     * @stable ICU 49
     */
    UCalendarWallTimeOption getSkippedWallTimeOption(void) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Sets what the first day of the week is; e.g., Sunday in US, Monday in France.
     *
     * @param value  The given first day of the week.
     * @deprecated ICU 2.6. Use setFirstDayOfWeek(UCalendarDaysOfWeek value) instead.
     */
    void setFirstDayOfWeek(EDaysOfWeek value);
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Sets what the first day of the week is; e.g., Sunday in US, Monday in France.
     *
     * @param value  The given first day of the week.
     * @stable ICU 2.6.
     */
    void setFirstDayOfWeek(UCalendarDaysOfWeek value);

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Gets what the first day of the week is; e.g., Sunday in US, Monday in France.
     *
     * @return   The first day of the week.
     * @deprecated ICU 2.6 use the overload with error code
     */
    EDaysOfWeek getFirstDayOfWeek(void) const;
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Gets what the first day of the week is; e.g., Sunday in US, Monday in France.
     *
     * @param status error code
     * @return   The first day of the week.
     * @stable ICU 2.6
     */
    UCalendarDaysOfWeek getFirstDayOfWeek(UErrorCode &status) const;

    /**
     * Sets what the minimal days required in the first week of the year are; For
     * example, if the first week is defined as one that contains the first day of the
     * first month of a year, call the method with value 1. If it must be a full week,
     * use value 7.
     *
     * @param value  The given minimal days required in the first week of the year.
     * @stable ICU 2.0
     */
    void setMinimalDaysInFirstWeek(uint8_t value);

    /**
     * Gets what the minimal days required in the first week of the year are; e.g., if
     * the first week is defined as one that contains the first day of the first month
     * of a year, getMinimalDaysInFirstWeek returns 1. If the minimal days required must
     * be a full week, getMinimalDaysInFirstWeek returns 7.
     *
     * @return   The minimal days required in the first week of the year.
     * @stable ICU 2.0
     */
    uint8_t getMinimalDaysInFirstWeek(void) const;

    /**
     * Gets the minimum value for the given time field. e.g., for Gregorian
     * DAY_OF_MONTH, 1.
     *
     * @param field  The given time field.
     * @return       The minimum value for the given time field.
     * @deprecated ICU 2.6. Use getMinimum(UCalendarDateFields field) instead.
     */
    virtual int32_t getMinimum(EDateFields field) const;

    /**
     * Gets the minimum value for the given time field. e.g., for Gregorian
     * DAY_OF_MONTH, 1.
     *
     * @param field  The given time field.
     * @return       The minimum value for the given time field.
     * @stable ICU 2.6.
     */
    virtual int32_t getMinimum(UCalendarDateFields field) const;

    /**
     * Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH,
     * 31.
     *
     * @param field  The given time field.
     * @return       The maximum value for the given time field.
     * @deprecated ICU 2.6. Use getMaximum(UCalendarDateFields field) instead.
     */
    virtual int32_t getMaximum(EDateFields field) const;

    /**
     * Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH,
     * 31.
     *
     * @param field  The given time field.
     * @return       The maximum value for the given time field.
     * @stable ICU 2.6.
     */
    virtual int32_t getMaximum(UCalendarDateFields field) const;

    /**
     * Gets the highest minimum value for the given field if varies. Otherwise same as
     * getMinimum(). For Gregorian, no difference.
     *
     * @param field  The given time field.
     * @return       The highest minimum value for the given time field.
     * @deprecated ICU 2.6. Use getGreatestMinimum(UCalendarDateFields field) instead.
     */
    virtual int32_t getGreatestMinimum(EDateFields field) const;

    /**
     * Gets the highest minimum value for the given field if varies. Otherwise same as
     * getMinimum(). For Gregorian, no difference.
     *
     * @param field  The given time field.
     * @return       The highest minimum value for the given time field.
     * @stable ICU 2.6.
     */
    virtual int32_t getGreatestMinimum(UCalendarDateFields field) const;

    /**
     * Gets the lowest maximum value for the given field if varies. Otherwise same as
     * getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
     *
     * @param field  The given time field.
     * @return       The lowest maximum value for the given time field.
     * @deprecated ICU 2.6. Use getLeastMaximum(UCalendarDateFields field) instead.
     */
    virtual int32_t getLeastMaximum(EDateFields field) const;

    /**
     * Gets the lowest maximum value for the given field if varies. Otherwise same as
     * getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
     *
     * @param field  The given time field.
     * @return       The lowest maximum value for the given time field.
     * @stable ICU 2.6.
     */
    virtual int32_t getLeastMaximum(UCalendarDateFields field) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Return the minimum value that this field could have, given the current date.
     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
     *
     * The version of this function on Calendar uses an iterative algorithm to determine the
     * actual minimum value for the field.  There is almost always a more efficient way to
     * accomplish this (in most cases, you can simply return getMinimum()).  GregorianCalendar
     * overrides this function with a more efficient implementation.
     *
     * @param field    the field to determine the minimum of
     * @param status   Fill-in parameter which receives the status of this operation.
     * @return         the minimum of the given field for the current date of this Calendar
     * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field, UErrorCode& status) instead.
     */
    int32_t getActualMinimum(EDateFields field, UErrorCode& status) const;
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Return the minimum value that this field could have, given the current date.
     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
     *
     * The version of this function on Calendar uses an iterative algorithm to determine the
     * actual minimum value for the field.  There is almost always a more efficient way to
     * accomplish this (in most cases, you can simply return getMinimum()).  GregorianCalendar
     * overrides this function with a more efficient implementation.
     *
     * @param field    the field to determine the minimum of
     * @param status   Fill-in parameter which receives the status of this operation.
     * @return         the minimum of the given field for the current date of this Calendar
     * @stable ICU 2.6.
     */
    virtual int32_t getActualMinimum(UCalendarDateFields field, UErrorCode& status) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Return the maximum value that this field could have, given the current date.
     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
     * for some years the actual maximum for MONTH is 12, and for others 13.
     *
     * The version of this function on Calendar uses an iterative algorithm to determine the
     * actual maximum value for the field.  There is almost always a more efficient way to
     * accomplish this (in most cases, you can simply return getMaximum()).  GregorianCalendar
     * overrides this function with a more efficient implementation.
     *
     * @param field    the field to determine the maximum of
     * @param status   Fill-in parameter which receives the status of this operation.
     * @return         the maximum of the given field for the current date of this Calendar
     * @deprecated ICU 2.6. Use getActualMaximum(UCalendarDateFields field, UErrorCode& status) instead.
     */
    int32_t getActualMaximum(EDateFields field, UErrorCode& status) const;
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Return the maximum value that this field could have, given the current date.
     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
     * for some years the actual maximum for MONTH is 12, and for others 13.
     *
     * The version of this function on Calendar uses an iterative algorithm to determine the
     * actual maximum value for the field.  There is almost always a more efficient way to
     * accomplish this (in most cases, you can simply return getMaximum()).  GregorianCalendar
     * overrides this function with a more efficient implementation.
     *
     * @param field    the field to determine the maximum of
     * @param status   Fill-in parameter which receives the status of this operation.
     * @return         the maximum of the given field for the current date of this Calendar
     * @stable ICU 2.6.
     */
    virtual int32_t getActualMaximum(UCalendarDateFields field, UErrorCode& status) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Gets the value for a given time field. Recalculate the current time field values
     * if the time value has been changed by a call to setTime(). Return zero for unset
     * fields if any fields have been explicitly set by a call to set(). To force a
     * recomputation of all fields regardless of the previous state, call complete().
     * This method is semantically const, but may alter the object in memory.
     *
     * @param field  The given time field.
     * @param status Fill-in parameter which receives the status of the operation.
     * @return       The value for the given time field, or zero if the field is unset,
     *               and set() has been called for any other field.
     * @deprecated ICU 2.6. Use get(UCalendarDateFields field, UErrorCode& status) instead.
     */
    int32_t get(EDateFields field, UErrorCode& status) const;
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Gets the value for a given time field. Recalculate the current time field values
     * if the time value has been changed by a call to setTime(). Return zero for unset
     * fields if any fields have been explicitly set by a call to set(). To force a
     * recomputation of all fields regardless of the previous state, call complete().
     * This method is semantically const, but may alter the object in memory.
     *
     * @param field  The given time field.
     * @param status Fill-in parameter which receives the status of the operation.
     * @return       The value for the given time field, or zero if the field is unset,
     *               and set() has been called for any other field.
     * @stable ICU 2.6.
     */
    int32_t get(UCalendarDateFields field, UErrorCode& status) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Determines if the given time field has a value set. This can affect in the
     * resolving of time in Calendar. Unset fields have a value of zero, by definition.
     *
     * @param field  The given time field.
     * @return   True if the given time field has a value set; false otherwise.
     * @deprecated ICU 2.6. Use isSet(UCalendarDateFields field) instead.
     */
    UBool isSet(EDateFields field) const;
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Determines if the given time field has a value set. This can affect in the
     * resolving of time in Calendar. Unset fields have a value of zero, by definition.
     *
     * @param field  The given time field.
     * @return   True if the given time field has a value set; false otherwise.
     * @stable ICU 2.6.
     */
    UBool isSet(UCalendarDateFields field) const;

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Sets the given time field with the given value.
     *
     * @param field  The given time field.
     * @param value  The value to be set for the given time field.
     * @deprecated ICU 2.6. Use set(UCalendarDateFields field, int32_t value) instead.
     */
    void set(EDateFields field, int32_t value);
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Sets the given time field with the given value.
     *
     * @param field  The given time field.
     * @param value  The value to be set for the given time field.
     * @stable ICU 2.6.
     */
    void set(UCalendarDateFields field, int32_t value);

    /**
     * Sets the values for the fields YEAR, MONTH, and DATE. Other field values are
     * retained; call clear() first if this is not desired.
     *
     * @param year   The value used to set the YEAR time field.
     * @param month  The value used to set the MONTH time field. Month value is 0-based.
     *               e.g., 0 for January.
     * @param date   The value used to set the DATE time field.
     * @stable ICU 2.0
     */
    void set(int32_t year, int32_t month, int32_t date);

    /**
     * Sets the values for the fields YEAR, MONTH, DATE, HOUR_OF_DAY, and MINUTE. Other
     * field values are retained; call clear() first if this is not desired.
     *
     * @param year    The value used to set the YEAR time field.
     * @param month   The value used to set the MONTH time field. Month value is
     *                0-based. E.g., 0 for January.
     * @param date    The value used to set the DATE time field.
     * @param hour    The value used to set the HOUR_OF_DAY time field.
     * @param minute  The value used to set the MINUTE time field.
     * @stable ICU 2.0
     */
    void set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute);

    /**
     * Sets the values for the fields YEAR, MONTH, DATE, HOUR_OF_DAY, MINUTE, and SECOND.
     * Other field values are retained; call clear() first if this is not desired.
     *
     * @param year    The value used to set the YEAR time field.
     * @param month   The value used to set the MONTH time field. Month value is
     *                0-based. E.g., 0 for January.
     * @param date    The value used to set the DATE time field.
     * @param hour    The value used to set the HOUR_OF_DAY time field.
     * @param minute  The value used to set the MINUTE time field.
     * @param second  The value used to set the SECOND time field.
     * @stable ICU 2.0
     */
    void set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second);

    /**
     * Clears the values of all the time fields, making them both unset and assigning
     * them a value of zero. The field values will be determined during the next
     * resolving of time into time fields.
     * @stable ICU 2.0
     */
    void clear(void);

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Clears the value in the given time field, both making it unset and assigning it a
     * value of zero. This field value will be determined during the next resolving of
     * time into time fields.
     *
     * @param field  The time field to be cleared.
     * @deprecated ICU 2.6. Use clear(UCalendarDateFields field) instead.
     */
    void clear(EDateFields field);
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Clears the value in the given time field, both making it unset and assigning it a
     * value of zero. This field value will be determined during the next resolving of
     * time into time fields.
     *
     * @param field  The time field to be cleared.
     * @stable ICU 2.6.
     */
    void clear(UCalendarDateFields field);

    /**
     * Returns a unique class ID POLYMORPHICALLY. Pure virtual method. This method is to
     * implement a simple version of RTTI, since not all C++ compilers support genuine
     * RTTI. Polymorphic operator==() and clone() methods call this method.
     * <P>
     * Concrete subclasses of Calendar must implement getDynamicClassID() and also a
     * static method and data member:
     *
     *      static UClassID getStaticClassID() { return (UClassID)&amp;fgClassID; }
     *      static char fgClassID;
     *
     * @return   The class ID for this object. All objects of a given class have the
     *           same class ID. Objects of other classes have different class IDs.
     * @stable ICU 2.0
     */
    virtual UClassID getDynamicClassID(void) const = 0;

    /**
     * Returns the calendar type name string for this Calendar object.
     * The returned string is the legacy ICU calendar attribute value,
     * for example, "gregorian" or "japanese".
     *
     * See type="old type name" for the calendar attribute of locale IDs
     * at http://www.unicode.org/reports/tr35/#Key_Type_Definitions
     *
     * Sample code for getting the LDML/BCP 47 calendar key value:
     * \code
     * const char *calType = cal->getType();
     * if (0 == strcmp(calType, "unknown")) {
     *     // deal with unknown calendar type
     * } else {
     *     string localeID("root@calendar=");
     *     localeID.append(calType);
     *     char langTag[100];
     *     UErrorCode errorCode = U_ZERO_ERROR;
     *     int32_t length = uloc_toLanguageTag(localeID.c_str(), langTag, (int32_t)sizeof(langTag), TRUE, &errorCode);
     *     if (U_FAILURE(errorCode)) {
     *         // deal with errors & overflow
     *     }
     *     string lang(langTag, length);
     *     size_t caPos = lang.find("-ca-");
     *     lang.erase(0, caPos + 4);
     *     // lang now contains the LDML calendar type
     * }
     * \endcode
     *
     * @return legacy calendar type name string
     * @stable ICU 49
     */
    virtual const char * getType() const = 0;

    /**
     * Returns whether the given day of the week is a weekday, a weekend day,
     * or a day that transitions from one to the other, for the locale and
     * calendar system associated with this Calendar (the locale's region is
     * often the most determinant factor). If a transition occurs at midnight,
     * then the days before and after the transition will have the
     * type UCAL_WEEKDAY or UCAL_WEEKEND. If a transition occurs at a time
     * other than midnight, then the day of the transition will have
     * the type UCAL_WEEKEND_ONSET or UCAL_WEEKEND_CEASE. In this case, the
     * method getWeekendTransition() will return the point of
     * transition.
     * @param dayOfWeek The day of the week whose type is desired (UCAL_SUNDAY..UCAL_SATURDAY).
     * @param status The error code for the operation.
     * @return The UCalendarWeekdayType for the day of the week.
     * @stable ICU 4.4
     */
    virtual UCalendarWeekdayType getDayOfWeekType(UCalendarDaysOfWeek dayOfWeek, UErrorCode &status) const;

    /**
     * Returns the time during the day at which the weekend begins or ends in
     * this calendar system.  If getDayOfWeekType() returns UCAL_WEEKEND_ONSET
     * for the specified dayOfWeek, return the time at which the weekend begins.
     * If getDayOfWeekType() returns UCAL_WEEKEND_CEASE for the specified dayOfWeek,
     * return the time at which the weekend ends. If getDayOfWeekType() returns
     * some other UCalendarWeekdayType for the specified dayOfWeek, is it an error condition
     * (U_ILLEGAL_ARGUMENT_ERROR).
     * @param dayOfWeek The day of the week for which the weekend transition time is
     * desired (UCAL_SUNDAY..UCAL_SATURDAY).
     * @param status The error code for the operation.
     * @return The milliseconds after midnight at which the weekend begins or ends.
     * @stable ICU 4.4
     */
    virtual int32_t getWeekendTransition(UCalendarDaysOfWeek dayOfWeek, UErrorCode &status) const;

    /**
     * Returns TRUE if the given UDate is in the weekend in
     * this calendar system.
     * @param date The UDate in question.
     * @param status The error code for the operation.
     * @return TRUE if the given UDate is in the weekend in
     * this calendar system, FALSE otherwise.
     * @stable ICU 4.4
     */
    virtual UBool isWeekend(UDate date, UErrorCode &status) const;

    /**
     * Returns TRUE if this Calendar's current date-time is in the weekend in
     * this calendar system.
     * @return TRUE if this Calendar's current date-time is in the weekend in
     * this calendar system, FALSE otherwise.
     * @stable ICU 4.4
     */
    virtual UBool isWeekend(void) const;

protected:

     /**
      * Constructs a Calendar with the default time zone as returned by
      * TimeZone::createInstance(), and the default locale.
      *
      * @param success  Indicates the status of Calendar object construction. Returns
      *                 U_ZERO_ERROR if constructed successfully.
     * @stable ICU 2.0
      */
    Calendar(UErrorCode& success);

    /**
     * Copy constructor
     *
     * @param source    Calendar object to be copied from
     * @stable ICU 2.0
     */
    Calendar(const Calendar& source);

    /**
     * Default assignment operator
     *
     * @param right    Calendar object to be copied
     * @stable ICU 2.0
     */
    Calendar& operator=(const Calendar& right);

    /**
     * Constructs a Calendar with the given time zone and locale. Clients are no longer
     * responsible for deleting the given time zone object after it's adopted.
     *
     * @param zone     The given time zone.
     * @param aLocale  The given locale.
     * @param success  Indicates the status of Calendar object construction. Returns
     *                 U_ZERO_ERROR if constructed successfully.
     * @stable ICU 2.0
     */
    Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success);

    /**
     * Constructs a Calendar with the given time zone and locale.
     *
     * @param zone     The given time zone.
     * @param aLocale  The given locale.
     * @param success  Indicates the status of Calendar object construction. Returns
     *                 U_ZERO_ERROR if constructed successfully.
     * @stable ICU 2.0
     */
    Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success);

    /**
     * Converts Calendar's time field values to GMT as milliseconds.
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.0
     */
    virtual void computeTime(UErrorCode& status);

    /**
     * Converts GMT as milliseconds to time field values. This allows you to sync up the
     * time field values with a new time that is set for the calendar.  This method
     * does NOT recompute the time first; to recompute the time, then the fields, use
     * the method complete().
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.0
     */
    virtual void computeFields(UErrorCode& status);

    /**
     * Gets this Calendar's current time as a long.
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @return the current time as UTC milliseconds from the epoch.
     * @stable ICU 2.0
     */
    double getTimeInMillis(UErrorCode& status) const;

    /**
     * Sets this Calendar's current time from the given long value.
     * @param millis  the new time in UTC milliseconds from the epoch.
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.0
     */
    void setTimeInMillis( double millis, UErrorCode& status );

    /**
     * Recomputes the current time from currently set fields, and then fills in any
     * unset fields in the time field list.
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     * @stable ICU 2.0
     */
    void complete(UErrorCode& status);

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Gets the value for a given time field. Subclasses can use this function to get
     * field values without forcing recomputation of time.
     *
     * @param field  The given time field.
     * @return       The value for the given time field.
     * @deprecated ICU 2.6. Use internalGet(UCalendarDateFields field) instead.
     */
    inline int32_t internalGet(EDateFields field) const {return fFields[field];}
#endif  /* U_HIDE_DEPRECATED_API */

#ifndef U_HIDE_INTERNAL_API
    /**
     * Gets the value for a given time field. Subclasses can use this function to get
     * field values without forcing recomputation of time. If the field's stamp is UNSET,
     * the defaultValue is used.
     *
     * @param field  The given time field.
     * @param defaultValue a default value used if the field is unset.
     * @return       The value for the given time field.
     * @internal
     */
    inline int32_t internalGet(UCalendarDateFields field, int32_t defaultValue) const {return fStamp[field]>kUnset ? fFields[field] : defaultValue;}

    /**
     * Gets the value for a given time field. Subclasses can use this function to get
     * field values without forcing recomputation of time.
     *
     * @param field  The given time field.
     * @return       The value for the given time field.
     * @internal
     */
    inline int32_t internalGet(UCalendarDateFields field) const {return fFields[field];}
#endif  /* U_HIDE_INTERNAL_API */

#ifndef U_HIDE_DEPRECATED_API
    /**
     * Sets the value for a given time field.  This is a fast internal method for
     * subclasses.  It does not affect the areFieldsInSync, isTimeSet, or areAllFieldsSet
     * flags.
     *
     * @param field    The given time field.
     * @param value    The value for the given time field.
     * @deprecated ICU 2.6. Use internalSet(UCalendarDateFields field, int32_t value) instead.
     */
    void internalSet(EDateFields field, int32_t value);
#endif  /* U_HIDE_DEPRECATED_API */

    /**
     * Sets the value for a given time field.  This is a fast internal method for
     * subclasses.  It does not affect the areFieldsInSync, isTimeSet, or areAllFieldsSet
     * flags.
     *
     * @param field    The given time field.
     * @param value    The value for the given time field.
     * @stable ICU 2.6.
     */
    inline void internalSet(UCalendarDateFields field, int32_t value);

    /**
     * Prepare this calendar for computing the actual minimum or maximum.
     * This method modifies this calendar's fields; it is called on a
     * temporary calendar.
     * @internal
     */
    virtual void prepareGetActual(UCalendarDateFields field, UBool isMinimum, UErrorCode &status);

    /**
     * Limit enums. Not in sync with UCalendarLimitType (refers to internal fields).
     * @internal
     */
    enum ELimitType {
#ifndef U_HIDE_INTERNAL_API
      UCAL_LIMIT_MINIMUM = 0,
      UCAL_LIMIT_GREATEST_MINIMUM,
      UCAL_LIMIT_LEAST_MAXIMUM,
      UCAL_LIMIT_MAXIMUM,
      UCAL_LIMIT_COUNT
#endif  /* U_HIDE_INTERNAL_API */
    };

    /**
     * Subclass API for defining limits of different types.
     * Subclasses must implement this method to return limits for the
     * following fields:
     *
     * <pre>UCAL_ERA
     * UCAL_YEAR
     * UCAL_MONTH
     * UCAL_WEEK_OF_YEAR
     * UCAL_WEEK_OF_MONTH
     * UCAL_DATE (DAY_OF_MONTH on Java)
     * UCAL_DAY_OF_YEAR
     * UCAL_DAY_OF_WEEK_IN_MONTH
     * UCAL_YEAR_WOY
     * UCAL_EXTENDED_YEAR</pre>
     *
     * @param field one of the above field numbers
     * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
     * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
     * @internal
     */
    virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const = 0;

    /**
     * Return a limit for a field.
     * @param field the field, from <code>0..UCAL_MAX_FIELD</code>
     * @param limitType the type specifier for the limit
     * @see #ELimitType
     * @internal
     */
    virtual int32_t getLimit(UCalendarDateFields field, ELimitType limitType) const;


    /**
     * Return the Julian day number of day before the first day of the
     * given month in the given extended year.  Subclasses should override
     * this method to implement their calendar system.
     * @param eyear the extended year
     * @param month the zero-based month, or 0 if useMonth is false
     * @param useMonth if false, compute the day before the first day of
     * the given year, otherwise, compute the day before the first day of
     * the given month
     * @return the Julian day number of the day before the first
     * day of the given month and year
     * @internal
     */
    virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month,
                                                   UBool useMonth) const  = 0;

    /**
     * Return the number of days in the given month of the given extended
     * year of this calendar system.  Subclasses should override this
     * method if they can provide a more correct or more efficient
     * implementation than the default implementation in Calendar.
     * @internal
     */
    virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const ;

    /**
     * Return the number of days in the given extended year of this
     * calendar system.  Subclasses should override this method if they can
     * provide a more correct or more efficient implementation than the
     * default implementation in Calendar.
     * @stable ICU 2.0
     */
    virtual int32_t handleGetYearLength(int32_t eyear) const;


    /**
     * Return the extended year defined by the current fields.  This will
     * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such
     * as UCAL_ERA) specific to the calendar system, depending on which set of
     * fields is newer.
     * @return the extended year
     * @internal
     */
    virtual int32_t handleGetExtendedYear() = 0;

    /**
     * Subclasses may override this.  This method calls
     * handleGetMonthLength() to obtain the calendar-specific month
     * length.
     * @param bestField which field to use to calculate the date
     * @return julian day specified by calendar fields.
     * @internal
     */
    virtual int32_t handleComputeJulianDay(UCalendarDateFields bestField);

    /**
     * Subclasses must override this to convert from week fields
     * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case
     * where YEAR, EXTENDED_YEAR are not set.
     * The Calendar implementation assumes yearWoy is in extended gregorian form
     * @return the extended year, UCAL_EXTENDED_YEAR
     * @internal
     */
    virtual int32_t handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy);

    /**
     * Validate a single field of this calendar.  Subclasses should
     * override this method to validate any calendar-specific fields.
     * Generic fields can be handled by `Calendar::validateField()`.
     * @internal
     */
    virtual void validateField(UCalendarDateFields field, UErrorCode &status);

#ifndef U_HIDE_INTERNAL_API
    /**
     * Compute the Julian day from fields.  Will determine whether to use
     * the JULIAN_DAY field directly, or other fields.
     * @return the julian day
     * @internal
     */
    int32_t computeJulianDay();

    /**
     * Compute the milliseconds in the day from the fields.  This is a
     * value from 0 to 23:59:59.999 inclusive, unless fields are out of
     * range, in which case it can be an arbitrary value.  This value
     * reflects local zone wall time.
     * @internal
     */
    double computeMillisInDay();

    /**
     * This method can assume EXTENDED_YEAR has been set.
     * @param millis milliseconds of the date fields
     * @param millisInDay milliseconds of the time fields; may be out
     * or range.
     * @param ec Output param set to failure code on function return
     *          when this function fails.
     * @internal
     */
    int32_t computeZoneOffset(double millis, double millisInDay, UErrorCode &ec);


    /**
     * Determine the best stamp in a range.
     * @param start first enum to look at
     * @param end last enum to look at
     * @param bestSoFar stamp prior to function call
     * @return the stamp value of the best stamp
     * @internal
     */
    int32_t newestStamp(UCalendarDateFields start, UCalendarDateFields end, int32_t bestSoFar) const;

    /**
     * Values for field resolution tables
     * @see #resolveFields
     * @internal
     */
    enum {
      /** Marker for end of resolve set (row or group). */
      kResolveSTOP = -1,
      /** Value to be bitwised "ORed" against resolve table field values for remapping.  Example: (UCAL_DATE | kResolveRemap) in 1st column will cause 'UCAL_DATE' to be returned, but will not examine the value of UCAL_DATE.  */
      kResolveRemap = 32
    };

    /**
     * Precedence table for Dates
     * @see #resolveFields
     * @internal
     */
    static const UFieldResolutionTable kDatePrecedence[];

    /**
     * Precedence table for Year
     * @see #resolveFields
     * @internal
     */
    static const UFieldResolutionTable kYearPrecedence[];

    /**
     * Precedence table for Day of Week
     * @see #resolveFields
     * @internal
     */
    static const UFieldResolutionTable kDOWPrecedence[];

    /**
     * Given a precedence table, return the newest field combination in
     * the table, or UCAL_FIELD_COUNT if none is found.
     *
     * <p>The precedence table is a 3-dimensional array of integers.  It
     * may be thought of as an array of groups.  Each group is an array of
     * lines.  Each line is an array of field numbers.  Within a line, if
     * all fields are set, then the time stamp of the line is taken to be
     * the stamp of the most recently set field.  If any field of a line is
     * unset, then the line fails to match.  Within a group, the line with
     * the newest time stamp is selected.  The first field of the line is
     * returned to indicate which line matched.
     *
     * <p>In some cases, it may be desirable to map a line to field that
     * whose stamp is NOT examined.  For example, if the best field is
     * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used.  In
     * order to do this, insert the value <code>kResolveRemap | F</code> at
     * the start of the line, where <code>F</code> is the desired return
     * field value.  This field will NOT be examined; it only determines
     * the return value if the other fields in the line are the newest.
     *
     * <p>If all lines of a group contain at least one unset field, then no
     * line will match, and the group as a whole will fail to match.  In
     * that case, the next group will be processed.  If all groups fail to
     * match, then UCAL_FIELD_COUNT is returned.
     * @internal
     */
    UCalendarDateFields resolveFields(const UFieldResolutionTable *precedenceTable);
#endif  /* U_HIDE_INTERNAL_API */


    /**
     * @internal
     */
    virtual const UFieldResolutionTable* getFieldResolutionTable() const;

#ifndef U_HIDE_INTERNAL_API
    /**
     * Return the field that is newer, either defaultField, or
     * alternateField.  If neither is newer or neither is set, return defaultField.
     * @internal
     */
    UCalendarDateFields newerField(UCalendarDateFields defaultField, UCalendarDateFields alternateField) const;
#endif  /* U_HIDE_INTERNAL_API */


private:
    /**
     * Helper function for calculating limits by trial and error
     * @param field The field being investigated
     * @param startValue starting (least max) value of field
     * @param endValue ending (greatest max) value of field
     * @param status return type
     * @internal
     */
    int32_t getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const;


protected:
    /**
     * The flag which indicates if the current time is set in the calendar.
     * @stable ICU 2.0
     */
    UBool      fIsTimeSet;

    /**
     * True if the fields are in sync with the currently set time of this Calendar.
     * If false, then the next attempt to get the value of a field will
     * force a recomputation of all fields from the current value of the time
     * field.
     * <P>
     * This should really be named areFieldsInSync, but the old name is retained
     * for backward compatibility.
     * @stable ICU 2.0
     */
    UBool      fAreFieldsSet;

    /**
     * True if all of the fields have been set.  This is initially false, and set to
     * true by computeFields().
     * @stable ICU 2.0
     */
    UBool      fAreAllFieldsSet;

    /**
     * True if all fields have been virtually set, but have not yet been
     * computed.  This occurs only in setTimeInMillis().  A calendar set
     * to this state will compute all fields from the time if it becomes
     * necessary, but otherwise will delay such computation.
     * @stable ICU 3.0
     */
    UBool fAreFieldsVirtuallySet;

    /**
     * Get the current time without recomputing.
     *
     * @return     the current time without recomputing.
     * @stable ICU 2.0
     */
    UDate        internalGetTime(void) const     { return fTime; }

    /**
     * Set the current time without affecting flags or fields.
     *
     * @param time    The time to be set
     * @return        the current time without recomputing.
     * @stable ICU 2.0
     */
    void        internalSetTime(UDate time)     { fTime = time; }

    /**
     * The time fields containing values into which the millis is computed.
     * @stable ICU 2.0
     */
    int32_t     fFields[UCAL_FIELD_COUNT];

    /**
     * The flags which tell if a specified time field for the calendar is set.
     * @deprecated ICU 2.8 use (fStamp[n]!=kUnset)
     */
    UBool      fIsSet[UCAL_FIELD_COUNT];

    /** Special values of stamp[]
     * @stable ICU 2.0
     */
    enum {
        kUnset                 = 0,
        kInternallySet,
        kMinimumUserStamp
    };

    /**
     * Pseudo-time-stamps which specify when each field was set. There
     * are two special values, UNSET and INTERNALLY_SET. Values from
     * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
     * @stable ICU 2.0
     */
    int32_t        fStamp[UCAL_FIELD_COUNT];

    /**
     * Subclasses may override this method to compute several fields
     * specific to each calendar system.  These are:
     *
     * <ul><li>ERA
     * <li>YEAR
     * <li>MONTH
     * <li>DAY_OF_MONTH
     * <li>DAY_OF_YEAR
     * <li>EXTENDED_YEAR</ul>
     *
     * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which
     * will be set when this method is called.  Subclasses can also call
     * the getGregorianXxx() methods to obtain Gregorian calendar
     * equivalents for the given Julian day.
     *
     * <p>In addition, subclasses should compute any subclass-specific
     * fields, that is, fields from BASE_FIELD_COUNT to
     * getFieldCount() - 1.
     *
     * <p>The default implementation in <code>Calendar</code> implements
     * a pure proleptic Gregorian calendar.
     * @internal
     */
    virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);

#ifndef U_HIDE_INTERNAL_API
    /**
     * Return the extended year on the Gregorian calendar as computed by
     * <code>computeGregorianFields()</code>.
     * @internal
     */
    int32_t getGregorianYear() const {
        return fGregorianYear;
    }

    /**
     * Return the month (0-based) on the Gregorian calendar as computed by
     * <code>computeGregorianFields()</code>.
     * @internal
     */
    int32_t getGregorianMonth() const {
        return fGregorianMonth;
    }

    /**
     * Return the day of year (1-based) on the Gregorian calendar as
     * computed by <code>computeGregorianFields()</code>.
     * @internal
     */
    int32_t getGregorianDayOfYear() const {
        return fGregorianDayOfYear;
    }

    /**
     * Return the day of month (1-based) on the Gregorian calendar as
     * computed by <code>computeGregorianFields()</code>.
     * @internal
     */
    int32_t getGregorianDayOfMonth() const {
      return fGregorianDayOfMonth;
    }
#endif  /* U_HIDE_INTERNAL_API */

    /**
     * Called by computeJulianDay.  Returns the default month (0-based) for the year,
     * taking year and era into account.  Defaults to 0 for Gregorian, which doesn't care.
     * @param eyear The extended year
     * @internal
     */
    virtual int32_t getDefaultMonthInYear(int32_t eyear) ;


    /**
     * Called by computeJulianDay.  Returns the default day (1-based) for the month,
     * taking currently-set year and era into account.  Defaults to 1 for Gregorian.
     * @param eyear the extended year
     * @param month the month in the year
     * @internal
     */
    virtual int32_t getDefaultDayInMonth(int32_t eyear, int32_t month);

    //-------------------------------------------------------------------------
    // Protected utility methods for use by subclasses.  These are very handy
    // for implementing add, roll, and computeFields.
    //-------------------------------------------------------------------------

    /**
     * Adjust the specified field so that it is within
     * the allowable range for the date to which this calendar is set.
     * For example, in a Gregorian calendar pinning the {@link #UCalendarDateFields DAY_OF_MONTH}
     * field for a calendar set to April 31 would cause it to be set
     * to April 30.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This utility method is intended for use by subclasses that need to implement
     * their own overrides of {@link #roll roll} and {@link #add add}.
     * <p>
     * <b>Note:</b>
     * <code>pinField</code> is implemented in terms of
     * {@link #getActualMinimum getActualMinimum}
     * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
     * a slow, iterative algorithm for a particular field, it would be
     * unwise to attempt to call <code>pinField</code> for that field.  If you
     * really do need to do so, you should override this method to do
     * something more efficient for that field.
     * <p>
     * @param field The calendar field whose value should be pinned.
     * @param status Output param set to failure code on function return
     *          when this function fails.
     *
     * @see #getActualMinimum
     * @see #getActualMaximum
     * @stable ICU 2.0
     */
    virtual void pinField(UCalendarDateFields field, UErrorCode& status);

    /**
     * Return the week number of a day, within a period. This may be the week number in
     * a year or the week number in a month. Usually this will be a value >= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, then
     * the week number will be zero for those
     * initial days. This method requires the day number and day of week for some
     * known date in the period in order to determine the day of week
     * on the desired day.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * This variant is handy for computing the week number of some other
     * day of a period (often the first or last day of the period) when its day
     * of the week is not known but the day number and day of week for some other
     * day in the period (e.g. the current date) <em>is</em> known.
     * <p>
     * @param desiredDay    The {@link #UCalendarDateFields DAY_OF_YEAR} or
     *              {@link #UCalendarDateFields DAY_OF_MONTH} whose week number is desired.
     *              Should be 1 for the first day of the period.
     *
     * @param dayOfPeriod   The {@link #UCalendarDateFields DAY_OF_YEAR}
     *              or {@link #UCalendarDateFields DAY_OF_MONTH} for a day in the period whose
     *              {@link #UCalendarDateFields DAY_OF_WEEK} is specified by the
     *              <code>knownDayOfWeek</code> parameter.
     *              Should be 1 for first day of period.
     *
     * @param dayOfWeek  The {@link #UCalendarDateFields DAY_OF_WEEK} for the day
     *              corresponding to the <code>knownDayOfPeriod</code> parameter.
     *              1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     *
     * @stable ICU 2.8
     */
    int32_t weekNumber(int32_t desiredDay, int32_t dayOfPeriod, int32_t dayOfWeek);


#ifndef U_HIDE_INTERNAL_API
    /**
     * Return the week number of a day, within a period. This may be the week number in
     * a year, or the week number in a month. Usually this will be a value >= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1,
     * then the week number will be zero for those
     * initial days. This method requires the day of week for the given date in order to
     * determine the result.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * @param dayOfPeriod   The {@link #UCalendarDateFields DAY_OF_YEAR} or
     *                      {@link #UCalendarDateFields DAY_OF_MONTH} whose week number is desired.
     *                      Should be 1 for the first day of the period.
     *
     * @param dayOfWeek     The {@link #UCalendarDateFields DAY_OF_WEEK} for the day
     *                      corresponding to the <code>dayOfPeriod</code> parameter.
     *                      1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     * @internal
     */
    inline int32_t weekNumber(int32_t dayOfPeriod, int32_t dayOfWeek);

    /**
     * returns the local DOW, valid range 0..6
     * @internal
     */
    int32_t getLocalDOW();
#endif  /* U_HIDE_INTERNAL_API */

private:

    /**
     * The next available value for fStamp[]
     */
    int32_t fNextStamp;// = MINIMUM_USER_STAMP;

    /**
     * Recalculates the time stamp array (fStamp).
     * Resets fNextStamp to lowest next stamp value.
     */
    void recalculateStamp();

    /**
     * The current time set for the calendar.
     */
    UDate        fTime;

    /**
     * @see   #setLenient
     */
    UBool      fLenient;

    /**
     * Time zone affects the time calculation done by Calendar. Calendar subclasses use
     * the time zone data to produce the local time. Always set; never NULL.
     */
    TimeZone*   fZone;

    /**
     * Option for repeated wall time
     * @see #setRepeatedWallTimeOption
     */
    UCalendarWallTimeOption fRepeatedWallTime;

    /**
     * Option for skipped wall time
     * @see #setSkippedWallTimeOption
     */
    UCalendarWallTimeOption fSkippedWallTime;

    /**
     * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. They are
     * used to figure out the week count for a specific date for a given locale. These
     * must be set when a Calendar is constructed. For example, in US locale,
     * firstDayOfWeek is SUNDAY; minimalDaysInFirstWeek is 1. They are used to figure
     * out the week count for a specific date for a given locale. These must be set when
     * a Calendar is constructed.
     */
    UCalendarDaysOfWeek fFirstDayOfWeek;
    uint8_t     fMinimalDaysInFirstWeek;
    UCalendarDaysOfWeek fWeekendOnset;
    int32_t fWeekendOnsetMillis;
    UCalendarDaysOfWeek fWeekendCease;
    int32_t fWeekendCeaseMillis;

    /**
     * Sets firstDayOfWeek and minimalDaysInFirstWeek. Called at Calendar construction
     * time.
     *
     * @param desiredLocale  The given locale.
     * @param type           The calendar type identifier, e.g: gregorian, buddhist, etc.
     * @param success        Indicates the status of setting the week count data from
     *                       the resource for the given locale. Returns U_ZERO_ERROR if
     *                       constructed successfully.
     */
    void        setWeekData(const Locale& desiredLocale, const char *type, UErrorCode& success);

    /**
     * Recompute the time and update the status fields isTimeSet
     * and areFieldsSet.  Callers should check isTimeSet and only
     * call this method if isTimeSet is false.
     *
     * @param status  Output param set to success/failure code on exit. If any value
     *                previously set in the time field is invalid or restricted by
     *                leniency, this will be set to an error status.
     */
    void updateTime(UErrorCode& status);

    /**
     * The Gregorian year, as computed by computeGregorianFields() and
     * returned by getGregorianYear().
     * @see #computeGregorianFields
     */
    int32_t fGregorianYear;

    /**
     * The Gregorian month, as computed by computeGregorianFields() and
     * returned by getGregorianMonth().
     * @see #computeGregorianFields
     */
    int32_t fGregorianMonth;

    /**
     * The Gregorian day of the year, as computed by
     * computeGregorianFields() and returned by getGregorianDayOfYear().
     * @see #computeGregorianFields
     */
    int32_t fGregorianDayOfYear;

    /**
     * The Gregorian day of the month, as computed by
     * computeGregorianFields() and returned by getGregorianDayOfMonth().
     * @see #computeGregorianFields
     */
    int32_t fGregorianDayOfMonth;

    /* calculations */

    /**
     * Compute the Gregorian calendar year, month, and day of month from
     * the given Julian day.  These values are not stored in fields, but in
     * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
     * DOW_LOCAL fields.
     */
    void computeGregorianAndDOWFields(int32_t julianDay, UErrorCode &ec);

protected:

    /**
     * Compute the Gregorian calendar year, month, and day of month from the
     * Julian day.  These values are not stored in fields, but in member
     * variables gregorianXxx.  They are used for time zone computations and by
     * subclasses that are Gregorian derivatives.  Subclasses may call this
     * method to perform a Gregorian calendar millis->fields computation.
     */
    void computeGregorianFields(int32_t julianDay, UErrorCode &ec);

private:

    /**
     * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
     * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
     * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
     * subclass based on the calendar system.
     *
     * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
     * most of the time, but at the year boundary it may be adjusted to YEAR-1
     * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
     * this case, a simple increment or decrement is performed on YEAR, even
     * though this may yield an invalid YEAR value.  For instance, if the YEAR
     * is part of a calendar system with an N-year cycle field CYCLE, then
     * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
     * back to 0 or 1.  This is not handled by this code, and in fact cannot be
     * simply handled without having subclasses define an entire parallel set of
     * fields for fields larger than or equal to a year.  This additional
     * complexity is not warranted, since the intention of the YEAR_WOY field is
     * to support ISO 8601 notation, so it will typically be used with a
     * proleptic Gregorian calendar, which has no field larger than a year.
     */
    void computeWeekFields(UErrorCode &ec);


    /**
     * Ensure that each field is within its valid range by calling {@link
     * #validateField(int, int&)} on each field that has been set.  This method
     * should only be called if this calendar is not lenient.
     * @see #isLenient
     * @see #validateField(int, int&)
     * @internal
     */
    void validateFields(UErrorCode &status);

    /**
     * Validate a single field of this calendar given its minimum and
     * maximum allowed value.  If the field is out of range,
     * <code>U_ILLEGAL_ARGUMENT_ERROR</code> will be set.  Subclasses may
     * use this method in their implementation of {@link
     * #validateField(int, int&)}.
     * @internal
     */
    void validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status);

 protected:
#ifndef U_HIDE_INTERNAL_API
    /**
     * Convert a quasi Julian date to the day of the week. The Julian date used here is
     * not a true Julian date, since it is measured from midnight, not noon. Return
     * value is one-based.
     *
     * @param julian  The given Julian date number.
     * @return   Day number from 1..7 (SUN..SAT).
     * @internal
     */
    static uint8_t julianDayToDayOfWeek(double julian);
#endif  /* U_HIDE_INTERNAL_API */

 private:
    char validLocale[ULOC_FULLNAME_CAPACITY];
    char actualLocale[ULOC_FULLNAME_CAPACITY];

 public:
#if !UCONFIG_NO_SERVICE
    /**
     * INTERNAL FOR 2.6 --  Registration.
     */

#ifndef U_HIDE_INTERNAL_API
    /**
     * Return a StringEnumeration over the locales available at the time of the call,
     * including registered locales.
     * @return a StringEnumeration over the locales available at the time of the call
     * @internal
     */
    static StringEnumeration* getAvailableLocales(void);

    /**
     * Register a new Calendar factory.  The factory will be adopted.
     * INTERNAL in 2.6
     *
     * Because ICU may choose to cache Calendars internally, this must
     * be called at application startup, prior to any calls to
     * Calendar::createInstance to avoid undefined behavior.
     *
     * @param toAdopt the factory instance to be adopted
     * @param status the in/out status code, no special meanings are assigned
     * @return a registry key that can be used to unregister this factory
     * @internal
     */
    static URegistryKey registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status);

    /**
     * Unregister a previously-registered CalendarFactory using the key returned from the
     * register call.  Key becomes invalid after a successful call and should not be used again.
     * The CalendarFactory corresponding to the key will be deleted.
     * INTERNAL in 2.6
     *
     * Because ICU may choose to cache Calendars internally, this should
     * be called during application shutdown, after all calls to
     * Calendar::createInstance to avoid undefined behavior.
     *
     * @param key the registry key returned by a previous call to registerFactory
     * @param status the in/out status code, no special meanings are assigned
     * @return TRUE if the factory for the key was successfully unregistered
     * @internal
     */
    static UBool unregister(URegistryKey key, UErrorCode& status);
#endif  /* U_HIDE_INTERNAL_API */

    /**
     * Multiple Calendar Implementation
     * @internal
     */
    friend class CalendarFactory;

    /**
     * Multiple Calendar Implementation
     * @internal
     */
    friend class CalendarService;

    /**
     * Multiple Calendar Implementation
     * @internal
     */
    friend class DefaultCalendarFactory;
#endif /* !UCONFIG_NO_SERVICE */

    /**
     * @return TRUE if this calendar has a default century (i.e. 03 -> 2003)
     * @internal
     */
    virtual UBool haveDefaultCentury() const = 0;

    /**
     * @return the start of the default century, as a UDate
     * @internal
     */
    virtual UDate defaultCenturyStart() const = 0;
    /**
     * @return the beginning year of the default century, as a year
     * @internal
     */
    virtual int32_t defaultCenturyStartYear() const = 0;

    /** Get the locale for this calendar object. You can choose between valid and actual locale.
     *  @param type type of the locale we're looking for (valid or actual)
     *  @param status error code for the operation
     *  @return the locale
     *  @stable ICU 2.8
     */
    Locale getLocale(ULocDataLocaleType type, UErrorCode &status) const;

    /**
     * @return      The related Gregorian year; will be obtained by modifying the value
     *              obtained by get from UCAL_EXTENDED_YEAR field
     * @internal
     */
    virtual int32_t getRelatedYear(UErrorCode &status) const;

    /**
     * @param year  The related Gregorian year to set; will be modified as necessary then
     *              set in UCAL_EXTENDED_YEAR field
     * @internal
     */
    virtual void setRelatedYear(int32_t year);

#ifndef U_HIDE_INTERNAL_API
    /** Get the locale for this calendar object. You can choose between valid and actual locale.
     *  @param type type of the locale we're looking for (valid or actual)
     *  @param status error code for the operation
     *  @return the locale
     *  @internal
     */
    const char* getLocaleID(ULocDataLocaleType type, UErrorCode &status) const;
#endif  /* U_HIDE_INTERNAL_API */

private:
    /**
     * Cast TimeZone used by this object to BasicTimeZone, or NULL if the TimeZone
     * is not an instance of BasicTimeZone.
     */
    BasicTimeZone* getBasicTimeZone() const;

    /**
     * Find the previous zone transition near the given time.
     * @param base The base time, inclusive
     * @param transitionTime Receives the result time
     * @param status The error status
     * @return TRUE if a transition is found.
     */
    UBool getImmediatePreviousZoneTransition(UDate base, UDate *transitionTime, UErrorCode& status) const;

public:
#ifndef U_HIDE_INTERNAL_API
    /**
     * Creates a new Calendar from a Locale for the cache.
     * This method does not set the time or timezone in returned calendar.
     * @param locale the locale.
     * @param status any error returned here.
     * @return the new Calendar object with no time or timezone set.
     * @internal For ICU use only.
     */
    static Calendar * U_EXPORT2 makeInstance(
            const Locale &locale, UErrorCode &status);

    /**
     * Get the calendar type for given locale.
     * @param locale the locale
     * @param typeBuffer calendar type returned here
     * @param typeBufferSize The size of typeBuffer in bytes. If the type
     *   can't fit in the buffer, this method sets status to
     *   U_BUFFER_OVERFLOW_ERROR
     * @param status error, if any, returned here.
     * @internal For ICU use only.
     */
    static void U_EXPORT2 getCalendarTypeFromLocale(
            const Locale &locale,
            char *typeBuffer,
            int32_t typeBufferSize,
            UErrorCode &status);
#endif  /* U_HIDE_INTERNAL_API */
};

// -------------------------------------

inline Calendar*
Calendar::createInstance(TimeZone* zone, UErrorCode& errorCode)
{
    // since the Locale isn't specified, use the default locale
    return createInstance(zone, Locale::getDefault(), errorCode);
}

// -------------------------------------

inline void
Calendar::roll(UCalendarDateFields field, UBool up, UErrorCode& status)
{
    roll(field, (int32_t)(up ? +1 : -1), status);
}

#ifndef U_HIDE_DEPRECATED_API
inline void
Calendar::roll(EDateFields field, UBool up, UErrorCode& status)
{
    roll((UCalendarDateFields) field, up, status);
}
#endif  /* U_HIDE_DEPRECATED_API */


// -------------------------------------

/**
 * Fast method for subclasses.  The caller must maintain fUserSetDSTOffset and
 * fUserSetZoneOffset, as well as the isSet[] array.
 */

inline void
Calendar::internalSet(UCalendarDateFields field, int32_t value)
{
    fFields[field] = value;
    fStamp[field] = kInternallySet;
    fIsSet[field]     = TRUE; // Remove later
}


#ifndef U_HIDE_INTERNAL_API
inline int32_t  Calendar::weekNumber(int32_t dayOfPeriod, int32_t dayOfWeek)
{
  return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek);
}
#endif  /* U_HIDE_INTERNAL_API */

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif // _CALENDAR