RaUI/Source/MyDb/SysFuns/ChinaDate.cs

1817 lines
74 KiB
C#
Raw Normal View History

2020-11-28 07:03:28 +00:00
using System.Globalization;
using System.Collections;
using System;
using System.Collections.Generic;
using ryCommon;
/// <summary>
/// 中国农历类,最大支持公元0-9999年
/// </summary>
/// 日期2019-02-09
/// 作者http://www.cnblogs.com/zjfree/
public static class ChinaDate
{
/// <summary>
/// 日历类型
/// </summary>
public enum TCalendarType
{
/// <summary>
/// 无效
/// </summary>
ctinvalid,
/// <summary>
/// Julian 日历
/// </summary>
ctJulian,
/// <summary>
/// Gregorian 日历
/// </summary>
ctGregorian,
/// <summary>
/// 有效
/// </summary>
ctInvalid
}
private static ChineseLunisolarCalendar china = new ChineseLunisolarCalendar();
/// <summary>
/// 公历节日
/// </summary>
private static readonly Hashtable gHoliday = new Hashtable();
/// <summary>
/// 农历节日
/// </summary>
private static readonly Hashtable nHoliday = new Hashtable();
/// <summary>
/// 某个月第n个星期几
/// </summary>
private static readonly Hashtable wHoliday = new Hashtable();
private static readonly int[] SCnLeapNumber =
{
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8,
9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15,
15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21,
22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27,
28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34,
34, 34, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 40, 40,
40, 41, 41, 41, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46,
47, 47, 47, 48, 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, 52, 52, 53,
53, 53, 54, 54, 54, 55, 55, 56, 56, 56, 56, 57, 57, 57, 58, 58, 59,
59, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 64, 64, 65, 65,
65, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 69, 69, 70, 71, 71, 71,
71, 71, 71, 72, 72, 73, 73, 74, 74, 74, 75, 75, 75, 75, 76, 76, 77,
77, 77, 77, 78, 79, 79, 79, 79, 79, 80, 80, 80, 81, 82, 82, 82, 83,
83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88,
89, 89, 90, 90, 91, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 95, 95,
96, 96, 96, 96, 97, 97, 98, 98, 98, 99, 99, 100, 100, 100, 101, 101,
101, 102, 102, 102, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106,
106, 107, 107, 107, 108, 108, 109, 109, 109, 110, 110, 111, 111, 111,
112, 112, 112, 113, 113, 114, 114, 114, 115, 115, 116, 116, 116, 117,
117, 117, 117, 118, 118, 119, 119, 119, 120, 120, 121, 121, 121, 122,
122, 122, 123, 123, 124, 124, 124, 124, 125, 125, 126, 126, 126, 126,
127, 127, 128, 128, 129, 129, 130, 130, 130, 130, 131, 131, 132, 132,
132, 133, 133, 133, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137,
137, 138, 138, 139, 139, 139, 140, 140, 141, 141, 141, 142, 142, 142,
143, 143, 143, 144, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147,
148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 153,
153, 153, 154, 154, 154, 155, 155, 156, 156, 156, 157, 157, 157, 158,
158, 158, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 163, 163,
163, 164, 164, 164, 165, 165, 165, 166, 166, 167, 167, 167, 168, 168,
168, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173,
174, 174, 174, 175, 175, 175, 176, 176, 177, 177, 177, 178, 178, 178,
179, 179, 179, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 184,
184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 188, 188, 188, 189,
189, 189, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194,
194, 195, 195, 195, 196, 196, 196, 197, 197, 198, 198, 198, 199, 199,
199, 200, 200, 200, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204,
205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 209, 209, 209,
210, 210, 210, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214,
214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 218, 218, 218, 219,
219, 219, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224,
224, 225, 225, 225, 226, 226, 226, 227, 227, 228, 228, 228, 229, 229,
229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234,
235, 235, 235, 236, 236, 236, 237, 237, 237, 238, 238, 239, 239, 239,
240, 240, 240, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244,
245, 245, 246, 246, 246, 247, 247, 247, 248, 248, 249, 249, 249, 250,
250, 250, 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255,
255, 256, 256, 256, 257, 257, 257, 258, 258, 259, 259, 259, 260, 260,
260, 261, 261, 261, 262, 262, 263, 263, 263, 264, 264, 264, 265, 265,
266, 266, 266, 267, 267, 267, 268, 268, 268, 269, 269, 270, 270, 270,
271, 271, 271, 272, 272, 273, 273, 273, 274, 274, 274, 275, 275, 276,
276, 276, 277, 277, 277, 278, 278, 278, 279, 279, 280, 280, 280, 281,
281, 281, 282, 282, 283, 283, 283, 284, 284, 284, 285, 285, 285, 286,
286, 287, 287, 287, 288, 288, 288, 289, 289, 290, 290, 290, 291, 291,
291, 292, 292, 292, 293, 293, 294, 294, 294, 295, 295, 295, 296, 296,
297, 297, 297, 298, 298, 298, 299, 299, 299, 300, 300, 301, 301, 301,
302, 302, 302, 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 306,
307, 307, 308, 308, 308, 309, 309, 309, 310, 310, 311, 311, 312, 312,
312, 313, 313, 313, 314, 314, 315, 315, 315, 316, 316, 316, 317, 317,
317, 318, 318, 319, 319, 319, 320, 320, 320, 321, 321, 322, 322, 322,
323, 323, 323, 324, 324, 325, 325, 325, 326, 326, 326, 327, 327, 327,
328, 328, 329, 329, 329, 330, 330, 330, 331, 331, 332, 332, 332, 333,
333, 333, 334, 334, 334, 335, 335, 336, 336, 336, 337, 337, 337, 338,
338, 339, 339, 339, 340, 340, 340, 341, 341, 341, 342, 342, 343, 343,
343, 344, 344, 344, 345, 345, 346, 346, 346, 347, 347, 347, 348, 348,
348, 349, 349, 350, 350, 350, 351, 351, 351, 352, 352, 353, 353, 353,
354, 354, 354, 355, 355, 355, 356, 356, 357, 357, 357, 358, 358, 358,
359, 359, 360, 360, 360, 361, 361, 361, 362, 362, 362, 363, 363, 364,
364, 364, 365, 365, 365, 366, 366, 367, 367, 367, 368, 368, 368, 369,
369, 369, 370, 370, 371, 371, 371, 372, 372, 372, 373, 373, 374, 374,
374, 375, 375, 375, 376, 376, 376, 377, 377, 378, 378, 378, 379, 379,
379, 380, 380, 381, 381, 381, 382, 382, 382, 383, 383, 383, 384, 384,
385, 385, 385, 386, 386, 386, 387, 387, 388, 388, 388, 389, 389, 389,
390, 390, 390, 391, 391, 392, 392, 392, 393, 393, 393, 394, 394, 395,
395, 395, 396, 396, 396, 397, 397, 397, 398, 398, 399, 399, 399, 400,
400, 400, 401, 401, 402, 402, 402, 403, 403, 403, 404, 404, 404, 405,
405, 406, 406, 406, 407, 407, 407, 408, 408, 409, 409, 409, 410, 410,
410, 411, 411, 411, 412, 412, 413, 413, 413, 414, 414, 414, 415, 415,
416, 416, 416, 417, 417, 417, 418, 418, 418, 419, 419, 420, 420, 420,
421, 421, 421, 422, 422, 423, 423, 423, 424, 424, 424, 425, 425, 425,
426, 426, 427, 427, 427, 428, 428, 428, 429, 429, 430, 430, 430, 431,
431, 431, 432, 432, 432, 433, 433, 434, 434, 434, 435, 435, 435, 436,
436, 437, 437, 437, 438, 438, 438, 439, 439, 439, 440, 440, 441, 441,
441, 442, 442, 442, 443, 443, 444, 444, 444, 445, 445, 445, 446, 446,
446, 447, 447, 448, 448, 448, 449, 449, 449, 450, 450, 451, 451, 451,
452, 452, 452, 453, 453, 453, 454, 454, 455, 455, 455, 456, 456, 456,
457, 457, 458, 458, 458, 459, 459, 459, 460, 460, 460, 461, 461, 462,
462, 462, 463, 463, 463, 464, 464, 465, 465, 465, 466, 466, 466, 467,
467, 467, 468, 468, 469, 469, 469, 470, 470, 470, 471, 471, 472, 472,
472, 473, 473, 473, 474, 474, 474, 475, 475, 475, 476, 476, 477, 477,
477, 478, 478, 478, 479, 479, 480, 480, 480, 481, 481, 481, 482, 482,
482, 483, 483, 484, 484, 484, 485, 485, 485, 486, 486, 487, 487, 487,
488, 488, 488, 489, 489, 489, 490, 490, 491, 491, 491, 492, 492, 492,
493, 493, 494, 494, 494, 495, 495, 495, 496, 496, 496, 497, 497, 498,
498, 498, 499, 499, 499, 500, 500, 501, 501, 501, 502, 502, 502, 503,
503, 503, 504, 504, 505, 505, 505, 506, 506, 506, 507, 507, 508, 508,
508, 509, 509, 509, 510, 510, 510, 511, 511, 512, 512, 512, 513, 513,
513, 514, 514, 515, 515, 515, 516, 516, 516, 517, 517, 517, 518, 518,
519, 519, 519, 520, 520, 520, 521, 521, 522, 522, 522, 523, 523, 523,
524, 524, 524, 525, 525, 526, 526, 526, 527, 527, 527, 528, 528, 529,
529, 529, 530, 530, 530, 531, 531, 531, 532, 532, 533, 533, 533, 534,
534, 534, 535, 535, 536, 536, 536, 537, 537, 537, 538, 538, 538, 539,
539, 540, 540, 540, 541, 541, 541, 542, 542, 543, 543, 543, 544, 544,
544, 545, 545, 545, 546, 546, 547, 547, 547, 548, 548, 548, 549, 549,
550, 550, 550, 551, 551, 551, 552, 552, 552, 553, 553, 554, 554, 554,
555, 555, 555, 556, 556, 557, 557, 557, 558, 558, 558, 559, 559, 559,
560, 560, 561, 561, 561, 562, 562, 562, 563, 563, 563, 564, 564, 565,
565, 565, 566, 566, 566, 567, 567, 568, 568, 568, 569, 569, 569, 570,
570, 570, 571, 571, 572, 572, 572, 573, 573, 573, 574, 574, 575, 575,
575, 576, 576, 576, 577, 577, 578, 578, 578, 579, 579, 579, 580, 580,
580, 581, 581, 582, 582, 582, 583, 583, 583, 584, 584, 584, 585, 585,
586, 586, 586, 587, 587, 587, 588, 588, 589, 589, 589, 590, 590, 590,
591, 591, 591, 592, 592, 593, 593, 593, 594, 594, 594, 595, 595, 596,
596, 596, 597, 597, 597, 598, 598, 598, 599, 599, 600, 600, 600, 601,
601, 601, 602, 602, 603, 603, 603, 604, 604, 604, 605, 605, 605, 606,
606, 607, 607, 607, 608, 608, 608, 609, 609, 610, 610, 610, 611, 611,
611, 612, 612, 612, 613, 613, 614, 614, 614, 615, 615, 615, 616, 616,
617, 617, 617, 618, 618, 618, 619, 619, 619, 620, 620, 621, 621, 621,
622, 622, 622, 623, 623, 624, 624, 624, 625, 625, 625, 626, 626, 626,
627, 627, 628, 628, 628, 629, 629, 629, 630, 630, 631, 631, 631, 632,
632, 632, 633, 633, 633, 634, 634, 635, 635, 635, 636, 636, 636, 637,
637, 638, 638, 638, 639, 639, 639, 640, 640, 640, 641, 641, 642, 642,
642, 643, 643, 643, 644, 644, 645, 645, 645, 646, 646, 646, 647, 647,
647, 648, 648, 649, 649, 649, 650, 650, 650, 651, 651, 652, 652, 652,
653, 653, 653, 654, 654, 654, 655, 655, 656, 656, 656, 657, 657, 657,
658, 658, 659, 659, 659, 660, 660, 660, 661, 661, 661, 662, 662, 663,
663, 663, 664, 664, 664, 665, 665, 666, 666, 666, 667, 667, 667, 668,
668, 668, 669, 669, 670, 670, 670, 671, 671, 671, 672, 672, 673, 673,
673, 674, 674, 674, 675, 675, 675, 676, 676, 677, 677, 677, 678, 678,
678, 679, 679, 680, 680, 680, 681, 681, 681, 682, 682, 682, 683, 683,
684, 684, 684, 685, 685, 685, 686, 686, 687, 687, 687, 688, 688, 688,
689, 689, 689, 690, 690, 691, 691, 691, 692, 692, 692, 693, 693, 694,
694, 694, 695, 695, 695, 696, 696, 696, 697, 697, 698, 698, 698, 699,
699, 699, 700, 700, 701, 701, 701, 702, 702, 702, 703, 703, 703, 704,
704, 705, 705, 705, 706, 706, 706, 707, 707, 707, 708, 708, 709, 709,
709, 710, 710, 710, 711, 711, 712, 712, 712, 713, 713, 713, 714, 714,
714, 715, 715, 716, 716, 716, 717, 717, 717, 718, 718, 719, 719, 719,
720, 720, 720, 721, 721, 721, 722, 722, 723, 723, 723, 724, 724, 724,
725, 725, 726, 726, 726, 727, 727, 727, 728, 728, 728, 729, 729, 730,
730, 730, 731, 731, 731, 732, 732, 733, 733, 733, 734, 734, 734, 735,
735, 736, 736, 736, 737, 737, 737, 738, 738, 738, 739, 739, 740, 740,
740, 741, 741, 741, 742, 742, 742, 743, 743, 744, 744, 744, 745, 745,
745, 746, 746, 747, 747, 747, 748, 748, 748, 749, 749, 749, 750, 750,
751, 751, 751, 752, 752, 752, 754, 754, 755, 755, 755, 756, 756, 756,
757, 757, 757, 758, 758, 759, 759, 759, 760, 760, 760, 761, 761, 762,
762, 762, 763, 763, 763, 764, 764, 764, 765, 765, 766, 766, 766, 767,
767, 767, 768, 768, 769, 769, 769, 770, 770, 770, 771, 771, 771, 772,
772, 773, 773, 773, 774, 774, 774, 775, 775, 776, 776, 776, 777, 777,
777, 778, 778, 778, 779, 779, 780, 780, 780, 781, 781, 781, 782, 782,
783, 783, 783, 784, 784, 784, 785, 785, 785, 786, 786, 787, 787, 787,
788, 788, 788, 789, 789, 790, 790, 790, 791, 791, 791, 792, 792, 792,
793, 793, 794, 794, 794, 795, 795, 795, 796, 796, 796, 797, 797, 798,
798, 798, 799, 799, 799, 800, 800, 801, 801, 801, 802, 802, 802, 803,
803, 804, 804, 804, 805, 805, 805, 806, 806, 806, 807, 807, 808, 808,
808, 809, 809, 809, 810, 810, 810, 811, 811, 812, 812, 812, 813, 813,
813, 814, 814, 815, 815, 815, 816, 816, 816, 817, 817, 818, 818, 818,
819, 819, 819, 820, 820, 820, 821, 821, 822, 822, 822, 823, 823, 823,
824, 824, 825, 825, 825, 826, 826, 826, 827, 827, 827, 828, 828, 829,
829, 829, 830, 830, 830, 831, 831, 832, 832, 832, 833, 833, 833, 834,
834, 834, 835, 835, 836, 836, 836, 837, 837, 837, 838, 838, 839, 839,
839, 840, 840, 840, 841, 841, 841, 842, 842, 843, 843, 843, 844, 844,
844, 845, 845, 845, 846, 846, 847, 847, 847, 848, 848, 848, 849, 849,
850, 850, 850, 851, 851, 851, 852, 852, 852, 853, 853, 854, 854, 854,
855, 855, 855, 856, 856, 857, 857, 857, 858, 858, 858, 859, 859, 859,
860, 860, 861, 861, 861, 862, 862, 862, 863, 863, 864, 864, 863, 864,
864, 864, 865, 865, 865, 866, 866, 867, 867, 867, 868, 868, 868, 869,
869, 870, 870, 870, 871, 871, 871, 872, 872, 873, 873, 873, 874, 874,
874, 875, 875, 875, 876, 876, 877, 877, 877, 878, 878, 878, 879, 879,
879, 880, 880, 881, 881, 881, 882, 882, 882, 883, 883, 884, 884, 884,
885, 885, 885, 886, 886, 886, 887, 887, 888, 888, 888, 889, 889, 889,
890, 890, 891, 891, 891, 892, 892, 892, 893, 893, 893, 894, 894, 895,
895, 895, 896, 896, 896, 897, 897, 898, 898, 898, 899, 899, 899, 900,
900, 900, 901, 901, 902, 902, 902, 903, 903, 903, 904, 904, 905, 905,
905, 906, 906, 906, 907, 907, 907, 908, 908, 909, 909, 909, 910, 910,
910, 911, 911, 912, 912, 912, 913, 913, 913, 914, 914, 914, 915, 915,
916, 916, 916, 917, 917, 917, 918, 918, 919, 919, 919, 920, 920, 920,
921, 921, 921, 922, 922, 923, 923, 923, 924, 924, 924, 925, 925, 925,
926, 926, 927, 927, 927, 928, 928, 928, 929, 929, 930, 930, 930, 931,
931, 931, 932, 932, 932, 933, 933, 934, 934, 934, 935, 935, 935, 936,
936, 937, 937, 937, 938, 938, 938, 939, 939, 939, 940, 940, 941, 941,
941, 942, 942, 942, 943, 943, 944, 944, 944, 945, 945, 945, 946, 946,
946, 947, 947, 948, 948, 948, 949, 949, 949, 950, 950, 951, 951, 951,
952, 952, 952, 953, 953, 953, 954, 954, 955, 955, 955, 956, 956, 956,
957, 957, 958, 958, 958, 959, 959, 959, 960, 960, 960, 961, 961, 962,
962, 962, 963, 963, 963, 964, 964, 965, 965, 965, 966, 966, 966, 967,
967, 967, 968, 968, 969, 969, 969, 970, 970, 970, 971, 971, 971, 972,
972, 973, 973, 973, 974, 974, 974, 975, 975, 976, 976, 976, 977, 977,
977, 978, 978, 978, 979, 979, 980, 980, 980, 981, 981, 981, 982, 982,
983, 983, 983, 984, 984, 984, 985, 985, 986, 986, 986, 987, 987, 987,
988, 988, 988, 989, 989, 990, 990, 990, 991, 991, 991, 992, 992, 993,
993, 993, 994, 994, 994, 995, 995, 995, 996, 996, 997, 997, 997, 998,
998, 998, 999, 999, 1000, 1000, 1000, 1001, 1001, 1001, 1002, 1002,
1002, 1003, 1003, 1004, 1004, 1004, 1005, 1005, 1005, 1006, 1006,
1006, 1007, 1007, 1008, 1008, 1008, 1009, 1009, 1009, 1010, 1010,
1011, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1013, 1014, 1014,
1015, 1015, 1015, 1016, 1016, 1016, 1017, 1017, 1018, 1018, 1018,
1019, 1019, 1019, 1020, 1020, 1020, 1021, 1021, 1022, 1022, 1022,
1023, 1023, 1023, 1024, 1024, 1025, 1025, 1025, 1026, 1026, 1026,
1027, 1027, 1027, 1028, 1028, 1029, 1029, 1029, 1030, 1030, 1030,
1031, 1031, 1032, 1032, 1032, 1033, 1033, 1033, 1034, 1034, 1034,
1035, 1035, 1036, 1036, 1036, 1037, 1037, 1037, 1038, 1038, 1039,
1039, 1039, 1040, 1040, 1040, 1041, 1041, 1042, 1042, 1042, 1043,
1043, 1043, 1044, 1044, 1044, 1045, 1045, 1046, 1046, 1046, 1047,
1047, 1047, 1048, 1048, 1048, 1049, 1049, 1050, 1050, 1050, 1051,
1051, 1051, 1052, 1052, 1053, 1053, 1053, 1054, 1054, 1054, 1055,
1055, 1055, 1056, 1056, 1057, 1057, 1057, 1058, 1058, 1058, 1059,
1059, 1060, 1060, 1060, 1061, 1061, 1061, 1062, 1062, 1062, 1063,
1063, 1064, 1064, 1064, 1065, 1065, 1065, 1066, 1066, 1067, 1067,
1067, 1068, 1068, 1068, 1069, 1069, 1069, 1070, 1070, 1071, 1071,
1071, 1072, 1072, 1072, 1073, 1073, 1074, 1074, 1074, 1075, 1075,
1075, 1076, 1076, 1076, 1077, 1077, 1078, 1078, 1078, 1079, 1079,
1079, 1080, 1080, 1081, 1081, 1081, 1082, 1082, 1082, 1083, 1083,
1083, 1084, 1084
};
private static readonly string SCnLeapMonth =
"0c0080050010a0070030c0080050010a0070030c0080050020a0070030c0080050020a" +
"0070030c0090050020a0070030c0090050020a0060030c0060030c00900600c0c0060c" +
"00c00c00c0c000600c0c0006090303030006000c00c060c0006c00000c0c0c00600030" +
"30006c00009009c0090c00c009000300030906030030c0c00060c00090c0060600c003" +
"0060c00c003006009060030c0060060c0090900c00090c0090c00c0060300060600030" +
"30c0c00030c0060030c0090060030c0090300c0080050020a0060030c0080050020b00" +
"70030c0090050010a0070030b0090060020a0070040c0080050020a0060030c0080050" +
"020b0070030c0090050010a0070030b0090060020a0070040c0080050020a0060030c0" +
"080050020b0070030c0090050000c00900909009009090090090090900900909009009" +
"0090900900909009009009090090090900900900909009009090090090900900900909" +
"00900909009009009090090090900900900909009009090060030c0090050010a00700" +
"30b008005001090070040c0080050020a0060030c0090040010a0060030c0090050010" +
"a0070030b0080050010a008005001090050020a0060030c0080040010a0060030c0090" +
"050010a0070030b0080050010a0070030b008005001090070040c0080050020a006003" +
"0c0080040010a0060030c0090050010a0070030b008005001090070040c0080050020a" +
"0060030c0080040010a0060030c0090050010a0060030c0090050010a0070030b00800" +
"5001090070040c0080050020a0060030c0080040010a0070030b0080050010a0070040" +
"c0080050020a0060030c0080040010a0070030c0090050010a0070030b0080050020a0" +
"060030c0080040010a0060030c0090050050020a0060030c0090050010b0070030c009" +
"0050010a0070040c0080040020a0060030c0080050020a0060030c0090050010a00700" +
"30b0080040020a0060040c0090050020b0070030c00a0050010a0070030b0090050020" +
"a0070030c0080040020a0060030c0090050010a0070030c0090050030b007005001090" +
"050020a007004001090060020c0070050c0090060030b0080040020a0060030b008004" +
"0010a0060030b0080050010a0050040c0080050010a0060030c0080050010b0070030c" +
"007005001090070030b0070040020a0060030c0080040020a0070030b0090050010a00" +
"60040c0080050020a0060040c0080050010b0070030c007005001090070030c0080050" +
"020a0070030c0090050020a0070030c0090050020a0060040c0090050020a0060040c0" +
"090050010b0070030c0080050030b007004001090060020c008004002090060020a008" +
"004001090050030b0080040020a0060040b0080040c00a0060020b0070050010900600" +
"30b0070050020a0060020c008004002090070030c008005002090070040c0080040020" +
"a0060040b0090050010a0060030b0080050020a0060040c0080050010b007003001080" +
"05001090070030c0080050020a007003001090050030a0070030b0090050020a006004" +
"0c0090050030b0070040c0090050010c0070040c0080060020b00700400a090060020b" +
"007003002090060020a005004001090050030b007004001090050040c0080040c00a00" +
"60020c007005001090060030b0070050020a0060020c008004002090060030b0080040" +
"02090060030b0080040020a0060040b0080040010b0060030b0070050010a006004002" +
"0700500308006004003070050030700600400307005003080060040030700500409006" +
"0040030700500409006005002070050030a00600500307005004002060040020600500" +
"30020600400307005004090060040030700500408007005003080050040a0060050030" +
"7005004002060050030800500400206005002070050040020600500307006004002070" +
"050030800600400307005004080060040a006005003080050040020700500409006004" +
"002060050030b006005002070050030800600400307005004080060040030700500408" +
"0060040020" +
"700500409006004003070050040b006005002070050040b006005003070060040a0060" +
"0500307006004002060050030700600409006004003070050040900700500308005004" +
"0b00600500307006005001070050030800600400206005003070060040020600500307" +
"0060040a00700500308006004003070050040800600500107005004080060050020700" +
"50040a0060040020600500308006005002070050030800600400307005004080070050" +
"030800500408006005003070050040a006005003070050040a00600500207005004001" +
"0600500307006004001070050030700600408007005004070060040900600400307005" +
"0040a007005003080060040b0060050030800600500107005003080060040020700500" +
"3070060040030700500307006004003070050030800600400307005004090060050b00" +
"7005004090060050020700600408006005003070060030800600500307006003080060";
//{ * 自公元前 850 年开始的农历闰月信息 -849~2100移植自中国日历类2100 后罗建仁计算补充}
private static readonly string[] JQ = { "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒" };
private static readonly int[] MonthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static readonly int[] MonthDays2 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static ChinaDate()
{
//公历节日
gHoliday.Add("0101", "元旦");
gHoliday.Add("0210", "气象节:1991");
gHoliday.Add("0214", "情人节");
gHoliday.Add("0303", "全国爱耳日:1999");
gHoliday.Add("0305", "雷锋日:1963");
gHoliday.Add("0308", "妇女节:1975");
gHoliday.Add("0312", "植树节:1979");
gHoliday.Add("0315", "消权日:1983");
gHoliday.Add("0322", "世界水日:1993");
gHoliday.Add("0401", "愚人节:1564");
gHoliday.Add("0422", "地球日:1970");
gHoliday.Add("0501", "劳动节:1890");
gHoliday.Add("0504", "青年节:1949");
gHoliday.Add("0512", "护士节:1912");
gHoliday.Add("0515", "家庭日:1989");
gHoliday.Add("0517", "世界电信日:1932");
gHoliday.Add("0531", "无烟日:1988");
gHoliday.Add("0601", "儿童节:1950");
gHoliday.Add("0605", "环境日:1972");
gHoliday.Add("0606", "全国爱眼日:1996");
gHoliday.Add("0608", "海洋日:2009");
gHoliday.Add("0614", "世界献血日:2005");
gHoliday.Add("0626", "禁毒日:1987");
gHoliday.Add("0701", "建党节:1921");
gHoliday.Add("0706", "国际接吻日:1991");
gHoliday.Add("0707", "七七事变:1937");
gHoliday.Add("0711", "人口日:1989");
gHoliday.Add("0801", "建军节:1933");
gHoliday.Add("0910", "教师节:1985");
gHoliday.Add("0920", "爱牙日:1989");
gHoliday.Add("0921", "和平日:2002");
gHoliday.Add("0922", "世界无车日:1998");
gHoliday.Add("0927", "世界旅游日:1979");
gHoliday.Add("0929", "心脏日:2011");
gHoliday.Add("1001", "国庆节:1949");
gHoliday.Add("1009", "世界邮政日:1969");
gHoliday.Add("1013", "保健日:1950");
gHoliday.Add("1016", "粮食日:1981");
gHoliday.Add("1028", "男性健康日:2000");
gHoliday.Add("1031", "万圣节:600");
gHoliday.Add("1111", "光棍节");
gHoliday.Add("1116", "宽容日:1996");
gHoliday.Add("1201", "艾滋病日:1988");
gHoliday.Add("1224", "平安夜");
gHoliday.Add("1225", "圣诞节");
//农历节日
nHoliday.Add("0101", "春节");
nHoliday.Add("0115", "元宵节");
nHoliday.Add("0202", "龙抬头");
nHoliday.Add("0505", "端午节");
nHoliday.Add("0624", "火把节");
nHoliday.Add("0707", "七夕");
nHoliday.Add("0715", "中元节");
nHoliday.Add("0722", "财神节");
nHoliday.Add("0815", "中秋节");
nHoliday.Add("0909", "重阳节");
nHoliday.Add("1001", "祭祖节");
nHoliday.Add("1208", "腊八节");
nHoliday.Add("1223", "小年(北方)");
nHoliday.Add("1224", "小年(南方)");
//某个月第n个星期几
wHoliday.Add("0527", "国际母亲节:1908");
wHoliday.Add("0637", "父亲节:1972");
wHoliday.Add("0907", "心脏日:2000-2010");//9月最后一个周日
wHoliday.Add("1011", "住房日:1986");
wHoliday.Add("1144", "感恩节:1941");//11月的第四个星期四
}
/// <summary>
/// 获取农历
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetChinaDate(DateTime dt)
{
string str = string.Format("{0} {1}{2}", GetYear(dt), GetMonth(dt), GetDay(dt));
string strJQ = GetSolarTerm(dt);
if (strJQ != "")
{
str += " (" + strJQ + ")";
}
//string strHoliday = GetHoliday(dt);
//string strChinaHoliday = GetChinaHoliday(dt);
//if (strHoliday != "")
//{
// str += " " + strHoliday;
//}
//if (strChinaHoliday != "")
//{
// str += " " + strChinaHoliday;
//}
return str;
}
/// <summary>
/// 获取农历
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetChinaDate(int AYear, int AMonth, int ADay)
{
string str = string.Format("{0} {1}{2}", GetYear(AYear, AMonth, ADay), GetMonth(AYear, AMonth, ADay), GetDay(AYear, AMonth, ADay));
string strJQ = GetSolarTerm(AYear, AMonth, ADay);
if (strJQ != "")
{
str += " (" + strJQ + ")";
}
//string strHoliday = GetHoliday(dt);
//string strChinaHoliday = GetChinaHoliday(dt);
//if (strHoliday != "")
//{
// str += " " + strHoliday;
//}
//if (strChinaHoliday != "")
//{
// str += " " + strChinaHoliday;
//}
return str;
}
// 移植自中国日历类
private static int GetLeapMonth(int AYear)
{
char C = SCnLeapMonth[AYear + 849];
if (C >= 48 && C <= 57) //0-9
{ return (int)C - 48; }
else if (C >= 97 && C <= 122) //a-z
{
return 10 + (int)C - 97;
}
else { return -1; }
}
// 移植自中国日历类
private static int GetLeapNum(int AYear)
{
if (AYear < 0)
{
return SCnLeapNumber[AYear + 849];
}
else { return SCnLeapNumber[AYear - 1 + 849]; }
}
/// <summary>
/// 获得某农历年的闰月,返回 1~12 对应一月到十二月,返回 0 表示无闰月
/// </summary>
/// <param name="AYear"></param>
/// <returns></returns>
public static int GetLunarLeapMonth(int AYear)
{
int result = GetLeapMonth(AYear);
if (result < 0) { result = 0; }
return result;
}
/// <summary>
/// 农历搜索方向
/// </summary>
public enum TLunarSearchDirection
{
/// <summary>
/// 无效
/// </summary>
lsdInvalid,
/// <summary>
/// 向上
/// </summary>
lsdUp,
/// <summary>
/// 向下
/// </summary>
lsdDown
}
/// <summary>
/// {* 日月食类型, 无, 日食, 月全食, 月偏食 }
/// </summary>
public enum TEclipseType
{
/// <summary>
/// 无
/// </summary>
etNone,
/// <summary>
/// 日食
/// </summary>
etSolar,
/// <summary>
/// 月全食
/// </summary>
etMoonFull,
/// <summary>
/// 月偏食
/// </summary>
etMoonHalf
}
/// <summary>
/// {* 月相, 无, 朔, 望}
/// </summary>
public enum TMoonPhase
{
/// <summary>
/// 无
/// </summary>
mpNone,
/// <summary>
/// 朔
/// </summary>
mpShuo,
/// <summary>
/// 望
/// </summary>
mpWang
}
// 获得一大于零的数的小数部分
private static double GetTail(double X)
{
if (X > 0) { return X - Math.Truncate(X); }
else { return X + Math.Truncate(X); }
}
// 某角度计算函数,移植自中国日历类
private static double GetAng(double X, double T, double C1, double T0, double T2, double T3)
{
return GetTail(C1 * X) * 2 * Math.PI + T0 - T2 * T * T - T3 * T * T * T;
}
/// <summary>
/// 获得某公历年月日的农历日数和该日月相以及日月食类型和时刻
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <param name="EclipseType"></param>
/// <param name="MoonPhase"></param>
/// <param name="theTime"></param>
/// <returns></returns>
public static double GetLunarMoon(int AYear, int AMonth, int ADay, out TEclipseType EclipseType, out TMoonPhase MoonPhase, out double theTime)
{
double T = (AYear - 1899.5) / 100;
int Ms = Convert.ToInt32(Math.Floor((AYear - 1900) * 12.3685));
double Rpi = 180 / Math.PI;
double Zone = 8;
double F0 = GetAng(Ms, T, 0, 0.75933, 2.172e-4, 1.55e-7)
+ 0.53058868 * Ms - 8.37e-4 * T + Zone / 24 + 0.5;
double Fc = 0.1734 - 3.93e-4 * T;
double J0 = 693595 + 29 * Ms;
double Aa0 = GetAng(Ms, T, 0.08084821133, 359.2242 / Rpi, 0.0000333 / Rpi, 0.00000347 / Rpi);
double Ab0 = GetAng(Ms, T, 7.171366127999999e-2, 306.0253 / Rpi, -0.0107306 / Rpi, -0.00001236 / Rpi);
double Ac0 = GetAng(Ms, T, 0.08519585128, 21.2964 / Rpi, 0.0016528 / Rpi, 0.00000239 / Rpi);
EclipseType = TEclipseType.etNone;
int LunDay = -1;
double ShuoTime = 0;
int WangDay = 0;
double WangTime = 0;
double K1 = -1; double K = -1;
int StdDays = GetEquStandardDays(AYear, AMonth, ADay);
while (K <= 13)
{
double Aa = Aa0 + 0.507984293 * K;
double Ab = Ab0 + 6.73377553 * K;
double Ac = Ac0 + 6.818486628 * K;
double F1 = F0 + 1.53058868 * K + Fc * Math.Sin(Aa) - 0.4068 * Math.Sin(Ab)
+ 0.0021 * Math.Sin(2 * Aa) + 0.0161 * Math.Sin(2 * Ab) + 0.0104 * Math.Sin(2 * Ac)
- 0.0074 * Math.Sin(Aa - Ab) - 0.0051 * Math.Sin(Aa + Ab);
double J = J0 + 28 * K + F1;
int LunDay0 = StdDays - (int)Math.Floor(J);
if ((K == Math.Floor(K)) && (LunDay0 >= 0) && (LunDay0 <= 29))
{
K1 = K;
ShuoTime = GetTail(J);
LunDay = LunDay0 + 1;
}
if (K == K1 + 0.5)
{
WangTime = GetTail(J);
WangDay = (int)Math.Floor(J) - (StdDays - LunDay + 1) + 1;
}
if (((LunDay == 1) && (K == K1)) || ((LunDay == WangDay) && (K == K1 + 0.5)))
{
if (Math.Abs(Math.Sin(Ac)) <= 0.36)
{
double S = 5.19595 - 0.0048 * Math.Cos(Aa) + 0.002 * Math.Cos(2 * Aa) - 0.3283 * Math.Cos(Ab)
- 0.006 * Math.Cos(Aa + Ab) + 0.0041 * Math.Cos(Aa - Ab);
double R = 0.207 * Math.Sin(Aa) + 0.0024 * Math.Sin(2 * Aa) - 0.039 * Math.Sin(Ab)
+ 0.0115 * Math.Sin(2 * Ab) - 0.0073 * Math.Sin(Aa + Ab) - 0.0067 * Math.Sin(Aa - Ab)
+ 0.0117 * Math.Sin(2 * Ac);
double P = Math.Abs(S * Math.Sin(Ac) + R * Math.Cos(Ac));
double Q = 0.0059 + 0.0046 * Math.Cos(Ac) - 0.0182 * Math.Cos(Ab) + 0.0004 * Math.Cos(2 * Ab)
- 0.0005 * Math.Cos(Aa + Ab);
if (P - Q <= 1.5572)
{
EclipseType = TEclipseType.etSolar; // 日食
if (K != Math.Floor(K))
{
if (P + Q >= 1.0129)
{
EclipseType = TEclipseType.etMoonHalf; //月偏食
}
else
{
EclipseType = TEclipseType.etMoonFull; //月全食
}
}
}
}
}
K = K + 0.5;
}
// 1924.3.5 ~ 4.3 少一天
//if ((AYear == 1) && (((AMonth == 9) && (ADay >= 6)) || ((AMonth == 10) && (ADay <= 4))))
//{
// LunDay--;
// if (LunDay <1) { LunDay = LunDay + 30; }
//}
// 1924.3.5 ~ 4.3 少一天
if ((AYear == 1924) && (((AMonth == 3) && (ADay >= 5)) || ((AMonth == 4) && (ADay <= 3))))
{
LunDay++;
if (LunDay > 30) { LunDay = LunDay - 30; }
}
// 2018.11.7 ~ 12.6 多一天
if ((AYear == 2018) && (((AMonth == 11) && (ADay >= 7)) || ((AMonth == 12) && (ADay <= 6))))
{
LunDay--;
if (LunDay < 1) { LunDay = LunDay + 30; }
}
//2025.4.27 ~ 5.26 少一天
if ((AYear == 2025) && (((AMonth == 4) && (ADay >= 7)) || ((AMonth == 5) && (ADay <= 26))))
{
LunDay++;
if (LunDay > 30) { LunDay = LunDay - 30; }
}
double Result = LunDay;
if (LunDay == 1)// 朔日
{
MoonPhase = TMoonPhase.mpShuo;
theTime = ShuoTime;
}
else if (LunDay == WangDay)
{
MoonPhase = TMoonPhase.mpWang;
theTime = WangTime;
}
else
{
MoonPhase = TMoonPhase.mpNone;
theTime = -1;
}
return Result;
}
/// <summary>
/// 获得某公历年月日的农历月数
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static double GetLunarMonth(int AYear, int AMonth, int ADay)
{
double LunDay = GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime);
if (aTime != -1) { LunDay = LunDay + aTime; }
LunDay = Math.Floor(LunDay - Math.Floor(LunDay / 100) * 100);
int LeapMons = GetLeapNum(AYear);
int NMonth = (int)Math.Round((GetEquStandardDays(AYear, AMonth, ADay)
- GetEquStandardDays(-849, 1, 21) - LunDay) / 29.530588) - LeapMons;
//历史上的修改月建
if (AYear <= 240) NMonth++;
if (AYear <= 237) NMonth--;
if (AYear < 24) NMonth++;
if (AYear < 9) NMonth--;
if (AYear <= -255) NMonth++;
if (AYear <= -256) NMonth += 2;
if (AYear <= -722) NMonth++;
double Result = Math.Round(GetRemain(NMonth - 3, 12) + 1);
if ((Result == GetLeapMonth(AYear - 1)) && (AMonth == 1) && (ADay < LunDay))
{
Result = -Result; //如果 AYear - 1年末是闰月且该月接到了 AYear 年,则 AYear 年年初也是闰月
}
else if (Result == GetLeapMonth(AYear))
{
// 如果得到的月份数与当年所闰的月相同比如1612年1月31号。
// 上面计算所得的是11月并且1612年年底有个闰11月这俩不能混淆
if (AMonth.IsInRange(1, 2) && (GetLeapMonth(AYear) != 12))
{
// 粗略判断如果月份在年初且今年闰月不是12月就说明两个月不是一个年的
// 所以不是闰月,修正为普通月。但这个修正可能不是太准确
// 比如1984年有闰10月而1984.1.1的农历月为10
// 但这是从1983年阴历接过来的所以不是1984年的闰10月
Result = Result + 1;
}
else { Result = -Result; }
}
else
{
if (Result < GetLeapMonth(AYear) || (AMonth < Result) && (GetLeapMonth(AYear) > 0))
{
Result = Result + 1; //如果 AYear 年是闰月但当月未过闰月则前面多扣除了本年的闰月,这里应当补偿
}
Result = Math.Round(GetRemain(Result - 1, 12) + 1);
}
return Result;
}
// 小数的求余数
static double GetRemain(double X, double W)
{
return GetTail(X / W) * W;
}
/// <summary>
/// 获取阳历日期对应的农历日期
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <param name="LunarYear"></param>
/// <param name="LunarMonth"></param>
/// <param name="LunarDay"></param>
/// <param name="IsLeapMonth"></param>
/// <returns></returns>
public static bool GetLunarFromDay(int AYear, int AMonth, int ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth)
{
bool Result = false;
LunarYear = 0;
LunarMonth = 0;
LunarDay = 0;
IsLeapMonth = false;
if ((AYear >= -849) && (AYear <= 2100))
{
LunarDay = (int)Math.Floor(GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime));
LunarMonth = (int)Math.Floor(GetLunarMonth(AYear, AMonth, ADay));
IsLeapMonth = LunarMonth < 0;
if (IsLeapMonth)
{ LunarMonth = -LunarMonth; }
LunarYear = AYear;
// 农历在下半年,公历在上半年,则农历应为上一年
if ((LunarMonth > 6) && (AMonth < 6))
{
LunarYear--;
}
Result = true;
}
return Result;
}
/// <summary>
/// 获得某公历年月日的农历月日和是否闰月的信息
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <param name="LunarMonth"></param>
/// <param name="LunarDay"></param>
/// <param name="IsLeapMonth"></param>
/// <returns></returns>
public static bool GetLunarMonthDayFromDay(int AYear, int AMonth, int ADay, out int LunarMonth, out int LunarDay, out bool IsLeapMonth)
{
bool Result = false;
LunarMonth = 0;
LunarDay = 0;
IsLeapMonth = false;
if ((AYear >= -849) && (AYear <= 2100))
{
LunarDay = (int)Math.Floor(GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime));
LunarMonth = (int)Math.Floor(GetLunarMonth(AYear, AMonth, ADay));
IsLeapMonth = LunarMonth < 0;
if (IsLeapMonth)
LunarMonth = -LunarMonth;
Result = true;
}
return Result;
}
/// <summary>
/// 获得等效标准日数对应的某公历日,倒推而来
/// </summary>
/// <param name="EquDays"></param>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
private static bool GetDayFromEquStandardDays(int EquDays, out int AYear, out int AMonth, out int ADay)
{
const int D1 = 365;
const int D4 = D1 * 4 + 1;
const int D100 = D4 * 25 - 1;
const int D400 = D100 * 4 + 1;
bool result = false;
AYear = 0; AMonth = 0; ADay = 0;
if (EquDays < 0) { return result; }// 暂不处理公元前的等效标准日
if (EquDays <= 577735)// 如果是 1582.10.4 (577735) 及之前为Julian历需要修正
{
int Diff = EquDays / (365 * 100) - EquDays / (365 * 400);
EquDays -= 10;// Gregorian 删去的 10 天
EquDays += 12 - Diff; // 补上多闰的 12 天中多闰的部分
}
int T = EquDays;
int Y = 1;
while (T >= D400)
{
T -= D400;
Y += 400;
}
int I = T / D100;
int D = T % D100;
if (I == 4)
{
I--;
D += D100;
}
Y += I * 100;
I = D / D4;
D = D % D4;
Y += I * 4;
I = D / D1;
D = D % D1;
if (I == 4)
{
I--;
D += D1;
}
Y += I;
int[] DayTable = null;
if (GetIsLeapYear(Y)) { DayTable = MonthDays2; } else { DayTable = MonthDays; }
int M = 0;
while (true)
{
I = DayTable[M];
if (D < I) break;
D -= I;
M++;
}
AYear = Y;
AMonth = M + 1;
ADay = D + 1;
result = true;
return result;
}
/// <summary>
/// 比较两个农历日期包括闰月信息1 大于2返回1、1等于2返回0、1小于2返回-1
/// </summary>
/// <param name="Year1"></param>
/// <param name="Month1"></param>
/// <param name="Day1"></param>
/// <param name="IsLeap1"></param>
/// <param name="Year2"></param>
/// <param name="Month2"></param>
/// <param name="Day2"></param>
/// <param name="IsLeap2"></param>
/// <returns></returns>
public static int Compare2LunarDay(int Year1, int Month1, int Day1, bool IsLeap1, int Year2, int Month2, int Day2, bool IsLeap2)
{
if (Year1 > Year2)
{
return 1;
}
else if (Year1 == Year2)
{
if (Month1 > Month2)
{
return 1;
}
else if (Month1 == Month2)
{
if (IsLeap1 == IsLeap2)
{
if (Day1 > Day2)
{
return 1;
}
else if (Day1 == Day2)
{
return 0;
}
else { return -1; }
}
else if (IsLeap1 && !IsLeap2)
{
return 1;
}
else { return -1; }
}
else
{
return -1;
}
}
else { return -1; }
}
/// <summary>
/// 获得某农历年月日(加是否闰月)的公历年月日
/// 该函数采用反向二分法查找
/// </summary>
/// <param name="ALunarYear"></param>
/// <param name="ALunarMonth"></param>
/// <param name="ALunarDay"></param>
/// <param name="IsLeapMonth"></param>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static bool GetDayFromLunar(int ALunarYear, int ALunarMonth, int ALunarDay, bool IsLeapMonth, out int AYear, out int AMonth, out int ADay)
{
AYear = -1; AMonth = -1; ADay = 1;
bool result = false;
if (IsLeapMonth && (GetLunarLeapMonth(ALunarYear) != ALunarMonth)) { return result; } // 该年无此闰月则退出
// 初始范围为本公历年一月一日到次年十二月三十一日,这样做的前提是历史上正月初一
// 没有落到公历年年前去。如果有这样的情况,可考虑适当扩大搜索范围,比如从
// 上一公历年一月一日到次年十二月三十一日,但又可能引发下面对搜索范围判断的错
int StartYear = ALunarYear;
int StartMonth = 1;
int StartDay = 1;
int StartDays = GetEquStandardDays(StartYear, StartMonth, StartDay);
int EndYear = ALunarYear + 1;
int EndMonth = 12;
int EndDay = 31;
int EndDays = GetEquStandardDays(EndYear, EndMonth, EndDay);
bool Only2 = false;
TLunarSearchDirection Lsd = TLunarSearchDirection.lsdInvalid;
int TempYear = StartYear;
int TempLunarYear = StartYear;
int OldTempLunarMonth = 0;
int Count = 0;
while (StartDays < EndDays)
{
Count++;
if (Count > 100) { break; } // 避免陷入死循环
int InterDays = (StartDays + EndDays) / 2;
if (Only2)
{ InterDays++; }
if (EndDays - StartDays == 1)
{ Only2 = true; }
GetDayFromEquStandardDays(InterDays, out TempYear, out int TempMonth, out int TempDay);
GetLunarMonthDayFromDay(TempYear, TempMonth, TempDay, out int TempLunarMonth, out int TempLunarDay, out bool TempIsLeap);
switch (Lsd)
{
case TLunarSearchDirection.lsdUp:
// 往未来搜索时如果农历月由大变小了,说明跨了年,年份得加一
if (TempLunarMonth < OldTempLunarMonth)
TempLunarYear++;
break;
case TLunarSearchDirection.lsdDown:
// 往过去搜索时如果农历月由小变大了,说明跨了年,年份得减一
if (TempLunarMonth > OldTempLunarMonth)
TempLunarYear--;
break;
}
switch (Compare2LunarDay(TempLunarYear, TempLunarMonth, TempLunarDay, TempIsLeap,
ALunarYear, ALunarMonth, ALunarDay, IsLeapMonth))
{
case -1:
StartDays = InterDays;
Lsd = TLunarSearchDirection.lsdUp; // 往未来搜索
break;
case 0:
AYear = TempYear;
AMonth = TempMonth;
ADay = TempDay;
return true;
case 1:
EndDays = InterDays;
Lsd = TLunarSearchDirection.lsdDown; // 往过去搜索
break;
}
OldTempLunarMonth = TempLunarMonth;
}
return false;
}
/// <summary>
/// 获取农历某一个月的总天数
/// </summary>
/// <param name="ALunarYear"></param>
/// <param name="ALunarMonth"></param>
/// <param name="IsLeapMonth"></param>
/// <returns></returns>
public static int GetLunarMonthDays(int ALunarYear, int ALunarMonth, bool IsLeapMonth = false)
{
// 该年无此闰月则退出
if (IsLeapMonth && (GetLunarLeapMonth(ALunarYear) != ALunarMonth)) { return -1; }
if (!GetDayFromLunar(ALunarYear, ALunarMonth, 1, IsLeapMonth, out int AYear, out int AMonth, out int ADay)) { return -1; }
//if(ALunarYear==1 && ALunarMonth == 9) { return 29; }
int EquDay1 = GetEquStandardDays(AYear, AMonth, ADay);
bool ALeap = false;
if (GetLunarLeapMonth(ALunarYear) == ALunarMonth)
{
if (IsLeapMonth)// 如果输入就是闰月,则后推一个月
{
ALunarMonth++;
if (ALunarMonth > 12)
{ ALunarMonth -= 12; ALunarYear++; }
}
else { ALeap = true; }
}
else
{
ALunarMonth++;
if (ALunarMonth > 12)
{
ALunarMonth -= 12; ALunarYear++;
}
}
if (!GetDayFromLunar(ALunarYear, ALunarMonth, 1, ALeap, out AYear, out AMonth, out ADay)) { return -1; }
int EquDay2 = GetEquStandardDays(AYear, AMonth, ADay);
return EquDay2 - EquDay1;
}
/// <summary>
/// 获取农历年份范围约1901-2101年
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetYear(DateTime dt)
{
return GetYear(dt.Year,dt.Month,dt.Day);
}
/// <summary>
/// 获取农历年份范围约0-9999年
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetYear(int AYear, int AMonth, int ADay)
{
GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth);
string yearTG = "甲乙丙丁戊己庚辛壬癸";
string yearDZ = "子丑寅卯辰巳午未申酉戌亥";
string yearSX = "鼠牛虎兔龙蛇马羊猴鸡狗猪";
int year = LunarYear;
int yTG = (LunarYear-3)%10;
if (yTG == 0) { yTG = 10; }
int yDZ = (AYear - 3) % 12;
if (yDZ == 0) { yDZ = 12; }
if (AMonth == 2)
{
GetJieQiInAYear(AYear, 2, out int _Month, out int _ADay, out int _, out int _);
if(ADay< _ADay) { yDZ--; if (yDZ == 0) { yDZ = 12; } }
}
else if (AMonth < 2) { yDZ--; if (yDZ == 0) { yDZ = 12; } }
string str = string.Format("[{0}]{1}{2}年", yearSX[yDZ-1], yearTG[yTG-1], yearDZ[yDZ-1]);
return str;
}
/// <summary>
/// 获取农历月份范围约1901-2101年
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetMonth(DateTime dt)
{
return GetMonth(dt.Year,dt.Month,dt.Day);
}
/// <summary>
/// 获取农历月份范围约0-9999年
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetMonth(int AYear, int AMonth, int ADay)
{
GetLunarMonthDayFromDay(AYear, AMonth, ADay, out int iMonth, out int TempLunarDay, out bool isLeapMonth);
string strMonth = isLeapMonth ? "闰" : "";
return strMonth + GetMonth(iMonth);
}
/// <summary>
/// 获取中文表示的农历月份
/// </summary>
/// <param name="iMonth"></param>
/// <returns></returns>
public static string GetMonth(int iMonth)
{
string szText = "正二三四五六七八九十";
var strMonth = "";
if (iMonth <= 10)
{
strMonth += szText.Substring(iMonth - 1, 1);
}
else if (iMonth == 11)
{
strMonth += "冬";
}
else
{
strMonth += "腊";
}
return strMonth + "月";
}
/// <summary>
/// 获取农历日范围约1901-2101年
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetDay(DateTime dt)
{
return GetDay(dt.Year,dt.Month,dt.Day);
}
/// <summary>
/// 获取农历日范围约0-9999年
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetDay(int AYear, int AMonth, int ADay)
{
GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMont);
return GetDay(LunarDay);
}
/// <summary>
/// 获取农历日范围约0-9999年
/// </summary>
/// <param name="iDay"></param>
/// <returns></returns>
public static string GetDay(int iDay)
{
string szText1 = "初十廿三";
string szText2 = "一二三四五六七八九十";
string strDay="";
if (iDay == 20)
{
strDay = "二十";
}
else if (iDay == 30)
{
strDay = "三十";
}
else if (iDay>0)
{
strDay = szText1.Substring((iDay - 1) / 10, 1);
strDay = strDay + szText2.Substring((iDay - 1) % 10, 1);
}
return strDay;
}
/// <summary>
/// 获取节气范围约1901-2101年
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetSolarTerm(DateTime dt)
{
int index = GetJieQiFromDay(dt.Year, dt.Month, dt.Day);
if (index == -1)
{ return ""; }
return JQ[index];
}
/// <summary>
/// 获取节气范围约0-9999年
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetSolarTerm(int AYear, int AMonth, int ADay)
{
int index = GetJieQiFromDay(AYear, AMonth, ADay);
if (index == -1)
{ return ""; }
return JQ[index];
}
/// <summary>
/// 返回y年第n个节气如小寒为1的日差天数值pd取值真假分别表示平气和定气
/// </summary>
/// <param name="AYear"></param>
/// <param name="N"></param>
/// <param name="pd">pd取值真假分别表示平气和定气</param>
/// <returns></returns>
public static double GetJieQiDayTimeFromYear(int AYear, int N, bool pd)
{
double juD, tht, yrD, shuoD;
if (AYear <= 0) { AYear++; } // 对没有公元 0 年的调整
juD = AYear * (365.2423112 - 6.4e-14 * (AYear - 100) * (AYear - 100)
- 3.047e-8 * (AYear - 100)) + 15.218427 * N + 1721050.71301;
tht = 3e-4 * AYear - 0.372781384 - 0.2617913325 * N;
yrD = (1.945 * Math.Sin(tht) - 0.01206 * Math.Sin(2 * tht)) * (1.048994 - 2.583e-5 * AYear);
shuoD = -18e-4 * Math.Sin(2.313908653 * AYear - 0.439822951 - 3.0443 * N);
return (pd) ?(juD + yrD + shuoD - GetEquStandardDays(AYear, 1, 0) - 1721425):(juD - GetEquStandardDays(AYear, 1, 0) - 1721425); // 定气
}
private static TCalendarType GetCalendarType(int AYear, int AMonth, int ADay)
{
if (AYear > 1582)
return TCalendarType.ctGregorian;
else if (AYear < 1582)
return TCalendarType.ctJulian;
else if (AMonth < 10)
return TCalendarType.ctJulian;
else if ((AMonth == 10) && (ADay <= 4))
return TCalendarType.ctJulian;
else if ((AMonth == 10) && (ADay >= 5 && ADay <= 14))
return TCalendarType.ctInvalid;
else
return TCalendarType.ctGregorian;
}
/// <summary>
/// 获取等效标准日数
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static int GetEquStandardDays(int AYear, int AMonth, int ADay)
{
TCalendarType AType = GetCalendarType(AYear, AMonth, ADay);
if (AType == TCalendarType.ctGregorian)
{
int aa = (AYear - 1) * 365 + ((AYear - 1) / 4) - ((AYear - 1) / 100)
+ ((AYear - 1) / 400);
return (AYear - 1) * 365 + ((AYear - 1) / 4) - ((AYear - 1) / 100)
+ ((AYear - 1) / 400) + GetDayFromYearBegin(AYear, AMonth, ADay);
}
else if (AType == TCalendarType.ctJulian)
{
return (AYear - 1) * 365 + ((AYear - 1) / 4)
+ GetDayFromYearBegin(AYear, AMonth, ADay) - 2;
}
return 0;
}
private static int GetDayFromYearBegin(int AYear, int AMonth, int ADay)
{
int[] JQData1 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int[] JQData2 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
bool IsLeapYear = GetIsLeapYear(AYear);
if (IsLeapYear)
{
return JQData2[AMonth - 1] + ADay;
}
else
{
return JQData1[AMonth - 1] + ADay;
}
}
/// <summary>
/// 取本月天数,不考虑 1582 年 10 月的特殊情况
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <returns></returns>
private static int GetMonthDays(int AYear, int AMonth)
{
switch (AMonth)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
if (GetIsLeapYear(AYear))
{ return 29; }
else { return 28; }
default:
return 0;
}
}
/// <summary>
/// 获取节气范围约1901-2101年
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static int GetJieQiFromDay(DateTime dt)
{
return GetJieQiFromDay(dt.Year, dt.Month, dt.Day);
}
/// <summary>
/// 获取节气范围约0-9999年
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static int GetJieQiFromDay(int AYear, int AMonth, int ADay)
{
int Idx;
int result = -1;
Idx = (AMonth - 1) * 2;
if (ADay >= 15) { Idx++; }
if (GetJieQiInAYear(AYear, Idx, out int Month, out int Day, out int DummyHour, out int DummyMinute))
{
if ((AMonth == Month) && (ADay == Day))
{
// 此时 I 表示 0 是小寒
result = Idx - 2;
// 转换成 0 是立春
if (result < 0)
result += 24;
return result;
}
}
return result;
}
/// <summary>
/// 获取节气
/// </summary>
/// <param name="AYear"></param>
/// <param name="N"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <param name="AHour"></param>
/// <param name="AMinitue"></param>
/// <returns></returns>
public static bool GetJieQiInAYear(int AYear, int N, out int AMonth, out int ADay, out int AHour, out int AMinitue)
{
double Days;
int Day;
bool Result = N >= 0 && N <= 23;
AMonth = 1;
if (Result)
{
Days = GetJieQiDayTimeFromYear(AYear, N + 1,true);
for (int i = 1; i <= 12; i++)
{
Day = GetMonthDays(AYear, i);
if (Days > Day)
{
Days = Days - Day;
}
else
{
AMonth = i; break;
}
}
ADay = Convert.ToInt32(Math.Floor(Days));
Days = Days - ADay;
AHour = Convert.ToInt32(Math.Floor(Days * 24));
Days = Days * 24 - AHour;
AMinitue = Convert.ToInt32(Math.Round(Days * 60));
// 如果分恰好等于 60则小时数要加一如果小时恰好到了 24则天数要加一
if (AMinitue >= 60)
{
AMinitue -= 60; AHour++;
if (AHour >= 24) { AHour -= 24; ADay++; }
// 节气不在月底,因此一般不用考虑天数加一后月份改变的情况
}
}
else
{
AMonth = 0;
ADay = 0;
AHour = 0;
AMinitue = 0;
}
return Result;
}
private static bool GetIsLeapYear(int AYear)
{
if (GetCalendarType(AYear, 1, 1) == TCalendarType.ctGregorian)
{
return (AYear % 4 == 0) && ((AYear % 100 != 0) || (AYear % 400 == 0));
}
else if (AYear >= 0)
{
return (AYear % 4 == 0);
}
else // 需要独立判断公元前的原因是没有公元 0 年
{
return (AYear - 3) % 4 == 0;
}
}
/// <summary>
/// 获取公历节日
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetHoliday(DateTime dt)
{
return GetHoliday(dt.Year, dt.Month,dt.Day);
}
/// <summary>
/// 获取公历节日
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetHoliday(int AYear, int AMonth, int ADay)
{
string strReturn = "";
object g = gHoliday[AMonth.ToString("00") + ADay.ToString("00")];
if (g != null)
{
strReturn = GetHolidayStr(g.ToString(), new DateTime(AYear, AMonth, ADay));
}
return strReturn;
}
private static string GetHolidayStr(string str,DateTime dt)
{
if (str.IndexOf(":") > 0)
{
string[] g_split = str.Split(':');
string[] year_split = g_split[1].Split('-');
if (year_split.Length == 1)
{
if (dt.Year >= year_split[0].ToInt())
{ return g_split[0]; }
else { return ""; }
}
else if (year_split.Length == 2) { if (dt.Year >= year_split[0].ToInt() && dt.Year <= year_split[1].ToInt()) { return g_split[0]; } else { return ""; } }
}
return str;
}
/// <summary>
/// 获取指定月份的第n个星期几的节日
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetWeekHoliday(DateTime dt)
{
string strReturn = "";
int week= RyDate.GetWeek_index(dt);
int week_num = (dt.Day / 7) + 1;
if(dt.Day % 7 == 0) { week_num--; }
object g = wHoliday[dt.Month.ToString("00") + week_num.ToString()+ week.ToString()];
if (g != null)
{
strReturn = GetHolidayStr(g.ToString(),dt);
}
if(dt.AddDays(7).Month!=dt.Month)
{
object g1 = wHoliday[dt.Month.ToString("00") + "0" + week.ToString()];
if (g1 != null)
{
strReturn +=" "+ GetHolidayStr(g1.ToString(), dt);
}
}
return strReturn.Trim();
}
/// <summary>
/// 返回星座范围约1901-2101年
/// </summary>
public static string GetXingzuo(DateTime solarDateTime)
{
return GetXingzuo(solarDateTime.Month, solarDateTime.Day);
}
/// <summary>
/// 返回星座范围约0-9999年
/// </summary>
public static string GetXingzuo(int AMonth, int ADay)
{
int constellation = -1;
int Y = AMonth * 100 + ADay;
if (((Y >= 321) && (Y <= 419))) { constellation = 0; }
else if ((Y >= 420) && (Y <= 520)) { constellation = 1; }
else if ((Y >= 521) && (Y <= 620)) { constellation = 2; }
else if ((Y >= 621) && (Y <= 722)) { constellation = 3; }
else if ((Y >= 723) && (Y <= 822)) { constellation = 4; }
else if ((Y >= 823) && (Y <= 922)) { constellation = 5; }
else if ((Y >= 923) && (Y <= 1022)) { constellation = 6; }
else if ((Y >= 1023) && (Y <= 1121)) { constellation = 7; }
else if ((Y >= 1122) && (Y <= 1221)) { constellation = 8; }
else if ((Y >= 1222) || (Y <= 119)) { constellation = 9; }
else if ((Y >= 120) && (Y <= 218)) { constellation = 10; }
else if ((Y >= 219) && (Y <= 320)) { constellation = 11; }
string con = "白羊金牛双子巨蟹狮子处女天秤天蝎射手摩羯水瓶双鱼";
return con.Substring(2 * constellation, 2) + "座";
}
/// <summary>
/// 获取农历节日
/// </summary>
/// <param name="AYear"></param>
/// <param name="AMonth"></param>
/// <param name="ADay"></param>
/// <returns></returns>
public static string GetChinaHoliday(int AYear, int AMonth, int ADay)
{
string strReturn = "";
GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth);
int year = LunarYear;
int iMonth = LunarMonth;
int iDay = LunarDay;
if (iMonth == 12 && GetLunarMonthDays(LunarYear, LunarMonth, IsLeapMonth) == iDay)
{
strReturn = "除夕";
}
else if (!IsLeapMonth)
{
object n = nHoliday[iMonth.ToString("00") + iDay.ToString("00")];
if (n != null)
{
if (strReturn == "")
{
strReturn = GetHolidayStr(n.ToString(), new DateTime(AYear, AMonth, ADay));
}
else
{
strReturn += " " + GetHolidayStr(n.ToString(), new DateTime(AYear, AMonth, ADay));
}
}
}
return strReturn;
}
/// <summary>
/// 获取农历节日
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static string GetChinaHoliday(DateTime dt)
{
return GetChinaHoliday(dt.Year,dt.Month,dt.Day);
}
/// <summary>
/// 判断y年m月(1,2,..,12,下同)d日是Gregorian历还是Julian历opt=1,2,3分别表示标准日历,Gregorge历和Julian历,是则返回1是Julian历则返回0若是Gregorge历所删去的那10天则返回-1
/// </summary>
private static int IfGregorian(int y, int m, int d, int opt)
{
if (opt == 1)
{
if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d > 14))
return (1); //Gregorian
else
if (y == 1582 && m == 10 && d >= 5 && d <= 14)
return (-1); //空
else
return (0); //Julian
}
if (opt == 2)
return (1); //Gregorian
if (opt == 3)
return (0); //Julian
return (-1);
}
/// <summary>
/// 返回阳历y年m月d日的日差天数在y年年内所走过的天数如2000年3月1日为61
/// </summary>
private static int DayDifference(int y, int m, int d)
{
int ifG = IfGregorian(y, m, d, 1);
int[] monL = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (ifG == 1)
if ((y % 100 != 0 && y % 4 == 0) || (y % 400 == 0))
monL[2] += 1;
else
if (y % 4 == 0)
monL[2] += 1;
int v = 0;
for (int i = 0; i <= m - 1; i++)
{
v += monL[i];
}
v += d;
if (y == 1582)
{
if (ifG == 1)
v -= 10;
if (ifG == -1)
v = 0; //infinity
}
return v;
}
/// <summary>
/// 返回阳历y年日差天数为x时所对应的月日数如y=2000x=274时返回1001(表示10月1日即返回100*m+d)
/// </summary>
private static double AntiDayDifference(int y, double x)
{
int m = 1;
for (int j = 1; j <= 12; j++)
{
int mL = DayDifference(y, j + 1, 1) - DayDifference(y, j, 1);
if (x <= mL || j == 12)
{
m = j;
break;
}
else
x -= mL;
}
return 100 * m + x;
}
/// <summary>
/// 获取指定日期的节气。
/// </summary>
/// <param name="year">要获取的年</param>
/// <param name="month">要获取的月</param>
/// <returns></returns>
/// <remarks>
/// 立春:立是开始的意思,春是蠢动,表示万物开始有生气,这一天春天开始。
/// 雨水:降雨开始,雨水将多。
/// 惊蛰:春雷响动,惊动蛰伏地下冬眠的生物,它们将开始出土活动。
/// 春分:这是春季九十天的中分点,这一天昼夜相等,所以古代曾称春分秋分为昼夜分。
/// 清明:明洁晴朗,气候温暖,草木开始萌发繁茂。
/// 谷雨:雨生百谷的意思。雨水增多,适时的降雨对谷物生长很为有利。
/// 立夏:夏天开始,万物渐将随温暖的气候而生长。
/// 小满:满指籽粒饱满,麦类等夏热作物这时开始结籽灌浆,即将饱满。
/// 芒种:有芒作物开始成熟,此时也是秋季作物播种的最繁忙时节。
/// 夏至:白天最长,黑夜最短,这一天中午太阳位置最高,日影短至终极,古代又称这一天为日北至或长日至。
/// 小暑:暑是炎热,此时还未到达最热。
/// 大暑:炎热的程度到达高峰。
/// 立秋:秋天开始,植物快成熟了。
/// 处暑:处是住的意思,表示暑气到此为止。
/// 白露:地面水气凝结为露,色白,是天气开始转凉了。
/// 秋分:秋季九十天的中间,这一天昼夜相等,同春分一样,太阳从正东升起正西落下。
/// 寒露:水露先白而后寒,是气候将逐渐转冷的意思。
/// 霜降:水气开始凝结成霜。
/// 立冬:冬是终了,作物收割后要收藏起来的意思,这一天起冬天开始。
/// 小雪:开始降雪,但还不多。
/// 大雪:雪量由小增大。
/// 冬至:这一天中午太阳在天空中位置最低,日影最长,白天最短, 黑夜最长,古代又称短日至或日南至。
/// 小寒:冷气积久而为寒,此时尚未冷到顶点。
/// 大寒:天候达到最寒冷的程度
/// </remarks>
public static SolarTerm[] GetSolarTerm(int year, int month)
{
string[] lunarHoliDayName ={
"小寒", "大寒", "立春", "雨水","惊蛰", "春分", "清明", "谷雨","立夏", "小满", "芒种", "夏至",
"小暑", "大暑", "立秋", "处暑","白露", "秋分", "寒露", "霜降","立冬", "小雪", "大雪", "冬至"};
SolarTerm[] solarTerm = new SolarTerm[2];
for (int n = month * 2 - 1; n <= month * 2; n++)
{
SolarTerm st = new SolarTerm();
double dd = GetJieQiDayTimeFromYear(year, n, true);
double sd1 = AntiDayDifference(2005, Math.Floor(dd));
double sm1 = Math.Floor(sd1 / 100);
int h = (int)Math.Floor(GetTail(dd) * 24);
int min = (int)Math.Floor((GetTail(dd) * 24 - h) * 60);
int mmonth = (int)Math.Ceiling((double)n / 2);
int day = (int)sd1 % 100;
st.SolarTermDateTime = new DateTime(year, mmonth, day, h, min, 0);
st.Name = lunarHoliDayName[n - 1];
solarTerm[n - month * 2 + 1] = st;
}
return solarTerm;
}
#region
/// <summary>
/// 获取年柱。
/// </summary>
public static int GetEraYear(DateTime solarDateTime)
{
int g = (solarDateTime.Year - 1900 + 36) % 60;
if ((DayDifference(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) + solarDateTime.Hour / 24) < GetJieQiDayTimeFromYear(solarDateTime.Year, 3, true) - 1)
{//判断是否过立春
g -= 1;
}
return g + 1;
}
/// <summary>
/// 获得月柱
/// </summary>
/// <param name="solarDateTime"></param>
/// <returns></returns>
public static int GetEraMonth(DateTime solarDateTime)
{
int v = ((solarDateTime.Year - 1900) * 12 + solarDateTime.Month + 12) % 60;
if (solarDateTime.Day <= GetSolarTerm(solarDateTime.Year, solarDateTime.Month)[0].SolarTermDateTime.Day)
v -= 1;
return v + 1;
}
/// <summary>
/// 获取日柱。
/// </summary>
public static int GetEraDay(DateTime solarDateTime)
{
double gzD = (solarDateTime.Hour < 23) ? GetEquStandardDays(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) : GetEquStandardDays(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) + 1;
return (int)Math.Round((double)GetRemain((int)gzD + 15, 60));
}
/// <summary>
/// 返回甲子数x对应的天干数如33为3
/// </summary>
private static int Gan(int x)
{
return x % 10;
}
/// <summary>
/// 返回甲子数x对应的地支数如33为9
/// </summary>
private static int Zhi(int x)
{
return x % 12;
}
/// <summary>
/// 获取日的天干地支
/// </summary>
/// <param name="solarDateTime"></param>
/// <returns></returns>
public static string GetDayTGDZ(DateTime solarDateTime)
{
string yearTG = "甲乙丙丁戊己庚辛壬癸";
string yearDZ = "子丑寅卯辰巳午未申酉戌亥";
int dG = Gan(GetEraDay(solarDateTime));
int dZ = Zhi(GetEraDay(solarDateTime));
if (dG == 0) { dG = 10; }
if (dZ == 0) { dZ = 12; }
return yearTG.Substring(dG - 1, 1) + yearDZ.Substring(dZ - 1, 1);
}
/// <summary>
/// 返回甲子数x对应的天干字符串
/// </summary>
public static string ToStringWithCelestialStem(int x)
{
return "癸甲乙丙丁戊己庚辛壬".Substring(x % 10, 1);
}
/// <summary>
/// 返回甲子数x对应的地支字符串
/// </summary>
public static string ToStringWithTerrestrialBranch(int x)
{
return "亥子丑寅卯辰巳午未申酉戌".Substring(x % 12, 1);
}
/// <summary>
/// 返回甲子数x对应的干支字符串
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static string ToStringWithSexagenary(int x)
{
return ToStringWithCelestialStem(x) + ToStringWithTerrestrialBranch(x);
}
#endregion
/// <summary>
/// 获取三伏开始时间
/// </summary>
/// <param name="Year"></param>
/// <param name="index">0表示1伏1表示2伏2表示3伏</param>
/// <returns></returns>
public static DateTime Get3Fu(int Year, int index)
{
if (index <= 1)
{
var day_count = GetJieQiDayTimeFromYear(Year, 12, true);
var xiazhi_date = new DateTime(Year, 1, 1).AddDays(day_count - 1).Date; //获取夏至 //ToStringWithSexagenary(GetEraDay(xiazhi_date));
var first_geng_date = xiazhi_date.AddDays(1);//获取夏至后的首个庚日
for (int i = 0; i < 20; i++)
{
if (ToStringWithCelestialStem(GetEraDay(first_geng_date.AddDays(i))) == "庚")
{
first_geng_date = first_geng_date.AddDays(i); break;
}
}
if (index == 0) { return first_geng_date.AddDays(20); }
else if (index == 1) { return first_geng_date.AddDays(30); }
}
else if (index == 2)//末伏开始的时间是立秋后的第一个庚日
{
var day_count = GetJieQiDayTimeFromYear(Year, 15, true);//立秋
var liqiu_date = new DateTime(Year, 1, 1).AddDays(day_count - 1).Date; //获取立秋 //ToStringWithSexagenary(GetEraDay(xiazhi_date));
var first_geng_date = liqiu_date.AddDays(1);//获取立秋后的首个庚日
for (int i = 0; i < 20; i++)
{
if (ToStringWithCelestialStem(GetEraDay(first_geng_date.AddDays(i))) == "庚")
{
first_geng_date = first_geng_date.AddDays(i); break;
}
}
return first_geng_date;
}
return new DateTime(2000, 1, 1);
}
}
/// <summary>
/// 节气
/// </summary>
public class SolarTerm
{
private DateTime solarTermDate;
private string name;
/// <summary>
/// 节气的时间。
/// </summary>
public DateTime SolarTermDateTime
{
get
{
return solarTermDate;
}
set
{
solarTermDate = value;
}
}
/// <summary>
/// 节气名。
/// </summary>
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}