calendar.c 6.95 KB
Newer Older
1
#include <stdio.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
2

3
4
#include "cdi.h"  		/* CALENDAR_ */
#include "timebase.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
5
6
7
8
9
10
11


static int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
static int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


12
13
14
int calendar_dpy(int calendar)
{
  int dpy = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15

16
17
18
  if      ( calendar == CALENDAR_360DAYS ) dpy = 360;
  else if ( calendar == CALENDAR_365DAYS ) dpy = 365;
  else if ( calendar == CALENDAR_366DAYS ) dpy = 366;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19

20
  return (dpy);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22
23
}


24
int days_per_month(int calendar, int year, int month)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
25
{
26
27
28
  int dayspermonth = 0;
  int *dpm = NULL;
  int dpy;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29

30
  dpy = calendar_dpy(calendar);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
31

32
33
34
  if      ( dpy == 360 ) dpm = month_360;
  else if ( dpy == 365 ) dpm = month_365;
  else                   dpm = month_366;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
35

36
37
  if ( month >= 1 && month <= 12 )
    dayspermonth = dpm[month-1];
38
  /*
39
40
  else
    fprintf(stderr, "days_per_month: month %d out of range\n", month);
41
  */
42
  if ( dpy == 0 && month == 2 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
43
    {
44
45
46
47
      if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
	dayspermonth = 29;
      else
	dayspermonth = 28;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
48
49
    }

50
  return (dayspermonth);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
52
53
}


54
int days_per_year(int calendar, int year)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
{
56
57
  int daysperyear;
  int dpy;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58

59
  dpy = calendar_dpy(calendar);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60

61
  if ( dpy == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
    {
63
64
65
66
67
68
69
70
71
      if ( calendar == CALENDAR_STANDARD )
	{
	  if ( year == 1582 )
	    dpy = 355;
	  else if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
	    dpy = 366;
	  else
	    dpy = 365;
	}
72
      else
73
74
75
76
77
78
	{
	  if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
	    dpy = 366;
	  else
	    dpy = 365;
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
    }

81
82
83
  daysperyear = dpy;
  
  return (daysperyear);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
85
86
}


87
static void decode_day(int dpy, int days, int *year, int *month, int *day)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
{
89
90
  int i = 0;
  int *dpm = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91

92
93
  *year = (days-1) / dpy;
  days -= (*year*dpy);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94

95
96
97
  if      ( dpy == 360 ) dpm = month_360;
  else if ( dpy == 365 ) dpm = month_365;
  else if ( dpy == 366 ) dpm = month_366;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98

99
100
101
102
103
104
  if ( dpm )
    for ( i = 0; i < 12; i++ )
      {
	if ( days > dpm[i] ) days -= dpm[i];
	else break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105

106
107
  *month = i + 1;
  *day   = days;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
109
110
}


111
static int encode_day(int dpy, int year, int month, int day)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
113
114
115
116
117
118
119
120
121
122
123
124
{
  int i;
  int *dpm = NULL;
  double rval;

  rval = dpy * year + day;

  if      ( dpy == 360 ) dpm = month_360;
  else if ( dpy == 365 ) dpm = month_365;
  else if ( dpy == 366 ) dpm = month_366;
  
  if ( dpm ) for ( i = 0; i < month-1; i++ ) rval += dpm[i];

125
  return (rval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
126
127
128
}


129
int date_to_calday(int calendar, int date)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
{
131
132
133
  int calday;
  int dpy;
  int year, month, day;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
134

135
  dpy = calendar_dpy(calendar);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
136

Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
  cdiDecodeDate(date, &year, &month, &day);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138

139
140
141
  if ( dpy == 360 || dpy == 365 || dpy == 366 )
    calday = encode_day(dpy, year, month, day);
  else
142
    calday = encode_julday(calendar, year, month, day);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143

144
  return (calday);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
146
147
}


148
int calday_to_date(int calendar, int calday)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
{
150
151
152
153
154
155
156
157
158
  int date;
  int dpy;
  int year, month, day;

  dpy = calendar_dpy(calendar);

  if ( dpy == 360 || dpy == 365 || dpy == 366 )
    decode_day(dpy, calday, &year, &month, &day);
  else
159
    decode_julday(calendar, calday, &year, &month, &day);
160

Uwe Schulzweida's avatar
Uwe Schulzweida committed
161
  date = cdiEncodeDate(year, month, day);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162

163
  return (date);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
166
}


167
168
void encode_caldaysec(int calendar, int year, int month, int day, int hour, int minute, int second,
		      int *julday, int *secofday)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
{
170
171
172
173
  int dpy;

  dpy = calendar_dpy(calendar);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
174
  if ( dpy == 360 || dpy == 365 || dpy == 366 )
175
    *julday = encode_day(dpy, year, month, day);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
  else
177
    *julday = encode_julday(calendar, year, month, day);
178

179
  *secofday = hour*3600 + minute*60 + second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
182
}


183
184
void decode_caldaysec(int calendar, int julday, int secofday, 
		      int *year, int *month, int *day, int *hour, int *minute, int *second)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
{
186
187
188
189
  int dpy;

  dpy = calendar_dpy(calendar);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
  if ( dpy == 360 || dpy == 365 || dpy == 366 )
191
    decode_day(dpy, julday, year, month, day);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
  else
193
    decode_julday(calendar, julday, year, month, day);
194
195
196

  *hour   = secofday/3600;
  *minute = secofday/60 - *hour*60;
197
  *second = secofday - *hour*3600 - *minute*60;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
199
}

200
201

#ifdef TEST
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
203
int main(void)
{
204
205
206
207
208
209
  int calendar = CALENDAR_STANDARD;
  int nmin;
  int vdate0, vtime0;
  int vdate, vtime;
  int ijulinc;
  int i, j = 0;
210
  int year, mon, day, hour, minute, second;
211
212
213
214
215
216
  int calday, secofday;

  /* 1 - Check valid range of years */

  nmin = 11000;
  vdate0 = -80001201;
217
  vtime0 = 120500;
218
219
220
221
222

  printf("start time: %8d %4d\n", vdate0, vtime0);

  for ( i = 0; i < nmin; i++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
224
      cdiDecodeDate(vdate0, &year, &mon, &day);
      cdiDecodeTime(vtime0, &hour, &minute, &second);
225
226
227
228
229
230
231
232
233
234
235
236

      calday  = date_to_calday(calendar, vdate0);
      secofday = time_to_sec(vtime0);

      vdate = calday_to_date(calendar, calday);
      vtime = sec_to_time(secofday);

      if ( vdate0 != vdate || vtime0 != vtime )
	printf("%4d %8d %4d %8d %4d %9d %9d\n",
	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);

      year++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237
238
      vdate0 = cdiEncodeDate(year, mon, day);
      vtime0 = cdiEncodeTime(hour, minute, second);
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    }

  printf("stop time: %8d %4d\n", vdate0, vtime0);

  /* 2 - Check time increment of one minute */

  nmin = 120000;
  ijulinc = 60;
  vdate0 = 20001201;
  vtime0 = 0;

  printf("start time: %8d %4d\n", vdate0, vtime0);

  calday = date_to_calday(calendar, vdate0);
  secofday = time_to_sec(vtime0);
  for ( i = 0; i < nmin; i++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
      cdiDecodeDate(vdate0, &year, &mon, &day);
      cdiDecodeTime(vtime0, &hour, &minute, &second);
258

259
      if ( ++minute >= 60 )
260
	{
261
	  minute = 0;
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
	  if ( ++hour >= 24 )
	    {
	      hour = 0;
	      if ( ++day >= 32 )
		{
		  day = 1;
		  if ( ++mon >= 13 )
		    {
		      mon = 1;
		      year++;
		    }
		}
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
278
      vdate0 = cdiEncodeDate(year, mon, day);
      vtime0 = cdiEncodeTime(hour, minute, second);
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

      julday_add_seconds(ijulinc, &calday, &secofday);

      vdate = calday_to_date(calendar, calday);
      vtime = sec_to_time(secofday);
      if ( vdate0 != vdate || vtime0 != vtime )
	printf("%4d %8d %4d %8d %4d %9d %9d\n",
	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);
    }

  printf("stop time: %8d %4d\n", vdate0, vtime0);

  return (0);
}
#endif


#ifdef TEST2
int main(void)
{
  int calendar = CALENDAR_STANDARD;
  int i;
  int calday, secofday;
302
  int year, month, day, hour, minute, second;
303
304
305
306
  int value = 30;
  int factor = 86400;
  
  calendar = CALENDAR_360DAYS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307

308
  year=1979; month=1; day=15; hour=12; minute=30; second = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
309

310
  printf("calendar = %d\n", calendar);
311
  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
312

313
  encode_caldaysec(calendar, year, month, day, hour, minute, second, &calday, &secofday);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314

315
316
  decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, calday, secofday);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
318
319

  for ( i = 0; i < 420; i++ )
    {
320

321
322
      decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
323
      julday_add_seconds(value*factor, &calday, &secofday);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
325
326
327
    }

  return (0);
}
328
#endif