看我之前的微博,我是做了双屏的时钟,这个是左边屏,只显示日期、星期、时间、农历。农历使用离线库。放出来给喜欢的朋友玩一下。可以直接烧。
注意:引脚位置,我这个屏的引脚定义可能跟大家的不一样,如果不亮把下面的数字调换一下就行了。
const int SDA_PIN = 2; //引脚.注意如果屏幕不亮可能是引脚定义不对,调换一下可能就好了。
const int SDC_PIN = 0;
说明:汉字为取模方式。
//leftmonitor.ino
#include <Arduino.h>//<>为系统头文件,一般在库内。
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <DNSServer.h>//密码直连将其三个库注释
#include <ESP8266WebServer.h>
#include <CustomWiFiManager.h>
#include <sys/time.h>
#include <coredecls.h>
#include <U8g2lib.h>
#include "SH1106Wire.h" //1.3寸,“”为自己的头文件,一般在当前目录下。
#include "lunarday.h"
const char* WIFI_SSID = ""; //填写你的WIFI名称及密码
const char* WIFI_PWD = "";
const String WDAY_NAMES[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //星期
#define TZ 8 // 中国时区为8
#define DST_MN 0 // 默认为0
#define TZ_MN ((TZ)*60) //时间换算
#define TZ_SEC ((TZ)*3600)
#define DST_SEC ((DST_MN)*60)
time_t now; //实例化时间
long timeSinceLastWUpdate = 0; //上次更新后的时间
const int UPDATE_INTERVAL_SECS = 5 * 60; // 5分钟更新一次
//#include "WeatherStationFonts.h"
const int I2C_DISPLAY_ADDRESS = 0x3c; //I2c地址默认
#if defined(ESP8266)
const int SDA_PIN = 2; //引脚.注意如果屏幕不亮可能是引脚定义不对,调换一下可能就好了。
const int SDC_PIN = 0;
//const int ledPin = 1; // GPIO1 of ESP8266-01S默认是1。
#endif
SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
void drawDateTime();//函数声明
//
//void wificonnect() { //WIFI密码连接
// WiFi.begin(WIFI_SSID, WIFI_PWD);
// while (WiFi.status() != WL_CONNECTED) {
// Serial.print('.');
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait.");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait..");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait...");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait....");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait.....");
// display.display();
// delay(80);
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
// display.drawString(10, 18, "wait......");
// display.display();
// delay(80);
//
// }
// Serial.println("");
// delay(500);
//}
void webconnect() { //Web配网,密码直连将其注释
display.clear();
display.setFont(ArialMT_Plain_24);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(10, 18, "WAIT WIFI!");
display.display();
WiFiManager wifiManager; //实例化WiFiManager
wifiManager.setDebugOutput(false); //关闭Debug
//wifiManager.setConnectTimeout(10); //设置超时
//wifiManager.setHeadImgBase64(FPSTR(Icon)); //设置图标
wifiManager.setPageTitle("欢迎来到WiFi配置页"); //设置页标题
if (!wifiManager.autoConnect("左屏 WIFI ")) { //AP模式
//Serial.println("连接失败并超时");
//重新设置并再试一次,或者让它进入深度睡眠状态
ESP.restart();
delay(1000);
}
//Serial.println("connected...^_^");
yield();
}
const unsigned char xing[] U8X8_PROGMEM = {
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00
}; /*星*/
const unsigned char zheng[] U8X8_PROGMEM = {
0x00,0x00,0xFE,0x3F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x88,0x00,0x88,0x1F,
0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0xFF,0x7F,0x00,0x00
};/*"正"*/
const unsigned char qi[] U8X8_PROGMEM = {
0x44,0x00,0x44,0x3E,0xFE,0x22,0x44,0x22,0x44,0x22,0x7C,0x3E,0x44,0x22,0x44,0x22,
0x7C,0x22,0x44,0x3E,0x44,0x22,0xFF,0x22,0x20,0x21,0x44,0x21,0x82,0x28,0x41,0x10
}; /*期*/
const unsigned char yue[] U8X8_PROGMEM = {
0x00,0x00,0xF8,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x10,
0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x10,0x04,0x10,0x04,0x10,0x02,0x14,0x01,0x08
/*"月"*/
};
const unsigned char ri[] U8X8_PROGMEM = {
0x00,0x00,0xF8,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x0F,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08
};/*"日"*/
const unsigned char yi[] U8X8_PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};/*"一"*/
const unsigned char er[] U8X8_PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00
};/*"二",0*/
const unsigned char san[] U8X8_PROGMEM = {
0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0x00,0x00,0x00,0x00
};/*"三",1*/
const unsigned char si[] U8X8_PROGMEM = {
0x00,0x00,0x00,0x00,0xFE,0x3F,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
0x12,0x22,0x12,0x3C,0x0A,0x20,0x06,0x20,0x02,0x20,0xFE,0x3F,0x02,0x20,0x00,0x00
};/*"四"*/
const unsigned char wu[] U8X8_PROGMEM = {
0x00,0x00,0xFE,0x3F,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xFC,0x0F,0x20,0x08,
0x20,0x08,0x20,0x08,0x20,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0xFF,0x7F,0x00,0x00
};/*"五"*/
const unsigned char liu[] U8X8_PROGMEM = {
0x40,0x00,0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0xFF,0x7F,0x00,0x00,0x00,0x00,
0x20,0x02,0x20,0x04,0x10,0x08,0x10,0x10,0x08,0x10,0x04,0x20,0x02,0x20,0x00,0x00
};/*"六"*/
const unsigned char qi1[] U8X8_PROGMEM = {
0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x3C,0xE0,0x03,0x5F,0x00,
0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x20,0x40,0x20,0x40,0x20,0x80,0x3F,0x00,0x00
};/*"七"*/
const unsigned char ba[] U8X8_PROGMEM = {
0x00,0x00,0x00,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x04,
0x10,0x04,0x10,0x04,0x10,0x08,0x08,0x08,0x08,0x10,0x04,0x10,0x04,0x20,0x02,0x40
};/*"八"*/
const unsigned char jiu[] U8X8_PROGMEM = {
0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xFE,0x07,0x20,0x04,0x20,0x04,0x20,0x04,
0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x44,0x08,0x44,0x04,0x44,0x02,0x78,0x01,0x00
};/*"九"*/
const unsigned char shi[] U8X8_PROGMEM = {
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x80,0x00,
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00
};/*"十"*/
const unsigned char chu[] U8X8_PROGMEM = {
0x04,0x00,0x08,0x00,0x80,0x3F,0x3F,0x22,0x10,0x22,0x08,0x22,0x08,0x22,0x2C,0x22,
0x1A,0x22,0x29,0x22,0x28,0x22,0x08,0x21,0x08,0x21,0x88,0x20,0x48,0x14,0x28,0x08
};/*"初"*/
const unsigned char nian[] U8X8_PROGMEM = {
0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0xFF,0x7F,0x10,0x08,0x10,0x08,
0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0xF0,0x0F,0x10,0x08
};/*"廿"*/
const unsigned char nong[] U8X8_PROGMEM = {
0x80,0x00,0x80,0x00,0x80,0x00,0xFE,0x3F,0x42,0x20,0x41,0x10,0xA0,0x00,0xA0,0x10,
0x10,0x09,0x18,0x05,0x14,0x02,0x12,0x04,0x11,0x08,0x50,0x10,0x30,0x60,0x10,0x00
};/*农*/
const unsigned char li[] U8X8_PROGMEM = {
0x00,0x00,0xFC,0x7F,0x04,0x00,0x04,0x01,0x04,0x01,0x04,0x01,0xF4,0x3F,0x04,0x21,
0x04,0x21,0x84,0x20,0x84,0x20,0x44,0x20,0x44,0x20,0x22,0x20,0x12,0x14,0x09,0x08
};/*"历",1*/
const unsigned char dong[] U8X8_PROGMEM = {
0x20,0x00,0x20,0x00,0xF0,0x0F,0x08,0x08,0x14,0x04,0x22,0x02,0xC0,0x01,0x30,0x06,
0x0C,0x18,0x03,0x60,0xE0,0x00,0x00,0x03,0x00,0x04,0x70,0x00,0x80,0x01,0x00,0x02
};/*"冬"*/
const unsigned char la[] U8X8_PROGMEM = {
0x00,0x11,0x1E,0x11,0x12,0x11,0xD2,0x7F,0x12,0x11,0x1E,0x11,0xF2,0x7F,0x12,0x00,
0x92,0x3F,0x9E,0x20,0x92,0x20,0x92,0x3F,0x92,0x20,0x92,0x20,0x92,0x3F,0x99,0x20
};/*"腊"*/
void changedate() {
using namespace std;
using namespace lunar;
int16_t x;
int16_t y;
now = time(nullptr);
struct tm* timeInfo;
timeInfo = localtime(&now);
char buff[16];
time_t current_time;
time(¤t_time);
tm *current_tm = localtime(¤t_time);
int year = current_tm->tm_year + 1900;
int month = current_tm->tm_mon + 1;
int day = current_tm->tm_mday;
Date lunar_date = LuanrDate(year, month, day);
display.setFont(ArialMT_Plain_24);
display.drawString(60 + x, 40 + y, String(buff));
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawXbm(20, 40, 16,16, yi);
display.drawXbm(20, 56, 16,16, er);
}
void setup() {
Serial.begin(115200);
Serial.println();//println换行输出
Serial.println();
// 屏幕初始化
display.init();
display.clear();
display.display();
display.flipScreenVertically(); //屏幕翻转
display.setContrast(100); //屏幕亮度
// 用固定密码连接
//wificonnect();
//web配网
webconnect();
display.flipScreenVertically(); //屏幕反转
configTime(TZ_SEC, DST_SEC, "ntp.ntsc.ac.cn", "ntp1.aliyun.com"); //ntp获取时间,你也可用其他"pool.ntp.org","0.cn.pool.ntp.org","1.cn.pool.ntp.org","ntp1.aliyun.com"
delay(200);
}
void drawDateTime() { //显示时间
using namespace std;
using namespace lunar;
int16_t x;
int16_t y;
now = time(nullptr);
struct tm* timeInfo;
timeInfo = localtime(&now);
char buff[16];
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setFont(ArialMT_Plain_16);
String date = WDAY_NAMES[timeInfo->tm_wday];
sprintf_P(buff, PSTR("%02d/%02d "), timeInfo->tm_mon + 1, timeInfo->tm_mday);
display.drawString(60 + x, 5 + y, String(buff));
display.setFont(ArialMT_Plain_24);
sprintf_P(buff, PSTR("%02d:%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
display.drawString(64 + x, 22 + y, String(buff));
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawXbm(62, 5, 16,16, xing);
display.drawXbm(79, 5, 16,16, qi);
if (WDAY_NAMES[timeInfo->tm_wday]=="Mon")
display.drawXbm(96, 5, 16,16, yi);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Tue")
display.drawXbm(96, 5, 16,16, er);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Wed")
display.drawXbm(96, 5, 16,16, san);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Thu")
display.drawXbm(96, 5, 16,16, si);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Fri")
display.drawXbm(96, 5, 16,16, wu);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Sat")
display.drawXbm(96, 5, 16,16, liu);
else if (WDAY_NAMES[timeInfo->tm_wday]=="Sun")
display.drawXbm(96, 5, 16,16, ri);
//显示农历
int year = timeInfo->tm_year + 1900;
int month = timeInfo->tm_mon + 1;
int day = timeInfo->tm_mday;
Date lunar_date = LuanrDate(year, month, day);
display.drawXbm(14, 48, 16,16, nong);
display.drawXbm(30, 48, 16,16, li);
// Serial.print("月份为:");
// Serial.println(lunar_date.month);
// Serial.print("日期为:");
// Serial.println(lunar_date.day);
//显示月份
if (lunar_date.month == 1 && lunar_date.day==0)
{
display.drawXbm(49, 48, 16,16, la);
}
else if (lunar_date.month==1 && lunar_date.day!=0 )
{
display.drawXbm(49, 48, 16,16, zheng);
}
else if (lunar_date.month==2)
{
display.drawXbm(49, 48, 16,16, er);
}
else if (lunar_date.month==3)
{
display.drawXbm(49, 48, 16,16, san);
}
else if (lunar_date.month==4)
{
display.drawXbm(49, 48, 16,16, si);
}
else if (lunar_date.month==5)
{
display.drawXbm(49, 48, 16,16, wu);
}
else if (lunar_date.month==6)
{
display.drawXbm(49, 48, 16,16, liu);
}
else if (lunar_date.month==7)
{
display.drawXbm(49, 48, 16,16, qi);
}
else if (lunar_date.month==8)
{
display.drawXbm(49, 48, 16,16, ba);
}
else if (lunar_date.month==9)
{
display.drawXbm(49, 48, 16,16, jiu);
}
else if (lunar_date.month==10)
{
display.drawXbm(49, 48, 16,16, shi);
}
else if (lunar_date.month==11)
{
display.drawXbm(49, 48, 16,16, dong);
}
else if (lunar_date.month==12)
{
display.drawXbm(49, 48, 16,16, la);
}
display.drawXbm(66, 48, 16,16, yue);
//显示日期
if (lunar_date.day==11)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, yi);
}
else if (lunar_date.day==12)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, er);
}
else if (lunar_date.day==13)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, san);
}
else if (lunar_date.day==14)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, si);
}
else if (lunar_date.day==15)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, wu);
}
else if (lunar_date.day==16)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, liu);
}
else if (lunar_date.day==17)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, qi1);
}
else if (lunar_date.day==18)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, ba);
}
else if (lunar_date.day==19)
{
display.drawXbm(83, 48, 16,16, shi);
display.drawXbm(100, 48, 16,16, jiu);
}
else if (lunar_date.day==20)
{
display.drawXbm(83, 48, 16,16, er);
display.drawXbm(100, 48, 16,16, shi);
}
else if (lunar_date.day==21)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, yi);
}
else if (lunar_date.day==22)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, er);
}
else if (lunar_date.day==23)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, san);
}
else if (lunar_date.day==24)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, si);
}
else if (lunar_date.day==25)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, wu);
}
else if (lunar_date.day==26)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, liu);
}
else if (lunar_date.day==27)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, qi1);
}
else if (lunar_date.day==28)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, ba);
}
else if (lunar_date.day==29)
{
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, jiu);
}
else if (lunar_date.day==30)
{
display.drawXbm(83, 48, 16,16, san);
display.drawXbm(100, 48, 16,16, shi);
}
else if (lunar_date.day==1)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, yi);
}
else if (lunar_date.day==2)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, er);
}
else if (lunar_date.day==3)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, san);
}
else if (lunar_date.day==4)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, si);
}
else if (lunar_date.day==5)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, wu);
}
else if (lunar_date.day==6)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, liu);
}
else if (lunar_date.day==7)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, qi1);
}
else if (lunar_date.day==8)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, ba);
}
else if (lunar_date.day==9)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, jiu);
}
else if (lunar_date.day==10)
{
display.drawXbm(83, 48, 16,16, chu);
display.drawXbm(100, 48, 16,16, shi);
}
else if (lunar_date.day==0 )
{
day=day-1;
//Serial.print("阳历日:");
//Serial.println(day);
Date lunar_date = LuanrDate(year, month, day);
//Serial.print("日期为:");
//Serial.println(lunar_date.day);
if (lunar_date.day==29){
display.drawXbm(83, 48, 16,16, san);
display.drawXbm(100, 48, 16,16, shi);}
else if(lunar_date.day==28){
display.drawXbm(83, 48, 16,16, nian);
display.drawXbm(100, 48, 16,16, jiu);
}
}
// if (lunar_date.leap==1){
// display.drawXbm(119, 48, 16,16, "R");
// }
}
//void showMessage(String message = "FUCK!!!") {
// display.clear();
// display.setFont(ArialMT_Plain_24);
// display.setTextAlignment(TEXT_ALIGN_CENTER);
// display.drawString(64, 18, message);
// display.display();
//}
void loop() {
display.clear();
drawDateTime();
// changedate();
display.display();
if (millis() - timeSinceLastWUpdate > (1000L * UPDATE_INTERVAL_SECS)) { //屏幕刷新
timeSinceLastWUpdate = millis();
}
}
//lunarday.cpp
#include "lunarday.h"
#include <ctime>
#include <cassert>
#include <cstring>
#include <iostream>
using namespace std;
using lunar::Date;
//使用比特位记录每年的情况
//0~4 共5bit 春节日份
//5~6 共2bit 春节月份
//7~19 共13bit 13个月的大小月情况(如果无闰月,最后位无效),大月为1,小月为0
//20~23 共4bit 记录闰月的月份,如果没有闰月为0
static const int BEGIN_YEAR = 1901;
static const int NUMBER_YEAR = 199;
static const unsigned int LUNAR_YEARS[199] = {
0x03a953,0x0752c8,0x5b253d,0x0325d0,0x054dc4,
0x4aab39,0x02b54d,0x05acc2,0x2ba936,0x03a94a, //1901-1910
0x6d92be,0x0592d2,0x0525c6,0x5a55ba,0x0156ce,
0x02b5c3,0x25b4b7,0x06d4cb,0x7ec941,0x074954, //1911-1920
0x0692c8,0x5d26bc,0x052b50,0x015b45,0x4adab8,
0x036a4d,0x0754c2,0x2f4937,0x07494a,0x66933e, //1921-1930
0x0295d1,0x052bc6,0x595b3a,0x05ad4e,0x036a44,
0x3764b8,0x03a4cb,0x7b49bf,0x0549d3,0x0295c8, //1931-1940
0x652dbb,0x0556cf,0x02b545,0x4daab9,0x05d24d,
0x05a4c2,0x2d49b6,0x054aca,0x7a96bd,0x029b51, //1941-1950
0x0556c6,0x5ad53b,0x02d94e,0x06d2c3,0x3ea538,
0x06a54c,0x854abf,0x054bd2,0x02ab48,0x755abc, //1951-1960
0x056acf,0x036945,0x4752b9,0x0752cd,0x032542,
0x364bb5,0x054dc9,0x7aad3e,0x02b551,0x05b4c6, //1961-1970
0x5ba93b,0x05a94f,0x0592c3,0x4b25b7,0x0525cb,
0x8a55bf,0x0156d2,0x02b6c7,0x65b4bc,0x06d4d0, //1971-1980
0x06c945,0x4e92b9,0x0692cd,0xad26c2,0x052b54,
0x015b49,0x62dabd,0x036ad1,0x0754c6,0x5f493b, //1981-1990
0x07494f,0x069344,0x352b37,0x052bca,0x8a6b3f,
0x01ad53,0x036ac7,0x5b64bc,0x03a4d0,0x0349c5, //1991-2000
0x4a95b8,0x0295CC,0x052dc1,0x2aad36,0x02b549,
0x7daabd,0x05d252,0x05a4c7,0x5d49ba,0x054ace, //2001-2010
0x0296C3,0x4556B7,0x055ACA,0x9AD53F,0x02E953,
0x06D2C8,0x6ea53c,0x06a550,0x064AC5,0x4A9739, //2011-2020
0x02AB4C,0x055AC1,0x2AD936,0x03694A,0x6752BD,
0x0392D1,0x0325C6,0x564BBA,0x0655CD,0x02AD43, //2021-2030
0x356B37,0x05B4CB,0xBBA93F,0x05A953,0x0592C8,
0x6D25BC,0x0525CF,0x0255C4,0x52ADB8,0x02D6CC, //2031-2040
0x05B541,0x2DA936,0x06C94A,0x7E92BE,0x0692D1,
0x052AC6,0x5A56BA,0x025B4E,0x02DAC2,0x36D537, //2041-2050
0x0764CB,0x8F4941,0x074953,0x069348,0x652B3C,
0x052BCF,0x026B44,0x436AB8,0x03AACC,0x03A4C2, //2051-2060
0x3749B5,0x0349C9,0x7A95BD,0x0295D1,0x052DC5,
0x5AAD3A,0x02B54E,0x05B2C3,0x4BA537,0x05A54B, //2061-2070
0x8D4ABF,0x054AD3,0x0296C7,0x6556BB,0x055ACF,
0x02D545,0x45D2B8,0x06D2CC,0x06A542,0x3E4AB6, //2071-2080
0x064B49,0x7CA73D,0x02AB51,0x055AC6,0x5AD93A,
0x03694E,0x0752C3,0x472538,0x0325ca,0x864BBE, //2081-2090
0x0255D2,0x02ADC7,0x656B3B,0x05B54F,0x03A945,
0x4B92B9,0x0592CC,0x0545C1,0x2A4DB5//2091-2099
//上表农历修正及校验完成。2021.3.3
};
//计算这个公历日期是一年中的第几天
static int DayOfSolarYear(int year, int month, int day )
{
//为了提高效率,记录每月一日是一年中的第几天
static const int NORMAL_YDAY[12] = {1,32,60,91,121,152,
182,213,244,274,305,335};
//闰年的情况
static const int LEAP_YDAY[12] = {1,32,61,92,122,153,
183,214,245,275,306,336};
const int *t_year_yday_ = NORMAL_YDAY;
//判断是否是公历闰年
if( year % 4 ==0 )
{
if(year%100 != 0)
t_year_yday_ = LEAP_YDAY;
if(year%400 == 0)
t_year_yday_ = LEAP_YDAY;
}
return t_year_yday_[month -1] + (day -1);
}
Date lunar::LuanrDate(int solar_year,int solar_month,int solar_day)
{
Date luanr_date ;
luanr_date.year = solar_year;
luanr_date.month = 0;
luanr_date.day = 0;
luanr_date.leap = false;
//越界检查,如果越界,返回无效日期
if(solar_year <= BEGIN_YEAR || solar_year > BEGIN_YEAR + NUMBER_YEAR - 1 )
return luanr_date;
int year_index = solar_year - BEGIN_YEAR;
//计算春节的公历日期
int spring_ny_month = ( LUNAR_YEARS[year_index] & 0x60 ) >> 5;
int spring_ny_day = ( LUNAR_YEARS[year_index] & 0x1f);
//计算今天是公历年的第几天
int today_solar_yd = DayOfSolarYear(solar_year,solar_month,solar_day);
//计算春节是公历年的第几天
int spring_ny_yd = DayOfSolarYear(solar_year,spring_ny_month,spring_ny_day);
//计算今天是农历年的第几天
int today_luanr_yd = today_solar_yd - spring_ny_yd + 1;
//如果今天在春节的前面,重新计算today_luanr_yd
if ( today_luanr_yd <= 0)
{
//农历年比当前公历年小1
year_index --;
luanr_date.year --;
//越界,返回无效日期
if(year_index <0)
return luanr_date;
spring_ny_month = ( LUNAR_YEARS[year_index] & 0x60 ) >> 5;
spring_ny_day = ( LUNAR_YEARS[year_index] & 0x1f);
spring_ny_yd = DayOfSolarYear(solar_year,spring_ny_month,spring_ny_day);
int year_total_day = DayOfSolarYear(luanr_date.year,12,31);
today_luanr_yd = today_solar_yd + year_total_day - spring_ny_yd + 1;
}
int luanr_month = 1;
//计算月份和日期
for(;luanr_month<=13;luanr_month++)
{
int month_day = 29;
if( (LUNAR_YEARS[year_index] >> (6 + luanr_month)) & 0x1 )
month_day = 30;
if( today_luanr_yd <= month_day )
break;
else
today_luanr_yd -= month_day;
}
luanr_date.day = today_luanr_yd;
//处理闰月
int leap_month = (LUNAR_YEARS[year_index] >>20) & 0xf;
if(leap_month > 0 && leap_month < luanr_month )
{
luanr_month --;
//如果当前月为闰月,设置闰月标志
if( luanr_month == leap_month )
luanr_date.leap = true;
}
assert(leap_month <= 12);
luanr_date.month = luanr_month;
return luanr_date;
}
根据网友测试上面原代码if ( today_luanr_yd < 0){}会出现“1月0号,0月0号”的问题,现已修正为:
if ( today_luanr_yd <= 0){}。2022.2.8
//file:lunarday.h
namespace lunar
{
//保存一个农历日期
typedef struct T_Date
{
//年
int year;
//月
int month;
//日
int day;
//是否闰月
bool leap;
} Date;
//公历转农历
Date LuanrDate(int solar_year,int solar_month,int solar_day);
}