-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
printf %T formats do not follow strftime(3) #62
Comments
It seems to be particularly
So you weren't getting seconds; you were getting minutes twice. This is broken in ksh2020 too, so there's no existing fix to backport. |
ksh/src/lib/libast/tm/tmxfmt.c Lines 336 to 338 in 1ca9286
$ printf '%(%l)T\n'; printf '%(%QL)T\n'
Jul 4 23:14
Jul 4 23:14 |
Wow. And there's a bunch more of these translations marked obsolete as well. The full list of those marked obsolete:
None of these are specified by POSIX But it's clearly against widespread expectations, the principle of least astonishment, etc. to act differently from GNU and BSD Going by to the multishell ksh93 repo (thanks for linking to that in another comment @JohnoKing, I'd no idea this existed), these have been marked obsolete as of version 2010-06-21. The ones that conflict with BSD strftime(3) as on my Mac are: Or we could be radical and strip out the entire AST implementation of strftime(3) and use the OS's standard strftime(3) instead. But this branch is not really about that, is it? There are probably old ksh scripts that use some of these AST-isms. So, it should also be documented that I wonder if even changing the behaviour of Opinions welcome… |
On Busybox strftime(3),
|
One thing that is definitely a bug is how
and in
Both of these are obviously wrong. ksh does not use the date(1) command, which uses the OS-provided strftime(3); it uses its own implementation of strftime(3) which will always differ from the OS-provided implementation for non-standard conversion specifiers simply because the OS-provided implementations differ from each other. So the only way to make ksh behave according to the documentation would be to remove libast's strftime(3) and use the OS-provided one instead. But that risks creating too many backwards compatibility problems. |
Here is a quick patch to make AST --- a/src/lib/libast/tm/tmxfmt.c
+++ b/src/lib/libast/tm/tmxfmt.c
@@ -316,9 +316,9 @@ tmxfmt(char* buf, size_t len, const char* format, Time_t t)
case 'J': /* Julian date (0 offset) */
cp = number(cp, ep, (long)tm->tm_yday, 3, width, pad);
continue;
- case 'k': /* (AST) OBSOLETE use %QD */
- p = "%QD";
- goto push;
+ case 'k': /* hour (0 - 23) with blank padding */
+ cp = number(cp, ep, (long)tm->tm_hour, -2, width, pad);
+ continue;
case 'K': /* (AST) largest to smallest */
switch (alt)
{
@@ -333,9 +333,11 @@ tmxfmt(char* buf, size_t len, const char* format, Time_t t)
break;
}
goto push;
- case 'l': /* (AST) OBSOLETE use %QL */
- p = "%QL";
- goto push;
+ case 'l': /* hour (0 - 12) with blank padding */
+ if ((n = tm->tm_hour) > 12) n -= 12;
+ else if (n == 0) n = 12;
+ cp = number(cp, ep, (long)n, -2, width, pad);
+ continue;
case 'L': /* (AST) OBSOLETE use %Ql */
p = "%Ql";
goto push;
ksh/src/lib/libast/tm/tmxfmt.c Lines 35 to 45 in 1ca9286
|
Yup, applied that, works.
Thanks! |
This commit changes the behavior of four date formats accepted by 'printf %()T' because the old behavior is not compatible with modern implementations of date(1): - %k and %l now return a blank-padded hour, the former based on a 24-hour clock and the latter a 12-hour clock (these are common extensions present on Linux and BSD systems). - %f now returns a date with the format %Y.%m.%d-%H:%M:%S' (BusyBox extension). - %q now returns the quarter of the current year (GNU extension). src/cmd/ksh93/data/builtins.c: - Copy the date format documentation from date in libcmd to the printf man page (for documenting 'printf %T'). src/cmd/ksh93/tests/builtins.sh: - Add four regression tests for the changed date formats. src/cmd/ksh93/sh.1: - Remove inaccurate information about the date formats accepted by printf %T'. The KornShell uses a custom version of strftime(3) that isn't guaranteed to accepts the same formats as the native strftime function. src/lib/libast/tm/tmxfmt.c: - Change the behavior of %f, %k, %l and %q to the common behavior. %k and %l are implemented as aliases to %_H and %_I to avoid duplicating code. src/lib/libcmd/date.c: - Update the documentation for the AST date command since it is also affected by the changes to 'printf %T'. Fixes ksh93#62
This commit changes the behavior of four date formats accepted by 'printf %()T' because the old behavior is not compatible with modern implementations of date(1): - %k and %l now return a blank-padded hour, the former based on a 24-hour clock and the latter a 12-hour clock (these are common extensions present on Linux and *BSD). - %f now returns a date with the format '%Y.%m.%d-%H:%M:%S' (BusyBox extension). - %q now returns the quarter of the current year (GNU extension). src/cmd/ksh93/data/builtins.c: - Copy the date format documentation from date in libcmd to the printf man page (for documenting 'printf %T'). src/cmd/ksh93/tests/builtins.sh: - Add four regression tests for the changed date formats. src/cmd/ksh93/sh.1: - Remove inaccurate information about the date formats accepted by printf %T'. The KornShell uses a custom version of strftime(3) that isn't guaranteed to accepts the same formats as the native strftime function. src/lib/libast/tm/tmxfmt.c: - Change the behavior of %f, %k, %l and %q to the common behavior. %k and %l are implemented as aliases to %_H and %_I to avoid duplicating code. src/lib/libcmd/date.c: - Update the documentation for the AST date command since it is also affected by the changes to 'printf %T'. Fixes ksh93#62
Is the %()T format code actually documented in the new Kornshell book somewhere and I just can't find it? I even went to archive.org's PDF copy of the book and searched in it, but didn't find anything. Something only tangentially related... is there an electronic copy of that book somewhere (other than the archive.org loaner copy)? I've bought the original one (ksh88), the new one (ksh93), and the O'Reilly, but having an easily searchable I could keep on a tablet.... |
I noticed before that |
I didn't think that %()T was that old, but I could be wrong. I doubt if it
would be in the book. Maybe someone could check old ksh versions, but
presence in the code does not equate to being officially released.
…On Thu, 9 Jul 2020, 2:15 am Martijn Dekker, ***@***.***> wrote:
I noticed before that %T is not documented in the book; it must be a
newer addition. No downloadable digital copy is available, AFAIK.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#62 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABUCE7VHN75UFN23WIVXCFTR2SLSVANCNFSM4OQVYRVA>
.
|
This commit changes the behavior of four date formats accepted by 'printf %()T' because the old behavior is not compatible with modern implementations of date(1): - %k and %l now return a blank-padded hour, the former based on a 24-hour clock and the latter a 12-hour clock (these are common extensions present on Linux and *BSD). - %f now returns a date with the format '%Y.%m.%d-%H:%M:%S' (BusyBox extension). - %q now returns the quarter of the current year (GNU extension). src/cmd/ksh93/data/builtins.c: - Copy the date format documentation from date in libcmd to the printf man page (for documenting 'printf %T'). src/cmd/ksh93/tests/builtins.sh: - Add four regression tests for the changed date formats. src/cmd/ksh93/sh.1: - Remove inaccurate information about the date formats accepted by printf %T'. The KornShell uses a custom version of strftime(3) that isn't guaranteed to accepts the same formats as the native strftime function. src/lib/libast/tm/tmxfmt.c: - Change the behavior of %f, %k, %l and %q to the common behavior. %k and %l are implemented as aliases to %_H and %_I to avoid duplicating code. src/lib/libcmd/date.c: - Update the documentation for the AST date command since it is also affected by the changes to 'printf %T'. Fixes #62
It's simple:
but:
The man page for strftime(3) says %l is supposed to be the 12-hour hour without leading zeroes:
And I didn't ask for the seconds at all, but ksh is displaying them.
93u+ and 93u+m both do the same thing. I can't find %()T anywhere in the new Korn book, but Learning the Korn Shell 2nd ed says it should reformat it "according to the date(1) specification." (p225)
(macOS 10.14.6)
The text was updated successfully, but these errors were encountered: