Bug 27796

Summary: Use of -v flag of date(1) can give non-intuitive results
Product: Base System Reporter: jabley <jabley>
Component: binAssignee: Brian Somers <brian>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.4-RELEASE   
Hardware: Any   
OS: Any   

Description jabley 2001-05-31 16:50:01 UTC
  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.
Comment 1 Brian Somers freebsd_committer freebsd_triage 2001-06-01 00:28:17 UTC
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 :) 


Comment 2 Brian Somers freebsd_committer freebsd_triage 2001-06-01 00:28:17 UTC
Responsible Changed
From-To: freebsd-bugs->brian

date -v is my fault^w^wmine
Comment 3 Brian Somers freebsd_committer freebsd_triage 2001-07-30 19:42:12 UTC
State Changed
From-To: feedback->closed

No response from the submitter