mirror of
				git://git.code.sf.net/p/cdesktopenv/code
				synced 2025-03-09 15:50:02 +00:00 
			
		
		
		
	Fix unexpected output from 'printf %T' with certain formats (#65)
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
This commit is contained in:
		
							parent
							
								
									e70925ce10
								
							
						
					
					
						commit
						9526b3fa08
					
				
					 7 changed files with 103 additions and 22 deletions
				
			
		|  | @ -1221,8 +1221,74 @@ USAGE_LICENSE | |||
| 		"convert it to an extended regular expression.]" | ||||
| 	"[+%T?Treat \astring\a as a date/time string and format it.  The " | ||||
| 		"\bT\b can be preceded by \b(\b\adformat\a\b)\b, where " | ||||
| 		"\adformat\a is a date format as defined by the \bdate\b " | ||||
| 		"command.]" | ||||
| 		"\adformat\a is a date format. The accepted date formats are " | ||||
| 		"as follows:]{" | ||||
| 			"[+%?% character]" | ||||
| 			"[+a?abbreviated weekday name]" | ||||
| 			"[+A?full weekday name]" | ||||
| 			"[+b?abbreviated month name]" | ||||
| 			"[+B?full month name]" | ||||
| 			"[+c?\bctime\b(3) style date without the trailing newline]" | ||||
| 			"[+C?2-digit century]" | ||||
| 			"[+d?day of month number]" | ||||
| 			"[+D?date as \amm/dd/yy\a]" | ||||
| 			"[+e?blank padded day of month number]" | ||||
| 			"[+f?print a date with the format '\%Y.\%m.\%d-\%H:\%M:\%S']" | ||||
| 			"[+F?%ISO 8601:2000 standard date format; equivalent to Y-%m-%d]" | ||||
| 			"[+g?\bls\b(1) \b-l\b recent date with \ahh:mm\a]" | ||||
| 			"[+G?\bls\b(1) \b-l\b distant date with \ayyyy\a]" | ||||
| 			"[+h?abbreviated month name]" | ||||
| 			"[+H?24-hour clock hour, zero-padded]" | ||||
| 			"[+i?international \bdate\b(1) date with time zone type name]" | ||||
| 			"[+I?12-hour clock hour, zero-padded]" | ||||
| 			"[+j?1-offset Julian date]" | ||||
| 			"[+J?0-offset Julian date]" | ||||
| 			"[+k?24-hour clock hour, blank-padded]" | ||||
| 			"[+K?all numeric date; equivalent to \b%Y-%m-%d+%H:%M:%S\b; \b%_[EO]]K\b for space separator, %OK adds \b.%N\b, \b%EK\b adds \b%.N%z\b, \b%_EK\b adds \b.%N %z\b]" | ||||
| 			"[+l?12-hour clock hour, blank-padded]" | ||||
| 			"[+L?locale default date format]" | ||||
| 			"[+m?month number]" | ||||
| 			"[+M?minutes]" | ||||
| 			"[+n?newline character]" | ||||
| 			"[+N?nanoseconds 000000000-999999999]" | ||||
| 			"[+p?meridian (e.g., \bAM\b or \bPM\b)]" | ||||
| 			"[+q?quarter of the year]" | ||||
| 			"[+Q?\a<del>recent<del>distant<del>\a: \a<del>\a is a unique " | ||||
| 				"delimter character; \arecent\a format for recent " | ||||
| 				"dates, \adistant\a format otherwise]" | ||||
| 			"[+r?12-hour time as \ahh:mm:ss meridian\a]" | ||||
| 			"[+R?24-hour time as \ahh:mm\a]" | ||||
| 			"[+s?number of seconds since the epoch; \a.prec\a preceding " | ||||
| 				"\bs\b appends \aprec\a nanosecond digits, \b9\b if " | ||||
| 				"\aprec\a is omitted]" | ||||
| 			"[+S?seconds 00-60]" | ||||
| 			"[+t?tab character]" | ||||
| 			"[+T?24-hour time as \ahh:mm:ss\a]" | ||||
| 			"[+u?weekday number 1(Monday)-7]" | ||||
| 			"[+U?week number with Sunday as the first day]" | ||||
| 			"[+V?ISO week number (i18n is \afun\a)]" | ||||
| 			"[+w?weekday number 0(Sunday)-6]" | ||||
| 			"[+W?week number with Monday as the first day]" | ||||
| 			"[+x?locale date style that includes month, day and year]" | ||||
| 			"[+X?locale time style that includes hours and minutes]" | ||||
| 			"[+y?2-digit year (you'll be sorry)]" | ||||
| 			"[+Y?4-digit year]" | ||||
| 			"[+z?time zone \aSHHMM\a west of GMT offset where S is " | ||||
| 				"\b+\b or \b-\b, use pad _ for \aSHH:MM\a]" | ||||
| 			"[+Z?time zone name]" | ||||
| 			"[+=[=]][-+]]flag?set (default or +) or clear (-) \aflag\a " | ||||
| 				"for the remainder of \aformat\a, or for the remainder " | ||||
| 				"of the process if \b==\b is specified. \aflag\a may be:]{" | ||||
| 				"[+l?enable leap second adjustments]" | ||||
| 				"[+n?convert \b%S\b as \b%S.%N\b]" | ||||
| 				"[+u?UTC time zone]" | ||||
| 			"}" | ||||
| 			"[+#?equivalent to %s]" | ||||
| 			"[+??alternate?use \aalternate\a format if a default format " | ||||
| 				"override has not been specified, e.g., \bls\b(1) uses " | ||||
| 				"\"%?%l\"; export TM_OPTIONS=\"format='\aoverride\a'\" " | ||||
| 				"to override the default]" | ||||
| 		"}" | ||||
| 	"[+%Z?Output a byte whose value is \b0\b.]" | ||||
| 	"\fextra\f" | ||||
| "}" | ||||
|  |  | |||
|  | @ -17,4 +17,4 @@ | |||
| *                  David Korn <dgk@research.att.com>                   * | ||||
| *                                                                      * | ||||
| ***********************************************************************/ | ||||
| #define SH_RELEASE	"93u+m 2020-07-06" | ||||
| #define SH_RELEASE	"93u+m 2020-07-07" | ||||
|  |  | |||
|  | @ -6527,10 +6527,7 @@ A | |||
| .BI %( date-format )T | ||||
| format can be used to treat an argument as a date/time string | ||||
| and to format the date/time according to the | ||||
| .I date-format\^ | ||||
| as defined for the | ||||
| .BR date (1) | ||||
| command. | ||||
| .IR date-format . | ||||
| .TP | ||||
| .B %Z | ||||
| A | ||||
|  |  | |||
|  | @ -749,5 +749,12 @@ unset foo | |||
| 	test_func | ||||
| ) | ||||
| 
 | ||||
| # ====== | ||||
| # Test the output of nonstandard date formats with 'printf %T' | ||||
| [[ $(printf '%(%l)T') == $(printf '%(%_I)T') ]] || err_exit 'date format %l is not the same as %_I' | ||||
| [[ $(printf '%(%k)T') == $(printf '%(%_H)T') ]] || err_exit 'date format %k is not the same as %_H' | ||||
| [[ $(printf '%(%f)T') == $(printf '%(%Y.%m.%d-%H:%M:%S)T') ]] || err_exit 'date format %f is not the same as %Y.%m.%d-%H:%M:%S' | ||||
| [[ $(printf '%(%q)T') == $(printf '%(%Qz)T') ]] && err_exit 'date format %q is the same as %Qz' | ||||
| 
 | ||||
| # ====== | ||||
| exit $((Errors<125?Errors:125)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue