Skip to content

Instantly share code, notes, and snippets.

@NaikSoftware
Last active September 24, 2019 06:42
Show Gist options
  • Save NaikSoftware/f9cf4e284794c9cdf3059fc1484071b6 to your computer and use it in GitHub Desktop.
Save NaikSoftware/f9cf4e284794c9cdf3059fc1484071b6 to your computer and use it in GitHub Desktop.
Working Days Lab
4
15.01. 17:00
16.01. 12:00
11.02. 14:00
30.01. 10:00
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
#include <iomanip>
#include <chrono>
using namespace std;
typedef chrono::time_point<chrono::system_clock> time_point;
const char *INPUT_FILENAME = "./INPUT.TXT"; // For Windows OS maybe you need to remove leading './'
const char *OUTPUT_FILENAME = "./OUTPUT.TXT"; // For Windows OS maybe you need to remove leading './'
const int DAY_START = 10;
const int DAY_END = 18;
chrono::minutes get_work_time(time_point &t1, time_point &t2);
/**
* You must place input file to run directory.
* Output will be placed in the same folder.
*
* Compiler: GCC C++14, Linux OS
*/
int main() {
ifstream input(INPUT_FILENAME);
// Read count
string line;
getline(input, line);
int point_count = stoi(line);
cout << "Time points:" << point_count << endl;
// Read all time points to dynamic array
auto time_points = new time_point[point_count];
tm time_buffer = {};
time_t timer = time(nullptr); // Now time
time_buffer.tm_year = localtime(&timer)->tm_year; // Set current 2019 year (not leap) to buffer
for (int i = 0; i < point_count; ++i) {
if (getline(input, line)) {
istringstream iss(line);
iss >> get_time(&time_buffer, "%d.%m. %H:%M");
cout << "Read point " << put_time(&time_buffer, "%c") << endl;
time_points[i] = chrono::system_clock::from_time_t(mktime(&time_buffer));
} else {
exit(EXIT_FAILURE); // Something went wrong
}
}
// Sort time points from early to late
qsort(time_points, point_count, sizeof(*time_points), [](const void *a, const void *b) {
// Closure (anonymous function) with custom sorting logic
time_point arg1 = *static_cast<const time_point *>(a);
time_point arg2 = *static_cast<const time_point *>(b);
return arg1.time_since_epoch().count() > arg2.time_since_epoch().count() ? 1 : -1; // 1 - a > b, -1 b > a, 0 = objects are equals
});
// Concatenate all work periods
chrono::minutes overall(0);
for (int i = 0; i < point_count; i += 2) {
chrono::minutes work_time = get_work_time(time_points[i], time_points[i + 1]);
overall += work_time;
}
delete[] time_points; // Clear dynamic memory after use
// Print results
long minutes = overall.count();
long hourMinutes = minutes % 60;
cout << "Overall: " << minutes / 60 << ":";
if (hourMinutes < 10) cout << "0" << hourMinutes << endl;
else cout << hourMinutes << endl;
// Write results to file
remove(OUTPUT_FILENAME);
ofstream output(OUTPUT_FILENAME);
output << minutes / 60 << ":";
if (hourMinutes < 10) output << "0" << hourMinutes;
else output << hourMinutes;
output.close();
return EXIT_SUCCESS;
}
chrono::minutes get_work_time(time_point &t1, time_point &t2) {
time_t tt = chrono::system_clock::to_time_t(t1);
tm start = *localtime(&tt);
tt = chrono::system_clock::to_time_t(t2);
tm end = *localtime(&tt);
long days = end.tm_yday - start.tm_yday + 1;
cout << "days in period " << days << endl;
cout << "from " << put_time(&start, "%c") << " to " << put_time(&end, "%c") << endl;
if (days == 1) {
auto result = chrono::duration_cast<chrono::minutes>(t2 - t1 + chrono::minutes(1));
cout << "add period for single working day" << result.count() / 60 << ":" << result.count() % 60 << endl;
return result;
} else {
chrono::minutes result = chrono::minutes(1);
if (days > 2) {
cout << "add full working days " << (days - 2) * 8 << ":00" << endl;
result += chrono::hours(8 * (days - 2)); // Add full working days if existing
}
result += chrono::minutes(DAY_END * 60 - start.tm_hour * 60 - start.tm_min); // Add first day of period;
result += chrono::minutes(end.tm_hour * 60 + end.tm_min - DAY_START * 60); // Add last day of period
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment