View | Details | Raw Unified | Return to bug 16005
Collapse All | Expand All

(-)date/date.1 (+11 lines)
Lines 48-53 Link Here
48
.Op Fl r Ar seconds
48
.Op Fl r Ar seconds
49
.Op Fl t Ar minutes_west
49
.Op Fl t Ar minutes_west
50
.Op Fl v Ns Ar [+|-]val Ns Op ymwdHMS
50
.Op Fl v Ns Ar [+|-]val Ns Op ymwdHMS
51
.Op Fl V Ns Ar [+|-]val Ns Op ymwdHMS
51
.Ar ...
52
.Ar ...
52
.Op Fl f Ar fmt Ar date | [[[[[cc]yy]mm]dd]HH]MM[\&.ss]
53
.Op Fl f Ar fmt Ar date | [[[[[cc]yy]mm]dd]HH]MM[\&.ss]
53
.Op Cm + Ns Ar format
54
.Op Cm + Ns Ar format
Lines 148-153 Link Here
148
if the given week day or month is the same as the current one.
149
if the given week day or month is the same as the current one.
149
.Pp
150
.Pp
150
Refer to the examples below for further details.
151
Refer to the examples below for further details.
152
.It Fl V
153
Adjust the second, minute, hour, month day, week day, month or year according to
154
.Ar val ,
155
but behave logically.
156
.Pp
157
I.e., if you are at Dec 31th and adjust the date with
158
.Fl -V-1m
159
the date will be Nov 30th.
160
.Fl v
161
would have produced a date of Dec 1st.
151
.El
162
.El
152
.Pp
163
.Pp
153
An operand with a leading plus (``+'') sign signals a user-defined format
164
An operand with a leading plus (``+'') sign signals a user-defined format
(-)date/date.c (-2 / +5 lines)
Lines 97-103 Link Here
97
	rflag = 0;
97
	rflag = 0;
98
	jflag = nflag = 0;
98
	jflag = nflag = 0;
99
	set_timezone = 0;
99
	set_timezone = 0;
100
	while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:")) != -1)
100
	while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:V:")) != -1)
101
		switch((char)ch) {
101
		switch((char)ch) {
102
		case 'd':		/* daylight savings time */
102
		case 'd':		/* daylight savings time */
103
			tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0;
103
			tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0;
Lines 128-135 Link Here
128
		case 'u':		/* do everything in GMT */
128
		case 'u':		/* do everything in GMT */
129
			(void)setenv("TZ", "GMT0", 1);
129
			(void)setenv("TZ", "GMT0", 1);
130
			break;
130
			break;
131
		case 'V':
132
			v = vary_append(v, optarg, 1);
133
			break;
131
		case 'v':
134
		case 'v':
132
			v = vary_append(v, optarg);
135
			v = vary_append(v, optarg, 0);
133
			break;
136
			break;
134
		default:
137
		default:
135
			usage();
138
			usage();
(-)date/vary.c (-9 / +20 lines)
Lines 68-74 Link Here
68
}
68
}
69
69
70
struct vary *
70
struct vary *
71
vary_append(struct vary *v, char *arg)
71
vary_append(struct vary *v, char *arg, char vary_logical)
72
{
72
{
73
  struct vary *result, **nextp;
73
  struct vary *result, **nextp;
74
74
Lines 82-87 Link Here
82
82
83
  *nextp = (struct vary *)malloc(sizeof(struct vary));
83
  *nextp = (struct vary *)malloc(sizeof(struct vary));
84
  (*nextp)->arg = arg;
84
  (*nextp)->arg = arg;
85
  (*nextp)->vary_logical = vary_logical;
85
  (*nextp)->next = NULL;
86
  (*nextp)->next = NULL;
86
  return result;
87
  return result;
87
}
88
}
Lines 132-139 Link Here
132
  return mktime(t) != -1;
133
  return mktime(t) != -1;
133
}
134
}
134
135
136
#define is_leap(year) (!((year) % 4) && (! ((year) % 400) || (year) % 100))
135
static int
137
static int
136
adjmon(struct tm *t, char type, int val, int istext)
138
adjmon(struct tm *t, char type, int val, int istext, char vary_logical)
137
{
139
{
138
  if (val < 0)
140
  if (val < 0)
139
    return 0;
141
    return 0;
Lines 167-175 Link Here
167
      if (val > t->tm_mon) {
169
      if (val > t->tm_mon) {
168
        if (!adjyear(t, '-', 1))
170
        if (!adjyear(t, '-', 1))
169
          return 0;
171
          return 0;
170
        val -= 12;
171
      }
172
      }
172
      t->tm_mon -= val;
173
      if (vary_logical) {
174
        for (; val > 0; val--) {
175
          t->tm_mday -= ((mdays[t->tm_mon] == 0) ? 28 + is_leap(t->tm_year + 1900) : mdays[t->tm_mon]) - ((mdays[(t->tm_mon == 0) ? 13 : t->tm_mon - 1] == 0) ? 28 + is_leap(t->tm_year + 1900) : mdays[t->tm_mon + (t->tm_mon == 0) ? 11 : -1]);
176
          t->tm_mon -= 1;
177
        }
178
      } else 
179
        t->tm_mon -= val;
180
      if (t->tm_mon < 0)
181
        t->tm_mon += 12;
173
      break;
182
      break;
174
183
175
    default:
184
    default:
Lines 192-198 Link Here
192
        if (val > mdays - t->tm_mday) {
200
        if (val > mdays - t->tm_mday) {
193
          val -= mdays - t->tm_mday + 1;
201
          val -= mdays - t->tm_mday + 1;
194
          t->tm_mday = 1;
202
          t->tm_mday = 1;
195
          if (!adjmon(t, '+', 1, 0))
203
          if (!adjmon(t, '+', 1, 0, 0))
196
            return 0;
204
            return 0;
197
        } else {
205
        } else {
198
          t->tm_mday += val;
206
          t->tm_mday += val;
Lines 205-211 Link Here
205
        if (val >= t->tm_mday) {
213
        if (val >= t->tm_mday) {
206
          val -= t->tm_mday;
214
          val -= t->tm_mday;
207
          t->tm_mday = 1;
215
          t->tm_mday = 1;
208
          if (!adjmon(t, '-', 1, 0))
216
          if (!adjmon(t, '-', 1, 0, 0))
209
            return 0;
217
            return 0;
210
          t->tm_mday = daysinmonth(t);
218
          t->tm_mday = daysinmonth(t);
211
        } else {
219
        } else {
Lines 379-388 Link Here
379
  char *arg;
387
  char *arg;
380
  int len;
388
  int len;
381
  int val;
389
  int val;
390
  char vary_logical;
382
391
383
  for (; v; v = v->next) {
392
  for (; v; v = v->next) {
384
    type = *v->arg;
393
    type = *v->arg;
385
    arg = v->arg;
394
    arg = v->arg;
395
    vary_logical = v->vary_logical;
386
    if (type == '+' || type == '-')
396
    if (type == '+' || type == '-')
387
      arg++;
397
      arg++;
388
    else
398
    else
Lines 399-405 Link Here
399
      } else {
409
      } else {
400
        val = trans(trans_mon, arg);
410
        val = trans(trans_mon, arg);
401
        if (val != -1) {
411
        if (val != -1) {
402
          if (!adjmon(t, type, val, 1))
412
          if (!adjmon(t, type, val, 1, vary_logical))
403
            return v;
413
            return v;
404
        } else
414
        } else
405
          return v;
415
          return v;
Lines 430-437 Link Here
430
            return v;
440
            return v;
431
          break;
441
          break;
432
        case 'm':
442
        case 'm':
433
          if (!adjmon(t, type, val, 0))
443
          if (!adjmon(t, type, val, 0, vary_logical))
434
            return v;
444
            return v;
435
          break;
445
          break;
436
        case 'y':
446
        case 'y':
437
          if (!adjyear(t, type, val))
447
          if (!adjyear(t, type, val))
(-)date/vary.h (-1 / +2 lines)
Lines 29-36 Link Here
29
struct vary {
29
struct vary {
30
  char *arg;
30
  char *arg;
31
  struct vary *next;
31
  struct vary *next;
32
  char vary_logical;
32
};
33
};
33
34
34
extern struct vary *vary_append(struct vary *v, char *arg);
35
extern struct vary *vary_append(struct vary *v, char *arg, char vary_logical);
35
extern const struct vary *vary_apply(const struct vary *v, struct tm *t);
36
extern const struct vary *vary_apply(const struct vary *v, struct tm *t);
36
extern void vary_destroy(struct vary *v);
37
extern void vary_destroy(struct vary *v);

Return to bug 16005