From 6a96532a8d0d4611ee1dd10cfcdb68847d90b8dc Mon Sep 17 00:00:00 2001 From: khumnath Date: Sat, 16 Nov 2024 00:00:58 +0900 Subject: [PATCH 1/2] update with date output format Usage: Show today's date: ./ndate --today [--unicode] [--format format_string] Convert to Bikram Sambat Date: ./ndate --tobs year month day [--unicode] [--format format_string] Convert to Gregorian Date: ./ndate --toad year month day [--unicode] [--format format_string] Options: --unicode : Display the date in Unicode format (Devanagari script). --format format_string : Specify a custom format for the date (e.g., 'y-m-d', 'd-M-y'). Default: 'y-m-d' Format Specifiers: y : Year m : Month (numeric) d : Day w : Weekday name M : Month name --- README.md | 135 ++++++++++++----------- src/main.cpp | 297 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 306 insertions(+), 126 deletions(-) diff --git a/README.md b/README.md index 500f714..50c6631 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ nepdate-cli is a command-line tool for displaying and converting dates between t - Display the current Bikram Sambat date. - Convert dates between Bikram Sambat and Gregorian calendars. -- Supports very long date range. +- Supports date formatting with devnagari script and date format specifiers. +- Supports very long date range. ### Installation @@ -23,104 +24,118 @@ There are two installation methods available: using a Debian package or compilin 1. **Download the latest `.deb` file** from the [releases](https://github.com/opensource-nepal/nepdate-cli/releases) page. 2. **Install the package** using `dpkg`: -Bash + ```bash + sudo dpkg -i nepdate-cli_1.0.0_amd64.deb + ``` -``` -sudo dpkg -i nepdate-cli_1.0.0_amd64.deb - -``` - -Replace `nepdate-cli_1.0.0_amd64.deb` with the filename of the downloaded package. + Replace `nepdate-cli_1.0.0_amd64.deb` with the filename of the downloaded package. #### From Source 1. Clone the repository: -Bash -``` -git clone https://github.com/opensource-nepal/nepdate-cli.git -cd nepdate-cli -``` + ```bash + git clone https://github.com/opensource-nepal/nepdate-cli.git + cd nepdate-cli + ``` 2. Install dependencies: -Bash + ```bash + sudo apt-get update + sudo apt-get install -y cmake build-essential debhelper devscripts + ``` -``` -sudo apt-get update -sudo apt-get install -y cmake build-essential debhelper devscripts - -``` - -* packages debhelper and devscripts are for building debian installer package. + *packages debhelper and devscripts are for building debian installer package.* 3. Build and install: -Bash + ```bash + mkdir build + cd build + cmake .. + make + sudo make install + ``` -``` -mkdir build -cd build -cmake .. -make -sudo make install - -``` -* if need to build deb package with signing, run ``` dpkg-buildpackage -b``` from project root directory.(you have to edit email address to yours in files in /debian folder.) -* ``` dpkg-buildpackage -b -us -uc``` command builds debian package without signing. + *if need to build deb package with signing, run `dpkg-buildpackage -b` from project root directory. (you have to edit email address to yours in files in /debian folder.)* + *`dpkg-buildpackage -b -us -uc` command builds debian package without signing.* ### Usage Once installed, you can use nepdate-cli from the command line. Here are some basic commands: -- Display the current Bikram Sambat date: - -Bash - -``` +```bash nepdate-cli ``` -output: -![Screenshot_select-area_20240810182013](https://github.com/user-attachments/assets/7b0f2e84-ec09-44a0-9edc-37bd46a682c4) -* Convert to Bikram Sambat + +Output: ``` - nepdate-cli --conv --tobs 2024 8 10 + Today's Date: + Gregorian: 2024 11 15 Friday + Bikram Sambat: 2081 8 30 शुक्रवार days in bikram month: 30 ``` -output: -![Screenshot_select-area_20240810182157](https://github.com/user-attachments/assets/474ff597-829e-4f48-8d16-079673f902fd) - -* Convert a Bikram Sambat date to Gregorian: ``` -nepdate-cli --conv --toad 2081 4 26 +Usage: + Show today's date: ./ndate --today [--unicode] [--format format_string] + Convert to Bikram Sambat Date: ./ndate --tobs year month day [--unicode] [--format format_string] + Convert to Gregorian Date: ./ndate --toad year month day [--unicode] [--format format_string] +Options: + --unicode : Display the date in Unicode format (Devanagari script). + --format format_string : Specify a custom format for the date (e.g., 'y-m-d', 'd-M-y'). Default: 'y-m-d' -``` -output: -![Screenshot_select-area_20240810182318](https://github.com/user-attachments/assets/308500ee-15dc-42a3-a1d5-9d5d729b267b) +Format Specifiers: + y : Year + m : Month (numeric) + d : Day + w : Weekday name + M : Month name -* Show only Bikram sambat date: +Example commands: + ./ndate --today --unicode --format 'd-M-y' : Show today's date in Unicode with custom format. + ./ndate --tobs 2024 11 15 --unicode --format 'y-m-d' : Convert a Gregorian date to Bikram Sambat date. + ./ndate --toad 2081 8 30 --unicode --format 'y/m/d' : Convert a Nepali date to Gregorian date. ``` -nepdate-cli --today -``` -output: -![Screenshot_select-area_20241109224159](https://github.com/user-attachments/assets/be8fdad0-9951-4cbd-a39e-cdfb6d37e46c) +### Examples: + +1. Show today's date in Devanagari script with default format: + ```bash + ./ndate --today --unicode + ``` + Output: २०८१-८-३० + +2. Convert a Gregorian date to Bikram Sambat date in Devanagari script: + ```bash + ./ndate --tobs 2024 11 15 --unicode + ``` + Output: २०८१-८-३० + +3. Show today's date with custom format 'd-M-y': + ```bash + ./ndate --today --format 'd-M-y' + ``` + Output: ३०-श्रावण-२०८१ +4. Convert a Bikram Sambat date to Gregorian date with weekday name: + ```bash + ./ndate --toad 2081 8 30 --format 'w, y-m-d' --unicode + ``` + Output: शुक्रवार, २०८१-८-३० -### ** Replace the date strings with the date you want to convert. -## Contributing +### Contributing Contributions are welcome! If you have any bug reports or feature requests, please open an issue on the GitHub [repository](https://github.com/opensource-nepal/nepdate-cli). Here's a quick guide to contributing code: 1. Fork the repository. -3. Create a new branch for your changes. -5. Commit your changes and push them to your fork. -7. Open a pull request against the main branch of the original repository. - +2. Create a new branch for your changes. +3. Commit your changes and push them to your fork. +4. Open a pull request against the main branch of the original repository. ### License diff --git a/src/main.cpp b/src/main.cpp index 3711043..a64af7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,104 +16,269 @@ */ #include "bikram.h" #include +#include +#include #include +#include + +std::map devanagariNumbers = { + {'0', "०"}, {'1', "१"}, {'2', "२"}, {'3', "३"}, {'4', "४"}, + {'5', "५"}, {'6', "६"}, {'7', "७"}, {'8', "८"}, {'9', "९"} +}; + +std::vector englishMonths = { + "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" +}; + +std::vector englishMonthsDevnagari = { + "जनवरी", // January + "फेब्रुअरी", // February + "मार्च", // March + "अप्रिल", // April + "मे", // May + "जुन", // June + "जुलाई", // July + "अगस्ट", // August + "सेप्टेम्बर", // September + "अक्टोबर", // October + "नोभेम्बर", // November + "डिसेम्बर" // December +}; + +std::vector romanizedNepaliMonths = { + "Baisakh", "Jestha", "Ashadh", "Shrawan", "Bhadra", "Ashwin", "Kartik", "Mangsir", "Poush", "Magh", "Falgun", "Chaitra" +}; + +std::vector nepaliMonths = { + "बैशाख", "जेष्ठ", "आषाढ", "श्रावण", "भाद्रपद", "आश्विन", "कार्तिक", "मङ्सिर", "पौष", "माघ", "फाल्गुन", "चैत्र" +}; + +std::vector englishWeekdays = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +}; + +std::vector romanizedNepaliWeekdays = { + "Ravivar", "Somvar", "Mangalvar", "Budhvar", "Brihaspativar", "Shukravar", "Shanivar" +}; + +std::vector nepaliWeekdays = { + "आइतबार", "सोमबार", "मङ्गलबार", "बुधबार", "बिहीबार", "शुक्रबार", "शनिबार" +}; -// Helper function to get the current date void getCurrentDate(int &year, int &month, int &day) { - std::time_t now = std::time(nullptr); - std::tm timeinfo = *std::localtime(&now); - year = timeinfo.tm_year + 1900; - month = timeinfo.tm_mon + 1; // Adjust month from 0-based to 1-based - day = timeinfo.tm_mday; + // Get the current time + time_t t = time(0); // Current time in seconds since the Unix epoch + struct tm * now = localtime(&t); // Get local time + + // Extract the year, month, and day from the tm struct + year = now->tm_year + 1900; // tm_year is years since 1900 + month = now->tm_mon + 1; // tm_mon is 0-indexed (0 = January, 11 = December) + day = now->tm_mday; // tm_mday is the day of the month } -void NoArgs() { - int year, month, day; - getCurrentDate(year, month, day); - bikram bsdate; - bsdate.fromGregorian(year, month, day); - std::string bs_weekday_name = bsdate.getWeekdayName(year, month, day); - std::cout << "\e[36m Today's Date:\e[0m" << std::endl; - std::cout << " \e[33m Gregorian: \e[0m" - "\e[35m" << year << " " << month << " " << day << " " << bsdate.getWeekdayName(year, month, day) << " " << "\e[0m" << std::endl; - std::cout << " \e[33m Bikram Sambat: \e[0m" - "\e[35m" << bsdate.getYear() << " " << bsdate.getMonth() << " " << bsdate.getDay() << " " - << bs_weekday_name << " "<< " \e[33m days in bikram month: \e[0m" << bsdate.daysInMonth(bsdate.getYear(), bsdate.getMonth()) << "\e[0m" << std::endl; - std::cerr << "Usage: \n\e[31m" - << "Convert to Nepali Date: nepdate-cli --conv --tobs year month day\n" - << "Convert to Gregorian Date: nepdate-cli --conv --toad year month day\n" - << "Show today's date: nepdate-cli --today\n\e[0m"; +// Convert numbers to Devanagari script +std::string convertToDevanagari(int num) { + std::string result = ""; + std::string numStr = std::to_string(num); // Convert the number to a string + for (char c : numStr) { + if (devanagariNumbers.find(c) != devanagariNumbers.end()) { + result += devanagariNumbers[c]; // Append the Devanagari digit + } else { + result += c; // In case it's not a digit, just append the character + } + } + + return result; +} + +// Get month name based on --unicode and command context +std::string getMonthName(int month, bool unicode, bool isToad) { + if (unicode && isToad) { + return englishMonthsDevnagari[month - 1]; // Use Devanagari for English months if both flags are true + } + if (isToad) { + return englishMonths[month - 1]; // Use English months for --toad + } + if (unicode) { + return nepaliMonths[month - 1]; // Use Nepali months if unicode is true + } + return romanizedNepaliMonths[month - 1]; // Use romanized Nepali months otherwise } -void showTodaysDate() { +// Get weekday name based on --unicode +std::string getWeekdayName(int dayOfWeek, bool unicode, bool isToad) { + if (unicode && isToad) { + return nepaliWeekdays[dayOfWeek]; + } if (isToad) { + return englishWeekdays[dayOfWeek]; // Use English months for --toad + } + if (unicode) { + return nepaliWeekdays[dayOfWeek]; + } else { + return romanizedNepaliWeekdays[dayOfWeek]; + } +} + +// Get English month name +std::string getEnglishMonthName(int month) { + return englishMonths[month - 1]; +} + +// Get English weekday name +std::string getEnglishWeekdayName(int dayOfWeek) { + return englishWeekdays[dayOfWeek]; +} + +void displayFormattedDate(int year, int month, int day, const std::string& format, bool unicode, bool isToad) { + std::string result; + result.reserve(format.length() * 2); // Reserve space to avoid frequent reallocations + + // Helper lambda to conditionally convert numbers + auto maybeConvertToDevanagari = [unicode](int num) { + return unicode ? convertToDevanagari(num) : std::to_string(num); + }; + + for (size_t i = 0; i < format.length(); i++) { + if (format[i] == 'y') { + result += maybeConvertToDevanagari(year); + } else if (format[i] == 'm') { + result += maybeConvertToDevanagari(month); + } else if (format[i] == 'd') { + result += maybeConvertToDevanagari(day); + } else if (format[i] == 'M') { + result += getMonthName(month, unicode, isToad); // Pass isToad here + } else if (format[i] == 'w') { + result += getWeekdayName((day + 6) % 7, unicode, isToad); // Sunday is 0 in Gregorian + } else { + result += format[i]; + } + } + + std::cout << result << std::endl; +} + +void showTodaysDate(bool unicode, const std::string& format) { int year, month, day; - getCurrentDate(year, month, day); + getCurrentDate(year, month, day); // Get today's date + + // Convert today's date to Bikram Sambat bikram bsdate; bsdate.fromGregorian(year, month, day); - std::string bs_weekday_name = bsdate.getWeekdayName(year, month, day); - std::cout << "\e[35m" << bsdate.getYear() << " " << bsdate.getMonth() << " " << bsdate.getDay() << " " << bs_weekday_name << " " << std::endl; + // After conversion, get the Bikram Sambat year, month, and day + year = bsdate.getYear(); + month = bsdate.getMonth(); + day = bsdate.getDay(); + + displayFormattedDate(year, month, day, format, unicode, false); // Assume today is in AD (Gregorian) } int main(int argc, char *argv[]) { // Check for no arguments if (argc == 1) { - NoArgs(); // Show usage information below today's date + int year, month, day; + getCurrentDate(year, month, day); + + bikram bsdate; + bsdate.fromGregorian(year, month, day); + std::string bs_weekday_name = bsdate.getWeekdayName(year, month, day); + + std::cout << "\e[36m Today's Date:\e[0m" << std::endl; + std::cout << " \e[33m Gregorian: \e[0m" + << "\e[35m" << year << " " << month << " " << day << " " + << bsdate.getWeekdayName(year, month, day) << " " << "\e[0m" << std::endl; + std::cout << " \e[33m Bikram Sambat: \e[0m" + << "\e[35m" << bsdate.getYear() << " " << bsdate.getMonth() << " " + << bsdate.getDay() << " " << bs_weekday_name << " " + << " \e[33m days in bikram month: \e[0m" + << bsdate.daysInMonth(bsdate.getYear(), bsdate.getMonth()) + << "\e[0m" << std::endl; + + std::cerr << "Usage: \n" + << " \e[31mShow today's date: ./ndate --today [--unicode] [--format format_string]\n\e[0m" + << " \e[31mConvert to Bikram Sambat Date: ./ndate --tobs year month day [--unicode] [--format format_string]\n\e[0m" + << " \e[31mConvert to Gregorian Date: ./ndate --toad year month day [--unicode] [--format format_string]\n\e[0m" + << "Options:\n" + << " \e[31m--unicode : Display the date in Unicode format (Devanagari script).\e[0m\n" + << " \e[31m--format format_string : Specify a custom format for the date (e.g., 'y-m-d', 'd-M-y'). \e[0mDefault: 'y-m-d'\n" + << "\nFormat Specifiers:\n" + << " \e[31my : Year\n" + << " \e[31mm : Month (numeric)\n" + << " \e[31md : Day\n" + << " \e[31mw : Weekday name\n" + << " \e[31mM : Month name\n\e[0m" + << "\nExample commands:\n" + << " \e[31m./ndate --today --unicode --format 'd-M-y' : Show today's date in Unicode with custom format.\n" + << " ./ndate --tobs 2024 11 15 --unicode --format 'y-m-d' : Convert a Gregorian date to Bikram Sambat date.\n" + << " ./ndate --toad 2081 8 30 --unicode --format 'y/m/d' : Convert a Nepali date to Gregorian date.\n\e[0m" + << "\e[35mFor more information, visit: https://github.com/opensource-nepal/nepdate-cli\n\e[0m"; + return 0; } + bool unicode = false; std::string command = argv[1]; + std::string format = "y-m-d"; // Default format + + // Parse the arguments + for (int i = 2; i < argc; ++i) { + if (std::string(argv[i]) == "--unicode") { + unicode = true; + } else if (std::string(argv[i]) == "--format" && i + 1 < argc) { + format = argv[i + 1]; + ++i; // Skip the next argument as it is the format string + } else if (command == "--today" && std::string(argv[i]) != "--unicode") { + format = argv[i]; + } + } // Handle the --today command if (command == "--today") { - showTodaysDate(); + showTodaysDate(unicode, format); // Pass the format argument here return 0; } - // Handle the conversion commands - if (argc != 6 || std::string(argv[1]) != "--conv" || - (std::string(argv[2]) != "--tobs" && std::string(argv[2]) != "--toad")) { - NoArgs(); // Show usage information for invalid commands - return 1; - } + // Handle the conversion commands (at least 5 arguments, up to 7 arguments) + if ((command == "--toad" || command == "--tobs") && argc >= 5) { + int year = std::stoi(argv[2]); + int month = std::stoi(argv[3]); + int day = std::stoi(argv[4]); - std::string convType = argv[2]; - int year = std::stoi(argv[3]); - int month = std::stoi(argv[4]); - int day = std::stoi(argv[5]); + // Optionally handle --unicode and --format in the command + for (int i = 5; i < argc; ++i) { + if (std::string(argv[i]) == "--unicode") { + unicode = true; + } else if (std::string(argv[i]) == "--format" && i + 1 < argc) { + format = argv[i + 1]; + ++i; // Skip the next argument as it is the format string + } + } - bikram bsdate; + // Convert to Bikram Sambat Date + bikram bsdate; - if (convType == "--tobs") { - bsdate.fromGregorian(year, month, day); - } else if (convType == "--toad") { - bsdate.fromNepali(year, month, day); - } - - int convertedYear = bsdate.getYear(); - int convertedMonth = bsdate.getMonth(); - int convertedDay = bsdate.getDay(); - std::string bs_weekday_name = bsdate.getWeekdayName(year, month, day); - std::string gregorian_weekday_name = ""; + if (command == "--tobs") { + bsdate.fromGregorian(year, month, day); + //displayFormattedDate(year, month, day, format, unicode, false); + } else if (command == "--toad") { + bsdate.fromNepali(year, month, day); + //displayFormattedDate(year, month, day, format, unicode, true); + } else { + std::cerr << "Invalid command or insufficient arguments.\n"; + return 1; // Exit with an error code + } - if (convType == "--tobs") { - // Get weekday name for Gregorian date after conversion - gregorian_weekday_name = bsdate.getWeekdayName(convertedYear, convertedMonth, convertedDay); + // Get the converted date values + year = bsdate.getYear(); + month = bsdate.getMonth(); + day = bsdate.getDay(); - std::cout << " \e[33m Bikram Sambat Date: \e[0m" - "\e[35m" << convertedYear << " " << convertedMonth << " " << convertedDay << " " << bs_weekday_name << " " << "\e[0m" - << " \e[33m days in bikram month: \e[0m" << bsdate.daysInMonth(bsdate.getYear(), bsdate.getMonth()) << "\e[0m" << std::endl; - } else if (convType == "--toad") { - // Convert to Gregorian date for weekday calculation - bsdate.toGregorian(year, month, day, convertedYear, convertedMonth, convertedDay); + // Display the converted date again based on the unicode flag + displayFormattedDate(year, month, day, format, unicode, command == "--toad"); - int gregorian_weekday = bsdate.getDayOfWeek(); - std::string gregorian_weekday_name = bsdate.getWeekdayName(convertedYear, convertedMonth, convertedDay); - - std::cout << "\e[33m Gregorian Date: \e[0m" - "\e[35m" << convertedYear << " " << convertedMonth << " " << convertedDay << " " << gregorian_weekday_name << " " << "\e[0m" << std::endl; + return 0; } - return 0; -} \ No newline at end of file + return 1; // Default return if no valid command is found +} From 7023d2898b1f1cddfc0c8fc852c7fe432098da49 Mon Sep 17 00:00:00 2001 From: khumnath Date: Sat, 16 Nov 2024 18:39:43 +0900 Subject: [PATCH 2/2] bump version + readme update --- debian/changelog | 6 ++++-- src/main.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/debian/changelog b/debian/changelog index 34031a6..f555baa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,7 @@ -nepdate-cli (1.0.0) stable; urgency=medium +nepdate-cli (1.0.2) stable; urgency=medium - * Initial release. + * update with date output format + * added option to display only Bikram sambat date + * rearranged for repo change -- khumnath Fri, 09 Aug 2024 12:00:00 +0000 diff --git a/src/main.cpp b/src/main.cpp index a64af7c..a3a984d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -196,9 +196,9 @@ int main(int argc, char *argv[]) { << "\e[0m" << std::endl; std::cerr << "Usage: \n" - << " \e[31mShow today's date: ./ndate --today [--unicode] [--format format_string]\n\e[0m" - << " \e[31mConvert to Bikram Sambat Date: ./ndate --tobs year month day [--unicode] [--format format_string]\n\e[0m" - << " \e[31mConvert to Gregorian Date: ./ndate --toad year month day [--unicode] [--format format_string]\n\e[0m" + << " \e[31mShow today's date: ./nepdate-cli --today [--unicode] [--format format_string]\n\e[0m" + << " \e[31mConvert to Bikram Sambat Date: ./nepdate-cli --tobs year month day [--unicode] [--format format_string]\n\e[0m" + << " \e[31mConvert to Gregorian Date: ./nepdate-cli --toad year month day [--unicode] [--format format_string]\n\e[0m" << "Options:\n" << " \e[31m--unicode : Display the date in Unicode format (Devanagari script).\e[0m\n" << " \e[31m--format format_string : Specify a custom format for the date (e.g., 'y-m-d', 'd-M-y'). \e[0mDefault: 'y-m-d'\n" @@ -209,9 +209,9 @@ int main(int argc, char *argv[]) { << " \e[31mw : Weekday name\n" << " \e[31mM : Month name\n\e[0m" << "\nExample commands:\n" - << " \e[31m./ndate --today --unicode --format 'd-M-y' : Show today's date in Unicode with custom format.\n" - << " ./ndate --tobs 2024 11 15 --unicode --format 'y-m-d' : Convert a Gregorian date to Bikram Sambat date.\n" - << " ./ndate --toad 2081 8 30 --unicode --format 'y/m/d' : Convert a Nepali date to Gregorian date.\n\e[0m" + << " \e[31m./nepdate-cli --today --unicode --format 'd-M-y' : Show today's date in Unicode with custom format.\n" + << " ./nepdate-cli --tobs 2024 11 15 --unicode --format 'y-m-d' : Convert a Gregorian date to Bikram Sambat date.\n" + << " ./nepdate-cli --toad 2081 8 30 --unicode --format 'y/m/d' : Convert a Nepali date to Gregorian date.\n\e[0m" << "\e[35mFor more information, visit: https://github.com/opensource-nepal/nepdate-cli\n\e[0m"; return 0;