51 Almanaque

Método de cálculo del calendario lunar,

///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

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

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

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

{

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;

}

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;

}