#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
const int ROW_NUM = 4;
const int COLUMN_NUM = 4;
char keys[ROW_NUM][COLUMN_NUM] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pin_rows[ROW_NUM] = {9, 8, 7, 6};
byte pin_column[COLUMN_NUM] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
LiquidCrystal_I2C lcd(0x27, 16, 2);
String inputNumber = "";
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print("Enter date:");
}
void loop() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
// Reset the process
inputNumber = "";
lcd.clear();
lcd.print("Enter date:");
}
else if (key == '*') {
if (inputNumber.length() == 8) {
// Display preloader
displayPreloader();
// Convert the input string to integers for day, month, and year
int day = inputNumber.substring(0, 2).toInt();
int month = inputNumber.substring(2, 4).toInt();
int year = inputNumber.substring(4, 8).toInt();
// Check if the date is valid
if (isValidDate(day, month, year)) {
// Calculate the day of the week using Zeller's Congruence
String result = zellersCongruence(day, month, year);
// Display the result on the LCD
lcd.clear();
lcd.print("Day of week:");
lcd.setCursor(0, 1);
lcd.print(result);
} else {
// Display "Invalid" on the LCD for invalid dates
lcd.clear();
lcd.print("Invalid date");
}
// Reset the input for the next round
inputNumber = "";
}
}
else if (key == 'A' && inputNumber.length() > 0) {
// Backspace functionality, remove the last entered digit
inputNumber.remove(inputNumber.length() - 1);
// Display the entered number on the LCD
lcd.clear();
lcd.print("Enter date:");
lcd.setCursor(0, 1);
lcd.print(inputNumber);
}
else if (inputNumber.length() < 8 && key >= '0' && key <= '9') {
// Append the pressed key to the input number, only if the length is less than 8 and key is a digit
inputNumber += key;
// Display the entered number on the LCD
lcd.clear();
lcd.print("Enter date:");
lcd.setCursor(0, 1);
lcd.print(inputNumber);
}
}
}
void displayPreloader() {
lcd.clear();
lcd.print("Processing...");
delay(2000); // Simulate preloader delay
}
String zellersCongruence(int day, int month, int year) {
if (month < 3) {
month += 12;
year -= 1;
}
int K = year % 100;
int J = year / 100;
int h = (day + ((13 * (month + 1)) / 5) + K + (K / 4) + (J / 4) - 2 * J) % 7;
// Map the result to the corresponding day names
switch (h) {
case 0: return "Saturday";
case 1: return "Sunday";
case 2: return "Monday";
case 3: return "Tuesday";
case 4: return "Wednesday";
case 5: return "Thursday";
case 6: return "Friday";
default: return "Invalid";
}
}
bool isValidDate(int day, int month, int year) {
// Basic checks for valid day, month, and year ranges
if (month < 1 || month > 12 || day < 1 || day > 31 || year < 1000 || year > 9999) {
return false;
}
// Additional checks for specific month-day combinations
if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
return false; // April, June, September, November have 30 days
} else if (month == 2) {
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return day <= 29; // February in a leap year has 29 days
} else {
return day <= 28; // February in a non-leap year has 28 days
}
}
return true; // All other months have 31 days
}