51 Almanaque
///Tabla de datos mensuales
código uchar día _ código 1【9】= { 0x 0, 0x1f, 0x3b, 0x5a, 0x78, 0x97, 0xb5 , 0xd4, 0x F3 };
código uint día _ código 2【3】= { 0x 111, 0x130, 0x 14e }
/*
; Función: Entrada de datos del calendario solar BCD y salida de datos del calendario lunar BCD (solo se permiten 1901-2099).
Ejemplo de llamada a función: conversión(c_sun, año_sun, mes_sun, día_sun)
Por ejemplo, calcule la conversión del 16 de junio de 2004 (0, 0x4, 0x10, 0x16);
C_sun, Year_Sun, Month_Sun y Day_Sun son todos datos BCD, C_Sun es la marca del siglo, c_sun=0 es 21.
Ji, c_sun=1 es del siglo XIX.
Después de llamar a esta función, los datos originales permanecen sin cambios. Lea C_moon, Year_moon, Month_moon y Day_moon para obtener los datos BCD del calendario lunar.
*/
Bit c_moon
Datos uchar año_mes, mes_mes, día_mes, semana;
/*Subfunción, utilizada para lea el mes grande o pequeño del calendario lunar en la tabla de datos.
Si el mes es grande, devuelve 1, si el mes es pequeño, devuelve 0*/
bit get_moon_day(uchar Month_p, uint table_addr)
{
temperatura uchar;
cambiar (mes p)
{
Caso 1:{ temp = año _ código[table _ addr]& amp ;0x08 p>
if (temp == 0) devuelve (0); else devuelve (1);
Caso 2: { temp = año _ código [tabla _ dirección]& amp; /p>
if (temp == 0) devuelve (0); else devuelve (1 }
Caso 3: { temp = año _ código [tabla _ dirección] &0x02
if (temp == 0) devuelve (0); else devuelve (1 }
Caso 4: { temp = año _ código [table _ addr 】& 0x 01;
if (temp == 0) devuelve (0); else devuelve (1 }
Caso 5: { temp = año _ código【 table_addr+1]&0x80
if (temp = = 0) devuelve (0); else devuelve (1);}
Caso 6: { temp = año _ código[table_addr+1]&0x40
si (temp == 0) devuelve (0); de lo contrario, devuelve (1);}
Caso 7:{ temp = código_año[table_addr+1]&0x20 p>
si (temp == 0) devuelve (0); de lo contrario, devuelve (1);}
Situación 8:{ temp = año _ código [tabla _ dirección+1] & 10;
si (temp == 0) devuelve (0); de lo contrario, devuelve (1)
Caso 9:{ temp = código_año[table_addr+1]&0x08;
if (temp == 0) devuelve (0); else devuelve (1);}
Caso 10:{temp = código_año[table_addr+1]&0x04 p>
si (temp==0) devuelve (0); de lo contrario, devuelve (1);}
Caso 11:{ temp = código_año[table_addr+1]&0x02
if (temp == 0) return (0); else Return (1);
Caso 12: { temp = año _ código [table _ addr+1] & 0x 01; /p>
if (temp == 0) devuelve (0); de lo contrario devuelve (1 }
Caso 13: { temp = año _ código [tabla _ dirección+2] & amp ; 0x80
if (temp = = 0) Devuelve (0); en caso contrario, devuelve (1);}
}
}
/*
Función: Entrada de datos del calendario gregoriano BCD, salida de datos del calendario lunar BCD (solo se permiten 1901-2099).
Ejemplo de llamada a función: conversión(c_sun, año_sun, mes_sun, día_sun)
Por ejemplo, calcule la conversión del 16 de junio de 2004 (0, 0x4, 0x10, 0x16);
C_sun, Year_Sun, Month_Sun y Day_Sun son todos datos BCD, C_Sun es la marca del siglo, c_sun=0 es 21.
Ji, c_sun=1 es del siglo XIX.
Después de llamar a esta función, los datos originales permanecen sin cambios. Lea C_moon, Year_moon, Month_moon y Day_moon para obtener los datos BCD del calendario lunar.
*/
Conversión no válida (c bit, año lunar, mes lunar, día lunar)
{//c=0 es el siglo XXI, c = 1 es el siglo XIX. Todos los datos de entrada y salida son datos BCD.
uchar temp1, temp2, temp3, mes_p;
uint temp4, table_addr
flag_y de flag2;
temp 1 = año/ 16; //BCD->Hex Primero convierta los datos a hexadecimal.
temp 2 = año % 16;
año = temp 1 * 1temp 2
temp 1 =mes/16; p>temp 2 = mes % 16;
mes = temp 1 * 1temp 2;
temp 1 = día/16;
temp 2 = day % 16;
day = temp 1 * 1temp 2;
//Ubica la dirección de la tabla de datos
If (c==0)
p>{
tabla _ addr = (año+0x 64-1) * 0x 3
}
Otros p>
{
table _ addr = (año-1) * 0x 3;
}
// Posicionamiento de la dirección de la tabla de datos completado.
//Obtén el mes del calendario gregoriano en el que cae la Fiesta de la Primavera ese año.
temp 1 = código_año[table_addr+2]&0x60
temp 1 = _ cror _(temp 1, 5);
//Obtener el Mes del calendario gregoriano donde se ubica la Fiesta de la Primavera de ese año para completarse.
//Basado en el día calendario en el que cae el Festival de Primavera de ese año.
temp 2 = año _ código [table _ addr+2] 0x 1f;
//Basado en el día calendario del Festival de Primavera de ese año.
//Calcula el número de días desde la primavera hasta el día de Año Nuevo. El Festival de Primavera solo será en octubre o febrero del calendario gregoriano 65438+.
si (temp 1 = = 0x 1)
{
temp 3 = temp 2-1;
}
Otros
{
temp 3 = temp 2+0x 1f-1;
}
//Calcular desde El número de días desde la primavera hasta el día de Año Nuevo.
//Para calcular el número de días desde el día del calendario gregoriano hasta el día de Año Nuevo del año actual, se utilizan dos tablas para reducir los cálculos.
//day_code 1[9], day_code 2[3]
//Si el mes del calendario gregoriano es en septiembre o antes de septiembre, el número de días será menor que 0xff , Y utilizará la tabla day_code 1[9].
//Después de septiembre, si el número de días es mayor que 0xff, use la tabla day_code 2 [3].
//Si el día del calendario gregoriano ingresado es el 10 de agosto, entonces el número de días desde el día del calendario gregoriano hasta el día de Año Nuevo es Day_code 1[8-1]+10-1.
//Si el día del calendario gregoriano en octubre es 110, entonces el número de días desde el día del calendario gregoriano hasta el día de Año Nuevo es Day_code 2[11-10]+10-1.
if(mes<10)
{
temp 4 = día _ código 1【mes-1】+día-1;
}
Otros
{
temp4 = día _ código 2【mes-10】+día-1;
} p>
if ((month>0x2)&&(year%0x4==0))
{//Si el mes del calendario gregoriano es mayor que febrero, y febrero de ese año es Si hay un mes bisiesto, el número de días aumentará en 1.
temp 4+= 1;
}
//Calcular el número de días desde el día del calendario gregoriano hasta el día de Año Nuevo en el año actual.
//Determina si el día calendario es antes o después del Festival de Primavera.
if (temp 4>=temperatura 3)
{//El día después de la Fiesta de la Primavera en el calendario gregoriano o el día de la Fiesta de la Primavera, utilice el siguiente código para operar.
Temperatura 4-=Temperatura 3;
mes = 0x 1;
mes _ p = 0x 1 //mes_p se refiere al mes, el calendario; el día es en el Festival de Primavera Anterior o mes_p se refiere al primer mes.
flag 2 = get_moon_day(month_p,table_addr);
//Comprueba si el mes lunar es mayor o menor. Devuelve 1 para meses grandes y 0 para meses pequeños.
flag _ y = 0;
if (flag 2 == 0) temp 1 = 0x 1d; // 29 días de aborto espontáneo
else temp 1 = 0x 1e; //tamaño 30 días
temp 2 =year_code[table_addr]&0xf0
temp 2 = _cror_(temp 2, 4); del año de la tabla de datos. Si es 0, no hay meses bisiestos en el año.
mientras(temp 4》gt;=temp1)
{
temp 4-= temp 1;
mes _ p+= 1;
if (mes == temp 2)
{
flag_y = ~ flag_y
if (flag_y ==0)
mes+= 1;
}
else mes+= 1;
bandera 2 = obtener _ luna _ día(mes_p, table_addr );
si (bandera 2 == 0) temp 1 = 0x 1d
si no temp 1 = 0x 1e
}
<; p>day = temp 4+1;}
Otros
{//El día antes del Festival de Primavera en el calendario gregoriano, use el siguiente código opera.
Temperatura 3-=Temperatura 4;
si (año==0x0)
{
año = 0x63c = 1;
}
else año-= 1;
tabla _ addr-= 0x 3;
mes= 0xc
temp 2 = código_año[table_addr]&0xf0
temp 2 = _cror_(temp 2, 4);
if (temperatura 2== 0)
mes_p = 0xc
Otro
mes_p = 0xd//
/*mes_p se refiere al mes. Si hay un mes bisiesto en ese año, hay trece meses en un año, el mes se refiere al 13 y no hay mes bisiesto al 12*/
flag _ y = 0; >
bandera 2 = get _ moon_day(month_p, table_addr);
if (bandera 2 == 0) temp 1 = 0x 1d
else temp 1 = 0x 1e;
p>mientras (temp 3 & gt; temperatura 1)
{
temp 3-= temp 1;
mes _ p-= 1 ;
if (bandera _ y == 0) mes-= 1
if (mes == temp 2) bandera _ y = ~ bandera _ y
bandera 2 = get_moon_day(month_p, table_addr);
si (bandera 2 == 0) temp 1 = 0x 1d; 0x 1e;
}
día = temp 1-temp 3+1;
}
c _ luna = c// Hex->BCD, después de la operación, convierta los datos a datos BCD.
temp 1 = año/10;
temp 1 = _ crol _ (temp 1, 4);
temp 2 = año % 10; p>
p>
año_luna = temp 1 | temp 2;
temp 1 =mes/10; , 4);
temp 2 = mes % 10;
mes _ luna = temp 1 | temp 2;
temp 1 = día/10;
temp 1 = _ crol _ (temp 1, 4);
temp 2 = día % 10
día _ luna = temp 1 |
}
/************************************ ******** **********************************
/ *Función: Ingresar datos del calendario solar BCD y generar datos de la semana BCD (solo se permiten 1901-2099).
Ejemplo de llamada a la función: convert_week(c_sun, año_sun, mes_sun, día_sun)
Por ejemplo, calcule la conversión del 16 de junio de 2004 (0, 0x4, 0x10, 0x16);
C_sun, Year_Sun, Month_Sun y Day_Sun son todos datos BCD, C_Sun es la marca del siglo, c_sun=0 es 21.
Ji, c_sun=1 es del siglo XIX.
Después de llamar a la función, los datos originales permanecen sin cambios y los datos BCD del calendario lunar se obtienen leyendo la semana.
*/
código uchar tabla _ semana【12】= { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 } ; //Tabla de datos de corrección mensual
/*
Algoritmo: la suma de fecha + año + número de año bisiesto + número positivo dividido por 7 es la semana, pero si es una semana
En un año bisiesto menor que marzo, a la suma anterior hay que restarle un día y dividirla entre 7.
El número de semanas es 0
*/
void Conver _ semana (c bit, año lunar, mes lunar, día lunar)
{//c=0 es el siglo XXI, c=1 es el siglo XIX. Todos los datos de entrada y salida son datos BCD.
uchar temp1, temp2
temp 1 = año/16; //BCD->Hex primero convierte los datos a hexadecimal.
temp 2 = año % 16;
año = temp 1 * 1temp 2
temp 1 =mes/16; p>temp 2 = mes % 16;
mes = temp 1 * 1temp 2;
temp 1 = día/16;
temp 2 = día % 16;
día = temp 1 * 1temp 2;
if (c == 0) { año+= 0x 64; , luego suma 100 al número de años.
temp 1 = año/0x 4; //El número de años bisiestos transcurridos es solo después de 1900.
temp 2 = año+temp 1;
temp 2 = temp 2% 0x 7; //Para ahorrar recursos, realice un resto primero para evitar números mayores que 0xff y Evite el uso de datos enteros.
temp 2 = temp 2+día+table_week[mes-1];
if (año% 0x4 = = 0 & amp& amp mes& lt3) temp 2-= 1;
semana = temporal 2% 0x 7;
}