~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to lib/ts/ink_time.cc

  • Committer: Package Import Robot
  • Author(s): Aron Xu
  • Date: 2013-05-09 01:00:04 UTC
  • mto: (1.1.11) (5.3.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: package-import@ubuntu.com-20130509010004-9fqq9n0adseg3f8w
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
93
93
  return ((double) s_val.tv_sec + 0.000001 * s_val.tv_usec);
94
94
}                               /* End ink_time_wall_seconds */
95
95
 
96
 
/*===========================================================================*
97
 
 
98
 
                          High-Level Date Processing
99
 
 
100
 
 *===========================================================================*/
101
 
 
102
 
/*---------------------------------------------------------------------------*
103
 
 
104
 
  int ink_time_gmt_string_to_tm(char *string, struct tm *broken_down_time)
105
 
 
106
 
  This routine takes an ASCII string representation of a date <string> in one
107
 
  of several formats, converts the string to a calendar time, and stores the
108
 
  calendar time through the pointer <broken_down_time>.
109
 
 
110
 
  This routine currently attempts to support RFC 1123 format, RFC 850
111
 
  format, and asctime() format.  The times are expected to be in GMT time.
112
 
 
113
 
  If the string is successfully parsed and converted to a date, the number
114
 
  of characters processed from the string is returned (useful for scanning
115
 
  over a string), otherwise 0 is returned.
116
 
 
117
 
 *---------------------------------------------------------------------------*/
118
 
int
119
 
ink_time_gmt_string_to_tm(char *string, struct tm *bdt)
120
 
{
121
 
  char *result;
122
 
 
123
 
  /* This declaration isn't being found in time.h for some reason */
124
 
 
125
 
  result = NULL;
126
 
 
127
 
  /* Try RFC 1123 Format */
128
 
 
129
 
  if (!result)
130
 
    result = strptime(string, (char *) "%a, %d %b %Y %T GMT", bdt);
131
 
  if (!result)
132
 
    result = strptime(string, (char *) "%a, %d %b %Y %T UTC", bdt);
133
 
 
134
 
  /* Try RFC 850 Format */
135
 
 
136
 
  if (!result)
137
 
    result = strptime(string, (char *) "%A, %d-%b-%y %T GMT", bdt);
138
 
  if (!result)
139
 
    result = strptime(string, (char *) "%A, %d-%b-%y %T UTC", bdt);
140
 
 
141
 
  /* Try asctime() Format */
142
 
 
143
 
  if (!result)
144
 
    result = strptime(string, (char *) "%a %b %d %T %Y", bdt);
145
 
 
146
 
  bdt->tm_isdst = -1;
147
 
 
148
 
  /* If No Success, You Lose, Pal */
149
 
 
150
 
  if (!result)
151
 
    return (0);
152
 
 
153
 
  return (result - string);
154
 
}                               /* End ink_time_gmt_string_to_tm */
155
 
 
156
 
 
157
 
/*---------------------------------------------------------------------------*
158
 
 
159
 
  int ink_time_gmt_tm_to_rfc1123_string(struct tm *t, char *string, int maxsize)
160
 
 
161
 
  This routine takes a calendar time <tm> in universal time, and converts
162
 
  the time to an RFC 1123 formatted string as in "Sun, 06 Nov 1994 08:49:37 GMT",
163
 
  which is placed in the string <string> up to <maxsize> bytes.  1 is
164
 
  returned on success, else 0.
165
 
 
166
 
 *---------------------------------------------------------------------------*/
167
 
int
168
 
ink_time_gmt_tm_to_rfc1123_string(struct tm *t, char *string, int maxsize)
169
 
{
170
 
  size_t size;
171
 
 
172
 
  size = strftime(string, maxsize, "%a, %d %b %Y %T GMT", t);
173
 
  if (size == 0) {
174
 
    if (maxsize > 0)
175
 
      string[0] = '\0';
176
 
    return (0);
177
 
  }
178
 
  return (1);
179
 
}                               /* End ink_time_gmt_tm_to_rfc1123_string */
180
 
 
181
 
 
182
 
/*---------------------------------------------------------------------------*
183
 
 
184
 
  InkTimeDayID ink_time_tm_to_dayid(struct tm *t)
185
 
 
186
 
  This routine takes a broken-down time <t>, and converts it to an
187
 
  InkTimeDayID <dayid>, representing an integer number of days since a base.
188
 
 
189
 
 *---------------------------------------------------------------------------*/
190
 
InkTimeDayID
191
 
ink_time_tm_to_dayid(struct tm * t)
192
 
{
193
 
  int m, dom, y;
194
 
  InkTimeDayID dayid;
195
 
 
196
 
  ink_time_tm_to_mdy(t, &m, &dom, &y);
197
 
  dayid = ink_time_mdy_to_dayid(m, dom, y);
198
 
  return (dayid);
199
 
}                               /* End ink_time_tm_to_dayid */
200
 
 
201
 
 
202
 
/*---------------------------------------------------------------------------*
203
 
 
204
 
  void ink_time_dump_dayid(FILE *fp, InkTimeDayID dayid)
205
 
 
206
 
  This routine prints an ASCII representation of <dayid> onto the file
207
 
  pointer <fp>.
208
 
 
209
 
 *---------------------------------------------------------------------------*/
210
 
void
211
 
ink_time_dump_dayid(FILE * fp, InkTimeDayID dayid)
212
 
{
213
 
  int m, d, y;
214
 
 
215
 
  ink_time_dayid_to_mdy(dayid, &m, &d, &y);
216
 
  fprintf(fp, "dayid %d (%d/%d/%d)\n", dayid, m, d, y);
217
 
}                               /* End ink_time_dump_dayid */
218
 
 
219
 
 
220
 
/*---------------------------------------------------------------------------*
221
 
 
222
 
  void ink_time_dayid_to_tm(InkTimeDayID dayid, struct tm *t)
223
 
 
224
 
  This routine takes an InkTimeDayID <dayid>, representing an integer number
225
 
  of days since a base, and computes a broken-down time <t>.
226
 
 
227
 
 *---------------------------------------------------------------------------*/
228
 
void
229
 
ink_time_dayid_to_tm(InkTimeDayID dayid, struct tm *t)
230
 
{
231
 
  int m, dom, y;
232
 
 
233
 
  ink_time_dayid_to_mdy(dayid, &m, &dom, &y);
234
 
  ink_time_mdy_to_tm(m, dom, y, t);
235
 
}                               /* End ink_time_dayid_to_tm */
236
 
 
237
 
 
238
 
/*---------------------------------------------------------------------------*
239
 
 
240
 
  InkTimeDayRange ink_time_dayid_to_dayrange(InkTimeDayID dayid, unsigned int width)
241
 
 
242
 
  This routine takes a <dayid> representing a particular day, and returns
243
 
  an InkTimeDayRange object of width <width> that spans the day in question.
244
 
 
245
 
 *---------------------------------------------------------------------------*/
246
 
InkTimeDayRange
247
 
ink_time_dayid_to_dayrange(InkTimeDayID dayid, unsigned int width)
248
 
{
249
 
  InkTimeDayRange range;
250
 
 
251
 
  range.base = dayid - (dayid % width);
252
 
  range.width = width;
253
 
  return (range);
254
 
}                               /* End ink_time_dayid_to_dayrange */
255
 
 
256
 
 
257
 
/*---------------------------------------------------------------------------*
258
 
 
259
 
  InkTimeDayRange ink_time_chomp_off_mouthful_of_dayrange
260
 
        (InkTimeDayRange *dayrange_ptr, unsigned int biggest_width)
261
 
 
262
 
  This routine takes a dayrange pointer <dayrange_ptr>, and bites off the
263
 
  biggest possible chunk of the dayrange pointed to by <dayrange_ptr>
264
 
  which is less than or equal to <biggest_width> and whose chunk is
265
 
  "chomp aligned", meaning that the start of the dayrange chunk starts on
266
 
  a multiple of the width.
267
 
 
268
 
  The value <biggest_width> must be a positive power of two.
269
 
 
270
 
  On exit, the chunk chomped off will be returned, and the original
271
 
  dayrange pointed to by <dayrange_ptr> will be modified to consist of
272
 
  the data after the chunk that was chopped off.
273
 
 
274
 
  If the dayrange pointed to by <dayrange_ptr> has no size, a dayrange
275
 
  of size 0 is returned, and the original data is unmodified.
276
 
 
277
 
  The purpose of this routine is to decompose a range of consecutive days
278
 
  into a collection of variable-sized, disjoint day ranges which cover the
279
 
  original space of days.
280
 
 
281
 
 *---------------------------------------------------------------------------*/
282
 
InkTimeDayRange
283
 
ink_time_chomp_off_mouthful_of_dayrange(InkTimeDayRange * dayrange_ptr, unsigned int biggest_width)
284
 
{
285
 
  unsigned int width;
286
 
  InkTimeDayRange chomped_chunk;
287
 
 
288
 
  chomped_chunk.base = dayrange_ptr->base;
289
 
 
290
 
  for (width = biggest_width; width >= 1; width = width / 2) {
291
 
    if ((width <= dayrange_ptr->width) && ((dayrange_ptr->base % width) == 0)) {
292
 
      chomped_chunk.width = width;
293
 
 
294
 
      dayrange_ptr->base += width;
295
 
      dayrange_ptr->width -= width;
296
 
 
297
 
      return (chomped_chunk);
298
 
    }
299
 
  }
300
 
 
301
 
  chomped_chunk.width = 0;
302
 
 
303
 
  return (chomped_chunk);
304
 
}                               /* End ink_time_chomp_off_mouthful_of_dayrange */
305
 
 
306
 
 
307
 
/*---------------------------------------------------------------------------*
308
 
 
309
 
  char *ink_time_dayrange_to_string(InkTimeDayRange *dayrange_ptr, char *buf)
310
 
 
311
 
  This routine take a day range pointer <dayrange_ptr>, and places a string
312
 
  representation of the day range in the buffer <buf>.  The buffer must be
313
 
  big enough to hold the representation of the dayrange.
314
 
 
315
 
  Of course, you shouldn't have any idea what the representation is, so I
316
 
  guess you're hosed.  Something like 64 characters is probably reasonable.
317
 
 
318
 
  The pointer <buf> is returned.
319
 
 
320
 
 *---------------------------------------------------------------------------*/
321
 
char *
322
 
ink_time_dayrange_to_string(InkTimeDayRange * dayrange_ptr, char *buf, const size_t bufSize)
323
 
{
324
 
  if (bufSize > 0) {
325
 
    buf[0] = '\0';
326
 
  }
327
 
 
328
 
  snprintf(buf, bufSize, "range_start_%d_width_%u", dayrange_ptr->base, dayrange_ptr->width);
329
 
  return (buf);
330
 
}                               /* End ink_time_dayrange_to_string */
331
 
 
332
 
 
333
 
/*===========================================================================*
334
 
 
335
 
                          Date Conversion Routines
336
 
 
337
 
  Note that both the day of month and the month number start at 1 not zero,
338
 
  so January 1 is <m=1,d=1> not <m=0,d=0>.
339
 
 
340
 
 *===========================================================================*/
341
 
 
342
 
static int _base_day = 4;       /* 1/1/1970 is Thursday */
343
 
static int _base_year = 1970;
344
 
 
345
 
static int _base_daysinmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
346
 
 
347
 
static const char *_day_names[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
348
 
static const char *_month_names[12] = {
349
 
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
350
 
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
351
 
};
352
 
 
353
 
 
354
 
/*---------------------------------------------------------------------------*
355
 
 
356
 
  void ink_time_current_mdy(int *m, int *dom, int *y)
357
 
 
358
 
  Gets the current local date in GMT, and returns the month, day of month,
359
 
  and year in GMT.
360
 
 
361
 
 *---------------------------------------------------------------------------*/
362
 
void
363
 
ink_time_current_mdy(int *m, int *dom, int *y)
364
 
{
365
 
  time_t c;
366
 
  struct tm t;
367
 
  c = time(0);
368
 
  ink_gmtime_r(&c, &t);
369
 
  ink_time_tm_to_mdy(&t, m, dom, y);
370
 
}                               /* End ink_time_current_mdy */
371
 
 
372
 
 
373
 
/*---------------------------------------------------------------------------*
374
 
 
375
 
  void ink_time_tm_to_mdy(struct tm *t, int *m, int *dom, int *y)
376
 
 
377
 
  Takes a broken down time pointer <t>, and returns the month, day of month,
378
 
  and year.
379
 
 
380
 
 *---------------------------------------------------------------------------*/
381
 
void
382
 
ink_time_tm_to_mdy(struct tm *t, int *m, int *dom, int *y)
383
 
{
384
 
  *m = t->tm_mon + 1;
385
 
  *dom = t->tm_mday;
386
 
  *y = t->tm_year + 1900;
387
 
}                               /* End ink_time_tm_to_mdy */
388
 
 
389
 
 
390
 
/*---------------------------------------------------------------------------*
391
 
 
392
 
  void ink_time_mdy_to_tm(int m, int dom, int y, struct tm *t)
393
 
 
394
 
  Takes a month <m>, day of month <dom>, and year <y>, and places a
395
 
  broken-down time in the structure pointed to by <t>.
396
 
 
397
 
 *---------------------------------------------------------------------------*/
398
 
void
399
 
ink_time_mdy_to_tm(int m, int dom, int y, struct tm *t)
400
 
{
401
 
  bzero((char *) t, sizeof(*t));
402
 
  t->tm_mon = m - 1;
403
 
  t->tm_mday = dom;
404
 
  t->tm_year = y - 1900;
405
 
  t->tm_wday = ink_time_mdy_to_dow(m, dom, y);
406
 
  t->tm_yday = ink_time_mdy_to_doy(m, dom, y);
407
 
}                               /* End ink_time_mdy_to_tm */
408
 
 
409
 
 
410
 
/*---------------------------------------------------------------------------*
411
 
 
412
 
  InkTimeDayID ink_time_mdy_to_dayid(int m, int dom, int y)
413
 
 
414
 
  Return a single integer representing encoding of the day <m> <dom>, <y>.
415
 
  The encoding is performed with respect to the base day.
416
 
 
417
 
 *---------------------------------------------------------------------------*/
418
 
InkTimeDayID
419
 
ink_time_mdy_to_dayid(int m, int dom, int y)
420
 
{
421
 
  int year, month;
422
 
  InkTimeDayID dayid;
423
 
 
424
 
  dayid = 0;
425
 
  for (year = _base_year; year < y; year++)
426
 
    dayid = dayid + ink_time_days_in_year(year);
427
 
  for (month = 1; month < m; month++)
428
 
    dayid = dayid + ink_time_days_in_month(month, year);
429
 
  dayid = dayid + dom - 1;
430
 
  return (dayid);
431
 
}                               /* End ink_time_mdy_to_dayid */
432
 
 
433
 
 
434
 
/*---------------------------------------------------------------------------*
435
 
 
436
 
  InkTimeDayID ink_time_current_dayid()
437
 
 
438
 
  Return a single integer representing encoding of the today's date.
439
 
  The encoding is performed with respect to the base day.
440
 
 
441
 
 *---------------------------------------------------------------------------*/
442
 
InkTimeDayID
443
 
ink_time_current_dayid()
444
 
{
445
 
  InkTimeDayID today;
446
 
  int today_m, today_d, today_y;
447
 
 
448
 
  ink_time_current_mdy(&today_m, &today_d, &today_y);
449
 
  today = ink_time_mdy_to_dayid(today_m, today_d, today_y);
450
 
 
451
 
  return (today);
452
 
}                               /* End ink_time_current_dayid */
453
 
 
454
 
 
455
 
/*---------------------------------------------------------------------------*
456
 
 
457
 
  void ink_time_dayid_to_mdy(InkTimeDayID dayid, int *mp, int *dp, int *yp)
458
 
 
459
 
  Takes a single integer representation of the date, and convert to the
460
 
  month <m>, day of month <dom>, and year <y>.
461
 
 
462
 
 *---------------------------------------------------------------------------*/
463
 
void
464
 
ink_time_dayid_to_mdy(InkTimeDayID dayid, int *mp, int *dp, int *yp)
465
 
{
466
 
  dayid = dayid + 1;
467
 
  for (*yp = _base_year; ink_time_days_in_year(*yp) < dayid; (*yp)++)
468
 
    dayid = dayid - ink_time_days_in_year(*yp);
469
 
  for (*mp = 1; ink_time_days_in_month(*mp, *yp) < dayid; (*mp)++)
470
 
    dayid = dayid - ink_time_days_in_month(*mp, *yp);
471
 
  *dp = dayid;
472
 
}                               /* End ink_time_dayid_to_mdy */
473
 
 
474
 
 
475
 
/*---------------------------------------------------------------------------*
476
 
 
477
 
  int ink_time_mdy_to_doy(int m, int dom, int y)
478
 
 
479
 
  Takes a date <m> <dom> <y>, and returns the number of days into year <y>.
480
 
 
481
 
 *---------------------------------------------------------------------------*/
482
 
int
483
 
ink_time_mdy_to_doy(int m, int dom, int y)
484
 
{
485
 
  InkTimeDayID first, current;
486
 
 
487
 
  first = ink_time_mdy_to_dayid(1, 1, y);
488
 
  current = ink_time_mdy_to_dayid(m, dom, y);
489
 
  return (current - first);
490
 
}                               /* End ink_time_mdy_to_doy */
491
 
 
492
 
 
493
 
/*---------------------------------------------------------------------------*
494
 
 
495
 
  void ink_time_doy_to_mdy(int doy, int year, int *mon, int *dom, int *dow)
496
 
 
497
 
  This routine take a <year>, and a zero-based <doy> within the year,
498
 
  and determines the corresponding month, day of month, and day of week.
499
 
 
500
 
 *---------------------------------------------------------------------------*/
501
 
void
502
 
ink_time_doy_to_mdy(int doy, int year, int *mon, int *dom, int *dow)
503
 
{
504
 
  int month, daysinmonth, days_so_far, next_days_so_far;
505
 
 
506
 
  days_so_far = 1;
507
 
  for (month = 1; month <= 12; month++) {
508
 
    daysinmonth = ink_time_days_in_month(month, year);
509
 
    next_days_so_far = days_so_far + daysinmonth;
510
 
    if (doy >= days_so_far && doy < next_days_so_far) {
511
 
      *mon = month;
512
 
      *dom = doy - days_so_far + 1;
513
 
      *dow = ink_time_mdy_to_dow(month, *dom, year);
514
 
      return;
515
 
    }
516
 
    days_so_far = next_days_so_far;
517
 
  }
518
 
}                               /* End ink_time_doy_to_mdy */
519
 
 
520
 
 
521
 
/*---------------------------------------------------------------------------*
522
 
 
523
 
  int ink_time_mdy_to_dow(int month, int dom, int year)
524
 
 
525
 
  What day of the week does <month> <dom>, <year> fall on?
526
 
 
527
 
 *---------------------------------------------------------------------------*/
528
 
int
529
 
ink_time_mdy_to_dow(int month, int dom, int year)
530
 
{
531
 
  int i, base;
532
 
 
533
 
  base = ink_time_first_day_of_year(year);
534
 
  for (i = 0; i < month - 1; i++) {
535
 
    base = (base + ink_time_days_in_month(i + 1, year)) % 7;
536
 
  }
537
 
  return ((base + dom - 1) % 7);
538
 
}                               /* End ink_time_mdy_to_dow */
539
 
 
540
 
 
541
 
/*---------------------------------------------------------------------------*
542
 
 
543
 
  int ink_time_days_in_month(int month, int year)
544
 
 
545
 
  This routine returns the number of days in a particular <month> and <year>.
546
 
 
547
 
 *---------------------------------------------------------------------------*/
548
 
int
549
 
ink_time_days_in_month(int month, int year)
550
 
{
551
 
  return (_base_daysinmonth[month - 1] + (month == 2 ? ink_time_leap_year_correction(year) : 0));
552
 
}                               /* End ink_time_days_in_month */
553
 
 
554
 
 
555
 
/*---------------------------------------------------------------------------*
556
 
 
557
 
  int ink_time_days_in_year(int year)
558
 
 
559
 
  This routine returns the number of days in the year <year>, compensating
560
 
  for leap years.
561
 
 
562
 
 *---------------------------------------------------------------------------*/
563
 
int
564
 
ink_time_days_in_year(int year)
565
 
{
566
 
  return (365 + ink_time_leap_year_correction(year));
567
 
}                               /* End ink_time_days_in_year */
568
 
 
569
 
 
570
 
/*---------------------------------------------------------------------------*
571
 
 
572
 
  int ink_time_first_day_of_year(int year)
573
 
 
574
 
  What day is January 1 on in this year?
575
 
 
576
 
 *---------------------------------------------------------------------------*/
577
 
int
578
 
ink_time_first_day_of_year(int year)
579
 
{
580
 
  int i, base;
581
 
 
582
 
  base = _base_day;
583
 
  if (year > _base_year) {
584
 
    for (i = _base_year; i < year; i++)
585
 
      base = (base + ink_time_days_in_year(i)) % 7;
586
 
  } else if (year < _base_year) {
587
 
    for (i = _base_year - 1; i >= year; i--)
588
 
      base = ((base - ink_time_days_in_year(i)) % 7 + 7) % 7;
589
 
  }
590
 
  return (base);
591
 
}                               /* End ink_time_first_day_of_year */
592
 
 
593
 
 
594
 
/*---------------------------------------------------------------------------*
595
 
 
596
 
  void ink_time_day_to_string(int day, char *buffer)
597
 
 
598
 
  This routine takes a day number and places a 3 character, NUL terminated
599
 
  string representing this day in the buffer pointed to by <buffer>.
600
 
 
601
 
 *---------------------------------------------------------------------------*/
602
 
void
603
 
ink_time_day_to_string(int day, char *buffer, const size_t bufferSize)
604
 
{
605
 
  ink_strlcpy(buffer, _day_names[day], bufferSize);
606
 
}                               /* End ink_time_day_to_string */
607
 
 
608
 
 
609
 
/*---------------------------------------------------------------------------*
610
 
 
611
 
  void ink_time_month_to_string(int month, char *buffer)
612
 
 
613
 
  This routine takes a month number and places a 3 character, NUL terminated
614
 
  string representing this day in the buffer pointed to by <buffer>.
615
 
 
616
 
 *---------------------------------------------------------------------------*/
617
 
void
618
 
ink_time_month_to_string(int month, char *buffer, const size_t bufferSize)
619
 
{
620
 
  ink_strlcpy(buffer, _month_names[month - 1], bufferSize);
621
 
}                               /* End ink_time_month_to_string */
622
 
 
623
 
 
624
 
/*---------------------------------------------------------------------------*
625
 
 
626
 
  int ink_time_string_to_month(char *str)
627
 
 
628
 
  This routine takes a name of a month <str>, and returns the corresponding
629
 
  month number, else -1.
630
 
 
631
 
 *---------------------------------------------------------------------------*/
632
 
int
633
 
ink_time_string_to_month(char *str)
634
 
{
635
 
  int i;
636
 
 
637
 
  for (i = 0; i < 12; i++) {
638
 
    if (strcasecmp(str, _month_names[i]) == 0)
639
 
      return (i + 1);
640
 
  }
641
 
  return (-1);
642
 
}                               /* End ink_time_string_to_month */
643
 
 
644
 
 
645
 
/*---------------------------------------------------------------------------*
646
 
 
647
 
  int ink_time_leap_year_correction(int year)
648
 
 
649
 
  Return 1 if <year> is a leap year, 0 if not, and -1 if negative leap year.
650
 
 
651
 
 *---------------------------------------------------------------------------*/
652
 
int
653
 
ink_time_leap_year_correction(int year)
654
 
{
655
 
  return (ink_time_is_4th_year(year) - ink_time_is_100th_year(year) + ink_time_is_400th_year(year));
656
 
}                               /* End ink_time_leap_year_correction */
657
 
 
658
 
/* asah #ifndef sun asah */
 
96
 
659
97
struct dtconv
660
98
{
661
99
  char *abbrev_month_names[12];
669
107
  char *pm_string;
670
108
  char *ldate_format;
671
109
};
672
 
/* asah #endif asah */
673
110
 
674
111
 
675
112
 
703
140
 
704
141
#define DAYS_OFFSET  25508
705
142
 
706
 
int
707
 
ink_gmtime_r(const ink_time_t * clock, struct tm *res)
708
 
{
709
 
  static const char months[] = {
710
 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
711
 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
712
 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
713
 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
714
 
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
715
 
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
716
 
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
717
 
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
718
 
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
719
 
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
720
 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
721
 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
722
 
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
723
 
    8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
724
 
    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
725
 
    9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
726
 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
727
 
    10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
728
 
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
729
 
    11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
730
 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
731
 
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
732
 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
733
 
  };
734
 
  static const int days[12] = {
735
 
    305, 336, -1, 30, 60, 91, 121, 152, 183, 213, 244, 274
736
 
  };
737
 
 
738
 
  size_t t = *clock;
739
 
 
740
 
  size_t d, dp;
741
 
 
742
 
  size_t sec = t % 60;
743
 
  t /= 60;
744
 
  size_t min = t % 60;
745
 
  t /= 60;
746
 
  size_t hour = t % 24;
747
 
  t /= 24;
748
 
 
749
 
  /* Jan 1, 1970 was a Thursday */
750
 
  size_t wday = (4 + t) % 7;
751
 
 
752
 
  /* guess the year and refine the guess */
753
 
  size_t yday = t;
754
 
  size_t year = yday / 365 + 69;
755
 
 
756
 
  d = dp = (year * 365) + (year / 4) - (year / 100) + (year / 100 + 3) / 4 - DAYS_OFFSET - 1;
757
 
 
758
 
  while (dp < yday) {
759
 
    d = dp;
760
 
    year += 1;
761
 
    dp = (year * 365) + (year / 4) - (year / 100) + (year / 100 + 3) / 4 - DAYS_OFFSET - 1;
762
 
  }
763
 
 
764
 
  /* convert the days */
765
 
  d = yday - d;
766
 
  if (d> 366)
767
 
    return -1;
768
 
 
769
 
  size_t month = months[d];
770
 
  if (month > 1)
771
 
    year -= 1;
772
 
 
773
 
  size_t mday = d - days[month] - 1;
774
 
  // year += 1900; real year
775
 
 
776
 
  res->tm_sec = (int) sec;
777
 
  res->tm_min = (int) min;
778
 
  res->tm_hour = (int) hour;
779
 
  res->tm_mday = (int) mday;
780
 
  res->tm_mon = (int) month;
781
 
  res->tm_year = (int) year;
782
 
  res->tm_wday = (int) wday;
783
 
  res->tm_yday = (int) yday;
784
 
  res->tm_isdst = 0;
785
 
 
786
 
  return 0;
787
 
}
788
 
 
789
143
ink_time_t
790
144
convert_tm(const struct tm * tp)
791
145
{