代码: 全选
//table.h
#define YEAR_SRT 1901
#define YEAR_NUM 200
#define THIS_YEAR(x) Year_Info[x - YEAR_SRT]
static long Year_Info[YEAR_NUM] = {
/*
YEAR:LC:ZY:ZYDAY:L:LEAP:MONTHS
1901:01:10:10011:0:0000:010010101111
年 立 春 春 闰闰无 十非的
份 春 节 节 月月则 二闰大
日 阳 阳 大月为 个月小
偏 历 历 小份零
移 月 日
量 份 期
*/
0x1A604AF, 0x2900A57, 0x27A554D, 0x2A00D27, 0x1880D95, //1901-1905
0x2734655, 0x29A056B, 0x28409AD, 0x16C255D, 0x29404AF, //1906-1910
0x27C6A5B, 0x2A40A4D, 0x18C0D25, 0x1755D25, 0x29C0B55, //1911-1915
0x2860D6A, 0x16E2ADA, 0x196095B, 0x2837497, 0x2A80497, //1916-1920
0x1900A4B, 0x1785B4B, 0x2A006A5, 0x28A06D5, 0x1714AB5, //1921-1925
0x19A02B7, 0x2840957, 0x26E252F, 0x1940497, 0x17C6656, //1926-1930
0x2A20D4A, 0x28C0EA5, 0x17556A9, 0x19C05AD, 0x28802B7, //1931-1935
0x271386E, 0x196092E, 0x17F7C8D, 0x2A60C95, 0x2900D4B, //1936-1940
0x1776D8A, 0x19E0B55, 0x28A056B, 0x2734A5B, 0x19A025D, //1941-1945
0x184092D, 0x16C2D2B, 0x2940A95, 0x17A7B55, 0x1A206CB, //1946-1950
0x18C0B55, 0x2775535, 0x19C04DB, 0x1860A5B, 0x1713457, //1951-1955
0x298052B, 0x17E8A9B, 0x1A40E95, 0x19006AB, 0x2786AEA, //1956-1960
0x19E0AB5, 0x18A04B7, 0x1724AAE, 0x29A0A57, 0x1840527, //1961-1965
0x16A3F26, 0x1920D95, 0x27C75B5, 0x1A2056B, 0x18C096D, //1966-1970
0x17654DD, 0x29E04AD, 0x1860A4D, 0x16E4D4D, 0x1960D25, //1971-1975
0x27E8D55, 0x1A40B55, 0x18E0B6A, 0x179695A, 0x2A0095B, //1976-1980
0x18A049B, 0x1724A97, 0x19A0A4B, 0x184AB27, 0x1A806A5, //1981-1985
0x19206D5, 0x17A6AF4, 0x1A20AB6, 0x18C0957, 0x17654AF, //1986-1990
0x19E0497, 0x188064B, 0x16E374A, 0x1940EA5, 0x17E86B5, //1991-1995
0x1A605AD, 0x18E0AB6, 0x178596D, 0x1A0092F, 0x18A0C96, //1996-2000
0x1704D95, 0x1980D4B, 0x1820DA5, 0x16C2755, 0x192056B, //2001-2005
0x17A7ABB, 0x1A4025D, 0x18E092D, 0x1745CAB, 0x19C0A95, //2006-2010
0x1860B4B, 0x16E4BAA, 0x1940AD5, 0x17E955D, 0x1A604BB, //2011-2015
0x1900A5B, 0x0796517, 0x1A0052B, 0x18A0A93, 0x1724795, //2016-2020
0x09806AB, 0x1820AD5, 0x16C25B5, 0x19404B7, 0x07A6A6E, //2021-2025
0x1A20A4E, 0x18C0D26, 0x1745EA6, 0x09A0D53, 0x18605AB, //2026-2030
0x16E376A, 0x196096D, 0x07EB4AF, 0x1A604AD, 0x1900A4D, //2031-2035
0x1796D0B, 0x09E0D25, 0x1880D53, 0x0705BD4, 0x1980B5A, //2036-2040
0x082056D, 0x16C255B, 0x194049B, 0x17C7A57, 0x0A20A4B, //2041-2045
0x18C0AA5, 0x1755B25, 0x19C06D3, 0x0840ADA, 0x06F34B6, //2046-2050
0x1960937, 0x182849F, 0x0A60497, 0x090064B, 0x179668A, //2051-2055
0x19E0EA5, 0x08806AB, 0x0714A6C, 0x0980AAE, 0x184092E, //2056-2060
0x06A3D2E, 0x0920C96, 0x17A7D55, 0x1A20D4B, 0x08A0DA5, //2061-2065
0x07455D5, 0x19C056B, 0x1860A6D, 0x06E455D, 0x096052D, //2066-2070
0x17E8A9B, 0x1A60A95, 0x08E0B4B, 0x0766B6A, 0x19E0AD5, //2071-2075
0x18A055B, 0x0704ABA, 0x0980A5B, 0x184052B, 0x16C3B27, //2076-2080
0x0920693, 0x07A7733, 0x0A206AB, 0x18C0AD5, 0x07554B5, //2081-2085
0x09C04B7, 0x0860A57, 0x170454E, 0x0940D16, 0x07C8E96, //2086-2090
0x0A40D52, 0x18E0DAA, 0x07766AA, 0x09E056D, 0x08A04AF, //2091-2095
0x1724A9D, 0x0980A2D, 0x0820D15, 0x06A2F25, 0x1920D53 //2096-2100
};
[/c]
[c]
//lunar.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include "table.h"
#ifndef uint
typedef unsigned int uint;
#endif
uint dayofspring(const uint year)
{
if (((THIS_YEAR(year) & 0xC00000) >> 22) == 1)
return ((THIS_YEAR(year) & 0x3E0000) >> 17) - 1;
return ((THIS_YEAR(year) & 0x3E0000) >> 17) - 1 + 31;
}
uint dayofyear(const uint year, const uint mon, const uint mday)
{
static int monofday[12] = {0, 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
uint day = 0;
day = monofday[mon - 1] + mday - 1;
if ((mon > 2) &&
((((year % 4) == 0) && ((year % 100) != 0)) ||
((year % 400) == 0)))
day++;
return day;
}
uint dayoffset(const uint year, const uint mon, const uint mday)
{
uint yday = dayofyear(year, mon, mday);
uint dspr = dayofspring(year);
if (yday >= dspr) return (yday - dspr);
uint last = dayoffset(year - 1, 12, 31);
if (mon == 1) return (last + mday);
return (last + 31 + mday);
}
uint monday(const uint year, const uint dayoffset)
{
uint months = 12;
uint monday = 0;
uint leap = ((THIS_YEAR(year) & 0xF000) >> 12);
uint nleap = ((THIS_YEAR(year) & 0x10000) >> 16);
uint lmon = 0x1000;
if (leap) {
months = 13;
monday |= (leap << 9);
monday |= (nleap << 13);
}
uint i = 0;
uint left = dayoffset;
for (i = 1; i <= months ; i++)
{
uint mdays = 0;
if (!leap || (i != (leap + 1))) {
mdays = ((lmon >> i) & THIS_YEAR(year))? 30 : 29;
} else {
i--;
leap = 0;
months = 12;
mdays = (nleap? 30 : 29);
if (left < mdays) i = 0;
}
if (left < mdays) {
monday |= (i << 5);
monday |= left;
return monday;
}
left -= mdays;
}
return 0;
}
uint getrealmonday(const uint year, const uint mon, const uint mday)
{
if (dayofyear(year, mon, mday) >= dayofspring(year)) {
return (monday(year, dayoffset(year, mon, mday)));
}
return (monday(year - 1, dayoffset(year, mon, mday)));
}
void ganzhi(const uint year, const uint mon, const uint mday)
{
static char* tgGB[] = { "甲", "乙", "丙", "丁", "戊",
"己", "庚", "辛", "壬", "癸" };
static char* dzGB[] = { "子", "丑", "寅", "卯", "辰",
"巳", "午", "未", "申", "酉", "戌", "亥" };
uint i = 6, j = 8;
uint realyear = year;
uint lcoffset = ((0x3000000 & THIS_YEAR(year)) >> 24);
//懒得算立春日了 -_-||
if (dayofyear(year, mon, mday) < (31 + 2 + lcoffset))
realyear -= 1;
uint noun = realyear % 60;
i += noun;
i %= 10;
j += noun;
j %= 12;
printf("%s%s年", tgGB[i], dzGB[j]);
}
void printmonday(uint monday)
{
static char* numGB[] = { "初一", "初二", "初三", "初四", "初五",
"初六", "初七", "初八", "初九", "初十",
"十一", "十二", "十三", "十四", "十五",
"十六", "十七", "十八", "十九", "二十",
"廿一", "廿二", "廿三", "廿四", "廿五",
"廿六", "廿七", "廿八", "廿九", "三十" };
static char* monGB[] = { "正月", "二月", "三月", "四月", "五月",
"六月", "七月", "八月", "九月", "十月", "冬月", "腊月" };
uint mon = ((monday >> 5) & 0xF);
uint mday = (monday & 0x1F);
if (!mon) {
printf("闰%s%s\n", monGB[((monday >> 9) & 0xF) - 1], numGB[mday]);
} else {
printf("%s%s\n", monGB[mon - 1], numGB[mday]);
}
}
void usage(char* argv)
{
fprintf(stderr, "%s [%d-%d] [1-12] [1-31]\n", argv,
YEAR_SRT, YEAR_SRT + YEAR_NUM - 1);
return;
}
int isdate(const uint year, const uint mon, const uint mday)
{
if (mon > 12) return 0;
if (mon == 2) {
if ((((year % 4) == 0) && ((year % 100) != 0)) ||
((year % 400) == 0)) {
if (mday > 29) return 0;
return 1;
}
if (mday > 28) return 0;
return 1;
}
if ((mon == 1) || (mon == 3) || (mon == 5) || (mon == 7) || (mon == 8) ||
(mon == 10) || (mon == 12)) {
if (mday > 31) return 0;
return 1;
}
if ((mon == 2) || (mon == 4) || (mon == 6) || (mon == 9) || (mon == 11)) {
if (mday > 30) return 0;
return 1;
}
return 0;
}
int main(int argc, char* argv[])
{
if ((argc != 1) && (argc != 4)) {
usage(argv[0]);
return 1;
}
uint year = 0, mon = 0, mday = 0;
int i = 1, j =0;
if (argc == 4) {
for (i = 1; i < 4; i++) {
for (j = 0; j < strlen(argv[i]); j++) {
if (!isdigit(* (argv[i] + j))) {
usage(argv[0]);
return 1;
}
}
}
year = atoi(argv[1]);
mon = atoi(argv[2]);
mday = atoi(argv[3]);
if (!isdate(year, mon, mday)) {
usage(argv[0]);
return 1;
}
}
if(argc == 1) {
time_t cur_t = 0;
time(&cur_t);
struct tm* cur_tm = NULL;
cur_tm = localtime(&cur_t);
year = (cur_tm->tm_year) + 1900;
mon = (cur_tm->tm_mon) + 1;
mday = cur_tm->tm_mday;
}
if ((year < YEAR_SRT) || (year > (YEAR_SRT + YEAR_NUM - 1))) {
usage(argv[0]);
return 1;
}
if ((year == YEAR_SRT) &&
(dayofyear(year, mon, mday) < dayofspring(year))) {
usage(argv[0]);
return 1;
}
ganzhi(year, mon, mday);
uint monday = getrealmonday(year, mon, mday);
if (monday) printmonday(monday);
return 0;
}