diff --git a/Base/usr/share/man/man1/date.md b/Base/usr/share/man/man1/date.md index e05d0096a6..8ec6c346f7 100644 --- a/Base/usr/share/man/man1/date.md +++ b/Base/usr/share/man/man1/date.md @@ -5,7 +5,7 @@ date - print or set the system date and time ## Synopsis ```**sh -$ date [--set date] [--unix] [--iso-8601] [--rfc-3339] [--rfc-5322] +$ date [--set date] [--unix] [--iso-8601] [--rfc-3339] [--rfc-5322] [format-string] ``` ## Description @@ -21,12 +21,19 @@ or print the system date and time in various formats. * `-r`, `--rfc-3339`: Print date in RFC 3339 format * `-R`, `--rfc-5322`: Print date in RFC 5322 format +## Arguments + +* `format-string`: Custom format to print the date in. Must start with a '+' character. + ## Examples ```sh # Print the current date and time in ISO 8601 format $ date --iso-8601 +# Print the current date in a custom format +$ date +%Y-%m-%d + # Set date to 1610017485 (UNIX time) $ date -s 1610017485 ``` diff --git a/Userland/Utilities/date.cpp b/Userland/Utilities/date.cpp index 4fc23b578b..a7fdcb8a0d 100644 --- a/Userland/Utilities/date.cpp +++ b/Userland/Utilities/date.cpp @@ -20,6 +20,7 @@ ErrorOr serenity_main(Main::Arguments arguments) bool print_rfc_3339 = false; bool print_rfc_5322 = false; const char* set_date = nullptr; + StringView format_string; Core::ArgsParser args_parser; args_parser.add_option(set_date, "Set system date and time", "set", 's', "date"); @@ -27,6 +28,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(print_iso_8601, "Print date in ISO 8601 format", "iso-8601", 'i'); args_parser.add_option(print_rfc_3339, "Print date in RFC 3339 format", "rfc-3339", 'r'); args_parser.add_option(print_rfc_5322, "Print date in RFC 5322 format", "rfc-5322", 'R'); + args_parser.add_positional_argument(format_string, "Custom format to print the date in", "format-string", Core::ArgsParser::Required::No); args_parser.parse(arguments); if (set_date != nullptr) { @@ -43,15 +45,21 @@ ErrorOr serenity_main(Main::Arguments arguments) return 0; } - // FIXME: this should be improved and will need to be cleaned up - // when additional output formats and formatting is supported - if (print_unix_date && print_iso_8601 && print_rfc_3339 && print_rfc_5322) { - warnln("date: multiple output formats specified"); + if (print_unix_date + print_iso_8601 + print_rfc_3339 + print_rfc_5322 + !format_string.is_null() > 1) { + warnln("date: Multiple output formats specified"); return 1; } auto date = Core::DateTime::now(); - if (print_unix_date) { + if (!format_string.is_null()) { + // FIXME: If the string argument does not start with a '+' sign, POSIX says + // we should parse that as a date, and set the system time to it. + if (format_string.length() == 0 || format_string[0] != '+') { + warnln("date: Format string must start with '+'"); + return 1; + } + outln("{}", date.to_string(format_string.substring_view(1))); + } else if (print_unix_date) { outln("{}", date.timestamp()); } else if (print_iso_8601) { outln("{}", date.to_string("%Y-%m-%dT%H:%M:%S%:z"));