Skip to content

Commit 2647276

Browse files
Initial commit
0 parents  commit 2647276

File tree

12 files changed

+772
-0
lines changed

12 files changed

+772
-0
lines changed

Clock.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "Clock.h"
2+
#include "Display.h"
3+
#include "Utility.h"
4+
#include <iostream>
5+
#include <ctime>
6+
#include <thread>
7+
#include <chrono>
8+
#include <cstdio> // for printf
9+
10+
using namespace std;
11+
12+
Clock::Clock(const std::string &uName,
13+
const std::string &loc,
14+
int format,
15+
bool dispSec)
16+
: userName(uName),
17+
location(loc),
18+
timeFormat(format),
19+
displaySeconds(dispSec)
20+
{
21+
// 1. Calculate offsets
22+
timeZoneOffset = Utility::getTimeZoneOffset(location);
23+
minuteOffset = Utility::getMinutesOffset(location);
24+
25+
// 2. Log user preferences
26+
Utility::logUserChoice(userName, location, timeFormat, displaySeconds);
27+
28+
// 3. Fetch weather once and store in weatherInfo
29+
weatherInfo = Utility::getWeatherInfo(location);
30+
}
31+
32+
void Clock::start()
33+
{
34+
while (true)
35+
{
36+
// Clear screen
37+
Display::clearScreen();
38+
39+
// Get current UTC time
40+
time_t now = time(NULL);
41+
tm *t = gmtime(&now);
42+
43+
// Apply offset
44+
t->tm_hour += timeZoneOffset;
45+
t->tm_min += minuteOffset;
46+
47+
// Let mktime() fix any out-of-range values
48+
mktime(t);
49+
50+
int hour = t->tm_hour;
51+
int minute = t->tm_min;
52+
int second = t->tm_sec;
53+
54+
bool isPm = false;
55+
if (timeFormat == 12)
56+
{
57+
isPm = (hour >= 12);
58+
hour = hour % 12;
59+
if (hour == 0) hour = 12;
60+
}
61+
62+
// -------------------- DISPLAY TIME --------------------
63+
Display::displayDigit(hour / 10, 10, 5);
64+
Display::displayDigit(hour % 10, 18, 5);
65+
66+
// Colon
67+
Display::displayColon(26, 5);
68+
69+
Display::displayDigit(minute / 10, 34, 5);
70+
Display::displayDigit(minute % 10, 42, 5);
71+
72+
if (displaySeconds)
73+
{
74+
Display::displayColon(50, 5);
75+
Display::displayDigit(second / 10, 58, 5);
76+
Display::displayDigit(second % 10, 66, 5);
77+
}
78+
79+
// AM/PM label if 12-hour
80+
if (timeFormat == 12)
81+
{
82+
Display::displayAmPm(isPm, 80, 5);
83+
}
84+
85+
// -------------------- DISPLAY DATE --------------------
86+
// Get local date for the chosen location
87+
std::string localDate = Utility::getLocalDate(location);
88+
89+
// Print the date in, say, row=15, col=10
90+
printf("\033[%d;%dH", 15, 10);
91+
printf("\033[1;33mToday in %s: %s\033[0m\n", location.c_str(), localDate.c_str());
92+
93+
// -------------------- DISPLAY WEATHER --------------------
94+
// Print the stored weather info on row=17, col=10
95+
printf("\033[%d;%dH", 17, 10);
96+
printf("\033[1;32mWeather: %s\033[0m\n", weatherInfo.c_str());
97+
98+
fflush(stdout);
99+
100+
// Sleep for 1 second
101+
this_thread::sleep_for(chrono::seconds(1));
102+
}
103+
}

Clock.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef CLOCK_H
2+
#define CLOCK_H
3+
4+
#include <string>
5+
6+
class Clock
7+
{
8+
private:
9+
std::string userName;
10+
std::string location;
11+
int timeFormat; // 12 or 24
12+
bool displaySeconds;
13+
int timeZoneOffset;
14+
int minuteOffset;
15+
16+
// Store fetched weather info
17+
std::string weatherInfo;
18+
19+
public:
20+
// Constructor
21+
Clock(const std::string &userName,
22+
const std::string &location,
23+
int timeFormat,
24+
bool displaySeconds);
25+
26+
// Starts the clock loop (displays time continuously)
27+
void start();
28+
};
29+
30+
#endif

DigitalClock

99.5 KB
Binary file not shown.

Display.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#include "Display.h"
2+
#include <iostream> // for std::cout
3+
#include <cstdio> // for printf
4+
using namespace std;
5+
6+
// Initialize static members:
7+
const std::string Display::digits[10][HEIGHT] = {
8+
{
9+
" ██████╗ ",
10+
"██╔═══██╗",
11+
"██║ ██║",
12+
"██║ ██║",
13+
"██║ ██║",
14+
"╚██████╔╝",
15+
" ╚═════╝ "
16+
},
17+
{
18+
" ██╗",
19+
"███║",
20+
"╚██║",
21+
" ██║",
22+
" ██║",
23+
" ██║",
24+
" ╚═╝"
25+
},
26+
{
27+
"██████╗ ",
28+
"╚════██╗",
29+
" █████╔╝",
30+
"██╔═══╝ ",
31+
"███████╗",
32+
"╚══════╝",
33+
" "
34+
},
35+
{
36+
"██████╗ ",
37+
"╚════██╗",
38+
" █████╔╝",
39+
" ╚═══██╗",
40+
"██████╔╝",
41+
"╚═════╝ ",
42+
" "
43+
},
44+
{
45+
"██╗ ██╗",
46+
"██║ ██║",
47+
"███████║",
48+
"╚════██║",
49+
" ██║",
50+
" ╚═╝",
51+
" "
52+
},
53+
{
54+
"███████╗",
55+
"██╔════╝",
56+
"███████╗",
57+
"╚════██║",
58+
"███████║",
59+
"╚══════╝",
60+
" "
61+
},
62+
{
63+
" ██████╗ ",
64+
"██╔════╝ ",
65+
"███████╗ ",
66+
"██╔═══██╗",
67+
"╚██████╔╝",
68+
" ╚═════╝ ",
69+
" "
70+
},
71+
{
72+
"███████╗",
73+
"╚════██║",
74+
" ██╔╝",
75+
" ██╔╝ ",
76+
" ██╔╝ ",
77+
" ╚═╝ ",
78+
" "
79+
},
80+
{
81+
" █████╗ ",
82+
"██╔══██╗",
83+
"╚█████╔╝",
84+
"██╔══██╗",
85+
"╚█████╔╝",
86+
" ╚════╝ ",
87+
" "
88+
},
89+
{
90+
" █████╗ ",
91+
"██╔══██╗",
92+
"╚██████║",
93+
" ╚═══██║",
94+
" █████╔╝",
95+
" ╚════╝ ",
96+
" "
97+
}
98+
};
99+
100+
const std::string Display::colon[HEIGHT] = {
101+
" ",
102+
"",
103+
"",
104+
" ",
105+
"",
106+
"",
107+
" "
108+
};
109+
110+
const std::string Display::am[HEIGHT] = {
111+
" █████╗ ███╗ ███╗",
112+
"██╔══██╗████╗ ████║",
113+
"███████║██╔████╔██║",
114+
"██╔══██║██║╚██╔╝██║",
115+
"██║ ██║██║ ╚═╝ ██║",
116+
"╚═╝ ╚═╝╚═╝ ╚═╝",
117+
" "
118+
};
119+
120+
const std::string Display::pm[HEIGHT] = {
121+
"██████╗ ███╗ ███╗",
122+
"██╔══██╗████╗ ████║",
123+
"██████╔╝██╔████╔██║",
124+
"██╔═══╝ ██║╚██╔╝██║",
125+
"██║ ██║ ╚═╝ ██║",
126+
"╚═╝ ╚═╝ ╚═╝",
127+
" "
128+
};
129+
130+
void Display::clearScreen()
131+
{
132+
// ANSI escape codes to clear screen and move cursor to (0,0)
133+
printf("\033[2J");
134+
printf("\033[H");
135+
}
136+
137+
void Display::displayDigit(int digit, int x, int y)
138+
{
139+
// Print each line of the digit at the specified (x, y)
140+
for (int i = 0; i < HEIGHT; i++)
141+
{
142+
printf("\033[%d;%dH", y + i, x);
143+
printf("%s%s%s", FG_COLOR, digits[digit][i].c_str(), RESET_COLOR);
144+
}
145+
}
146+
147+
void Display::displayColon(int x, int y)
148+
{
149+
for (int i = 0; i < HEIGHT; i++)
150+
{
151+
printf("\033[%d;%dH", y + i, x);
152+
printf("%s%s%s", FG_COLOR, colon[i].c_str(), RESET_COLOR);
153+
}
154+
}
155+
156+
void Display::displayAmPm(bool isPm, int x, int y)
157+
{
158+
const std::string* pattern = isPm ? pm : am;
159+
for (int i = 0; i < HEIGHT; i++)
160+
{
161+
printf("\033[%d;%dH", y + i, x);
162+
printf("%s%s%s", FG_COLOR, pattern[i].c_str(), RESET_COLOR);
163+
}
164+
}

Display.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef DISPLAY_H
2+
#define DISPLAY_H
3+
4+
#include <string>
5+
6+
class Display
7+
{
8+
private:
9+
static const int HEIGHT = 7;
10+
11+
// Console color escape sequences
12+
static constexpr const char* FG_COLOR = "\033[1;32m"; // Bold Green
13+
static constexpr const char* RESET_COLOR = "\033[0m"; // Reset
14+
15+
// Digit patterns
16+
static const std::string digits[10][HEIGHT];
17+
// Colon pattern
18+
static const std::string colon[HEIGHT];
19+
// AM/PM patterns
20+
static const std::string am[HEIGHT];
21+
static const std::string pm[HEIGHT];
22+
23+
public:
24+
// Clears the screen
25+
static void clearScreen();
26+
27+
// Displays a single digit at x, y
28+
static void displayDigit(int digit, int x, int y);
29+
30+
// Displays colon ':' at x, y
31+
static void displayColon(int x, int y);
32+
33+
// Displays either AM or PM at x, y
34+
static void displayAmPm(bool isPm, int x, int y);
35+
};
36+
37+
#endif

Input.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "Input.h"
2+
#include "Utility.h"
3+
#include <iostream>
4+
#include <limits>
5+
using namespace std;
6+
7+
int Input::getUserInput(const std::string &prompt, int minVal, int maxVal)
8+
{
9+
int input;
10+
while (true)
11+
{
12+
cout << prompt;
13+
cin >> input;
14+
15+
// Validate input
16+
if (!cin.fail() && (input == minVal || input == maxVal))
17+
{
18+
// Clear the buffer
19+
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
20+
break;
21+
}
22+
else
23+
{
24+
cout << "Invalid input. You can only select " << minVal << " or " << maxVal << "." << endl;
25+
// Clear error flags and discard invalid input
26+
cin.clear();
27+
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
28+
}
29+
}
30+
return input;
31+
}
32+
33+
std::string Input::getLocationInput()
34+
{
35+
while (true)
36+
{
37+
cout << "1. Enter your location (e.g., Sydney, Berlin, Tokyo, London, Kathmandu): ";
38+
string location;
39+
cin >> location;
40+
41+
// Check if location is valid
42+
if (Utility::getTimeZoneOffset(location) != -9999)
43+
{
44+
return location;
45+
}
46+
else
47+
{
48+
cout << "Invalid location. Please enter a valid location.\n";
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)