| Summary: | Use of -v flag of date(1) can give non-intuitive results | ||
|---|---|---|---|
| Product: | Base System | Reporter: | jabley <jabley> |
| Component: | bin | Assignee: | Brian Somers <brian> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.4-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->feedback Adjusting the date is not as straight forward as some might think. To find out what ``next month'' is you should ``date -v1d -v+1m +%m'' as there is always a ``day 1'' in each month. Your example is avoided in the man page as this rounding is done by mktime(3). Another good (confusing) example is ``date -v3m -v29d -v-1m''. If you (or anyone) care to produce documentation patches, I'm certainly happy to see if I can get them past a freebsd-doc review :) Responsible Changed From-To: freebsd-bugs->brian date -v is my fault^w^wmine State Changed From-To: feedback->closed No response from the submitter |
jabley@goose[132]$ date Thu May 31 11:44:23 EDT 2001 jabley@goose[133]$ date -v+1m Sun Jul 1 11:44:25 EDT 2001 jabley@goose[134]$ date -v+1m +%m jabley@goose[136]$ date -v+1m +%m 07 Intuitively, I would expect "date -v+1m +%m" to mean "tell me the number of next month", and return 06 instead of 07. Looking at the source to date(1), it looks as though -v+1m just adds 1 to the tm_mon element of the struct tm (see src/bin/date/vary.c). The problem then is that the resulting date is 31 June 2001, and since June only has 30 days, the month gets wrapped. As the manual page says: When the date is adjusted to a specific value that doesn't actu- ally exist (for example March 26, 1:30 BST 2000 in the Europe/London timezone), the date will be silently adjusted for- wards in units of one hour until it reaches a valid time. When the date is adjusted to a specific value that occurs twice (for example October 29, 1:30 2000), the resulting timezone will be set so that the date matches the earlier of the two times. It doesn't say so explicitly, but I suspect similar logic is being applied to days that don't exist within a month. Fix: None suggested -- I'm not sure if my semantic understanding of the -v flag is accurate. How-To-Repeat: jabley@goose[132]$ date Thu May 31 11:44:23 EDT 2001 jabley@goose[133]$ date -v+1m Sun Jul 1 11:44:25 EDT 2001 jabley@goose[134]$ date -v+1m +%m jabley@goose[136]$ date -v+1m +%m 07 Run on any day N of month M where month (M+1) has less than N days.