RaUI/Source/MyDb/SysFuns/ChinaDate.cs
2020-11-28 15:03:57 +08:00

1817 lines
74 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}