strptime 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/appveyor.yml +3 -1
- data/ext/strptime/ruby_time.c +348 -47
- data/ext/strptime/strptime.c +22 -29
- data/ext/strptime/strptime.h +1 -0
- data/lib/strptime/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed9027134b74ad744e3cab45ec184267a2cf88d1
|
4
|
+
data.tar.gz: f09b7df6da7b9e13ab1c8278a1bd6e5af9db11bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49265084818aa5d7c4ffeedfc80b366d69531f30fae2b40ad345a62639ae3cbb08559486f7556bdca984197fb15fbfd66ea0f6d8e5027fefcc1ee9b9aeee75fa
|
7
|
+
data.tar.gz: b1e1e24432703d46a985dbb09a0c2fa5aa94024d7f33f0f708100d37fb2b1fdde4f67f1b2104a65f269591da30dddbdc88b314d3bdd2e5686a3d14e10a8f7296
|
data/.travis.yml
CHANGED
data/appveyor.yml
CHANGED
data/ext/strptime/ruby_time.c
CHANGED
@@ -60,7 +60,7 @@ struct vtm {
|
|
60
60
|
struct time_object {
|
61
61
|
wideval_t timew; /* time_t value * TIME_SCALE. possibly Rational. */
|
62
62
|
struct vtm vtm;
|
63
|
-
int gmt; /* 0:
|
63
|
+
int gmt; /* 0:localtime 1:utc 2:fixoff */
|
64
64
|
int tm_got;
|
65
65
|
};
|
66
66
|
# endif
|
@@ -114,71 +114,56 @@ rb_timespec_now(struct timespec *ts)
|
|
114
114
|
}
|
115
115
|
#endif
|
116
116
|
|
117
|
-
/* localtime_with_gmtoff_zone */
|
118
|
-
#ifdef HAVE_GMTIME_R
|
119
|
-
#define rb_gmtime_r(t, tm) gmtime_r((t), (tm))
|
120
|
-
#define rb_localtime_r(t, tm) localtime_r((t), (tm))
|
121
|
-
#else
|
122
|
-
static inline struct tm *
|
123
|
-
rb_gmtime_r(const time_t *tp, struct tm *result)
|
124
|
-
{
|
125
|
-
struct tm *t = gmtime(tp);
|
126
|
-
if (t) *result = *t;
|
127
|
-
return t;
|
128
|
-
}
|
129
|
-
|
130
|
-
static inline struct tm *
|
131
|
-
rb_localtime_r(const time_t *tp, struct tm *result)
|
132
|
-
{
|
133
|
-
struct tm *t = localtime(tp);
|
134
|
-
if (t) *result = *t;
|
135
|
-
return t;
|
136
|
-
}
|
137
|
-
#endif
|
138
|
-
|
139
117
|
static struct tm *
|
140
|
-
|
118
|
+
rb_localtime_r(const time_t *t, struct tm *result)
|
141
119
|
{
|
142
120
|
#if defined __APPLE__ && defined __LP64__
|
143
121
|
if (*t != (time_t)(int)*t) return NULL;
|
144
122
|
#endif
|
145
|
-
|
123
|
+
#ifdef HAVE_GMTIME_R
|
124
|
+
result = localtime_r(t, result);
|
125
|
+
#else
|
126
|
+
{
|
127
|
+
struct tm *tmp = localtime(t);
|
128
|
+
if (tmp) *result = *tmp;
|
129
|
+
}
|
130
|
+
#endif
|
146
131
|
#if defined(HAVE_MKTIME) && defined(LOCALTIME_OVERFLOW_PROBLEM)
|
147
132
|
if (result) {
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
#
|
157
|
-
|
158
|
-
|
159
|
-
if (*t + gmtoff1 != t2 + gmtoff2) result = NULL;
|
133
|
+
long gmtoff1 = 0;
|
134
|
+
long gmtoff2 = 0;
|
135
|
+
struct tm tmp = *result;
|
136
|
+
time_t t2;
|
137
|
+
t2 = mktime(&tmp);
|
138
|
+
# if defined(HAVE_STRUCT_TM_TM_GMTOFF)
|
139
|
+
gmtoff1 = result->tm_gmtoff;
|
140
|
+
gmtoff2 = tmp.tm_gmtoff;
|
141
|
+
# endif
|
142
|
+
if (*t + gmtoff1 != t2 + gmtoff2)
|
143
|
+
result = NULL;
|
160
144
|
}
|
161
145
|
#endif
|
162
146
|
return result;
|
163
147
|
}
|
164
|
-
#define LOCALTIME(tm, result) (tzset(),
|
148
|
+
#define LOCALTIME(tm, result) (tzset(),rb_localtime_r((tm), &(result)))
|
165
149
|
|
166
|
-
#if !defined(HAVE_STRUCT_TM_TM_GMTOFF)
|
167
150
|
static struct tm *
|
168
|
-
|
151
|
+
rb_gmtime_r(const time_t *t, struct tm *result)
|
169
152
|
{
|
170
|
-
|
153
|
+
#ifdef HAVE_GMTIME_R
|
154
|
+
result = gmtime_r(t, result);
|
155
|
+
#else
|
156
|
+
struct tm *tmp = gmtime(t);
|
157
|
+
if (tmp) *result = *tmp;
|
158
|
+
#endif
|
171
159
|
#if defined(HAVE_TIMEGM) && defined(LOCALTIME_OVERFLOW_PROBLEM)
|
172
|
-
if (result) {
|
173
|
-
|
174
|
-
time_t t2 = timegm(&tmp);
|
175
|
-
if (*t != t2) result = NULL;
|
160
|
+
if (result && *t != timegm(result)) {
|
161
|
+
return NULL;
|
176
162
|
}
|
177
163
|
#endif
|
178
164
|
return result;
|
179
165
|
}
|
180
|
-
#define GMTIME(tm, result)
|
181
|
-
#endif
|
166
|
+
#define GMTIME(tm, result) rb_gmtime_r((tm), &(result))
|
182
167
|
|
183
168
|
struct tm *
|
184
169
|
localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff,
|
@@ -217,7 +202,9 @@ localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff,
|
|
217
202
|
}
|
218
203
|
|
219
204
|
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
|
205
|
+
#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
|
220
206
|
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
|
207
|
+
#define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
|
221
208
|
|
222
209
|
static int
|
223
210
|
leap_year_p(int y)
|
@@ -263,6 +250,20 @@ static const int leap_year_days_in_month[] = {
|
|
263
250
|
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
264
251
|
};
|
265
252
|
|
253
|
+
static int
|
254
|
+
calc_tm_yday(long tm_year, int tm_mon, int tm_mday)
|
255
|
+
{
|
256
|
+
int tm_year_mod400 = (int)MOD(tm_year, 400);
|
257
|
+
int tm_yday = tm_mday;
|
258
|
+
|
259
|
+
if (leap_year_p(tm_year_mod400 + 1900))
|
260
|
+
tm_yday += leap_year_yday_offset[tm_mon];
|
261
|
+
else
|
262
|
+
tm_yday += common_year_yday_offset[tm_mon];
|
263
|
+
|
264
|
+
return tm_yday;
|
265
|
+
}
|
266
|
+
|
266
267
|
time_t
|
267
268
|
timegm_noleapsecond(struct tm *tm)
|
268
269
|
{
|
@@ -287,6 +288,306 @@ timegm_noleapsecond(struct tm *tm)
|
|
287
288
|
DIV(tm_year+299,400))*86400;
|
288
289
|
}
|
289
290
|
|
291
|
+
/* assume time_t is signed */
|
292
|
+
#define SIGNED_INTEGER_MAX(sint_type) \
|
293
|
+
(sint_type) \
|
294
|
+
((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) | \
|
295
|
+
((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) - 1))
|
296
|
+
#define SIGNED_INTEGER_MIN(sint_type) (-SIGNED_INTEGER_MAX(sint_type)-1)
|
297
|
+
# define TIMET_MAX SIGNED_INTEGER_MAX(time_t)
|
298
|
+
# define TIMET_MIN SIGNED_INTEGER_MIN(time_t)
|
299
|
+
# define DEBUG_FIND_TIME_NUMGUESS_INC
|
300
|
+
# define DEBUG_REPORT_GUESSRANGE
|
301
|
+
|
302
|
+
static int
|
303
|
+
tmcmp(struct tm *a, struct tm *b)
|
304
|
+
{
|
305
|
+
if (a->tm_year != b->tm_year)
|
306
|
+
return a->tm_year < b->tm_year ? -1 : 1;
|
307
|
+
else if (a->tm_mon != b->tm_mon)
|
308
|
+
return a->tm_mon < b->tm_mon ? -1 : 1;
|
309
|
+
else if (a->tm_mday != b->tm_mday)
|
310
|
+
return a->tm_mday < b->tm_mday ? -1 : 1;
|
311
|
+
else if (a->tm_hour != b->tm_hour)
|
312
|
+
return a->tm_hour < b->tm_hour ? -1 : 1;
|
313
|
+
else if (a->tm_min != b->tm_min)
|
314
|
+
return a->tm_min < b->tm_min ? -1 : 1;
|
315
|
+
else if (a->tm_sec != b->tm_sec)
|
316
|
+
return a->tm_sec < b->tm_sec ? -1 : 1;
|
317
|
+
else
|
318
|
+
return 0;
|
319
|
+
}
|
320
|
+
|
321
|
+
const char *
|
322
|
+
find_time_t(struct tm *tptr, int utc_p, time_t *tp)
|
323
|
+
{
|
324
|
+
time_t guess, guess0, guess_lo, guess_hi;
|
325
|
+
struct tm *tm, tm0, tm_lo, tm_hi;
|
326
|
+
int d;
|
327
|
+
int find_dst;
|
328
|
+
struct tm result;
|
329
|
+
int status;
|
330
|
+
int tptr_tm_yday;
|
331
|
+
|
332
|
+
#define GUESS(p) (DEBUG_FIND_TIME_NUMGUESS_INC (utc_p ? rb_gmtime_r((p), &result) : LOCALTIME((p), result)))
|
333
|
+
|
334
|
+
guess_lo = TIMET_MIN;
|
335
|
+
guess_hi = TIMET_MAX;
|
336
|
+
|
337
|
+
find_dst = 0 < tptr->tm_isdst;
|
338
|
+
|
339
|
+
#if defined(HAVE_MKTIME)
|
340
|
+
tm0 = *tptr;
|
341
|
+
if (!utc_p && (guess = mktime(&tm0)) != -1) {
|
342
|
+
tm = GUESS(&guess);
|
343
|
+
if (tm && tmcmp(tptr, tm) == 0) {
|
344
|
+
goto found;
|
345
|
+
}
|
346
|
+
}
|
347
|
+
#endif
|
348
|
+
|
349
|
+
tm0 = *tptr;
|
350
|
+
if (tm0.tm_mon < 0) {
|
351
|
+
tm0.tm_mon = 0;
|
352
|
+
tm0.tm_mday = 1;
|
353
|
+
tm0.tm_hour = 0;
|
354
|
+
tm0.tm_min = 0;
|
355
|
+
tm0.tm_sec = 0;
|
356
|
+
}
|
357
|
+
else if (11 < tm0.tm_mon) {
|
358
|
+
tm0.tm_mon = 11;
|
359
|
+
tm0.tm_mday = 31;
|
360
|
+
tm0.tm_hour = 23;
|
361
|
+
tm0.tm_min = 59;
|
362
|
+
tm0.tm_sec = 60;
|
363
|
+
}
|
364
|
+
else if (tm0.tm_mday < 1) {
|
365
|
+
tm0.tm_mday = 1;
|
366
|
+
tm0.tm_hour = 0;
|
367
|
+
tm0.tm_min = 0;
|
368
|
+
tm0.tm_sec = 0;
|
369
|
+
}
|
370
|
+
else if ((d = (leap_year_p(1900 + tm0.tm_year) ?
|
371
|
+
leap_year_days_in_month :
|
372
|
+
common_year_days_in_month)[tm0.tm_mon]) < tm0.tm_mday) {
|
373
|
+
tm0.tm_mday = d;
|
374
|
+
tm0.tm_hour = 23;
|
375
|
+
tm0.tm_min = 59;
|
376
|
+
tm0.tm_sec = 60;
|
377
|
+
}
|
378
|
+
else if (tm0.tm_hour < 0) {
|
379
|
+
tm0.tm_hour = 0;
|
380
|
+
tm0.tm_min = 0;
|
381
|
+
tm0.tm_sec = 0;
|
382
|
+
}
|
383
|
+
else if (23 < tm0.tm_hour) {
|
384
|
+
tm0.tm_hour = 23;
|
385
|
+
tm0.tm_min = 59;
|
386
|
+
tm0.tm_sec = 60;
|
387
|
+
}
|
388
|
+
else if (tm0.tm_min < 0) {
|
389
|
+
tm0.tm_min = 0;
|
390
|
+
tm0.tm_sec = 0;
|
391
|
+
}
|
392
|
+
else if (59 < tm0.tm_min) {
|
393
|
+
tm0.tm_min = 59;
|
394
|
+
tm0.tm_sec = 60;
|
395
|
+
}
|
396
|
+
else if (tm0.tm_sec < 0) {
|
397
|
+
tm0.tm_sec = 0;
|
398
|
+
}
|
399
|
+
else if (60 < tm0.tm_sec) {
|
400
|
+
tm0.tm_sec = 60;
|
401
|
+
}
|
402
|
+
|
403
|
+
DEBUG_REPORT_GUESSRANGE;
|
404
|
+
guess0 = guess = timegm_noleapsecond(&tm0);
|
405
|
+
tm = GUESS(&guess);
|
406
|
+
if (tm) {
|
407
|
+
d = tmcmp(tptr, tm);
|
408
|
+
if (d == 0) { goto found; }
|
409
|
+
if (d < 0) {
|
410
|
+
guess_hi = guess;
|
411
|
+
guess -= 24 * 60 * 60;
|
412
|
+
}
|
413
|
+
else {
|
414
|
+
guess_lo = guess;
|
415
|
+
guess += 24 * 60 * 60;
|
416
|
+
}
|
417
|
+
DEBUG_REPORT_GUESSRANGE;
|
418
|
+
if (guess_lo < guess && guess < guess_hi && (tm = GUESS(&guess)) != NULL) {
|
419
|
+
d = tmcmp(tptr, tm);
|
420
|
+
if (d == 0) { goto found; }
|
421
|
+
if (d < 0)
|
422
|
+
guess_hi = guess;
|
423
|
+
else
|
424
|
+
guess_lo = guess;
|
425
|
+
DEBUG_REPORT_GUESSRANGE;
|
426
|
+
}
|
427
|
+
}
|
428
|
+
|
429
|
+
tm = GUESS(&guess_lo);
|
430
|
+
if (!tm) goto error;
|
431
|
+
d = tmcmp(tptr, tm);
|
432
|
+
if (d < 0) goto out_of_range;
|
433
|
+
if (d == 0) { guess = guess_lo; goto found; }
|
434
|
+
tm_lo = *tm;
|
435
|
+
|
436
|
+
tm = GUESS(&guess_hi);
|
437
|
+
if (!tm) goto error;
|
438
|
+
d = tmcmp(tptr, tm);
|
439
|
+
if (d > 0) goto out_of_range;
|
440
|
+
if (d == 0) { guess = guess_hi; goto found; }
|
441
|
+
tm_hi = *tm;
|
442
|
+
|
443
|
+
DEBUG_REPORT_GUESSRANGE;
|
444
|
+
|
445
|
+
status = 1;
|
446
|
+
|
447
|
+
while (guess_lo + 1 < guess_hi) {
|
448
|
+
if (status == 0) {
|
449
|
+
binsearch:
|
450
|
+
guess = guess_lo / 2 + guess_hi / 2;
|
451
|
+
if (guess <= guess_lo)
|
452
|
+
guess = guess_lo + 1;
|
453
|
+
else if (guess >= guess_hi)
|
454
|
+
guess = guess_hi - 1;
|
455
|
+
status = 1;
|
456
|
+
}
|
457
|
+
else {
|
458
|
+
if (status == 1) {
|
459
|
+
time_t guess0_hi = timegm_noleapsecond(&tm_hi);
|
460
|
+
guess = guess_hi - (guess0_hi - guess0);
|
461
|
+
if (guess == guess_hi) /* hh:mm:60 tends to cause this condition. */
|
462
|
+
guess--;
|
463
|
+
status = 2;
|
464
|
+
}
|
465
|
+
else if (status == 2) {
|
466
|
+
time_t guess0_lo = timegm_noleapsecond(&tm_lo);
|
467
|
+
guess = guess_lo + (guess0 - guess0_lo);
|
468
|
+
if (guess == guess_lo)
|
469
|
+
guess++;
|
470
|
+
status = 0;
|
471
|
+
}
|
472
|
+
if (guess <= guess_lo || guess_hi <= guess) {
|
473
|
+
/* Precious guess is invalid. try binary search. */
|
474
|
+
#ifdef DEBUG_GUESSRANGE
|
475
|
+
if (guess <= guess_lo) fprintf(stderr, "too small guess: %ld <= %ld\n", guess, guess_lo);
|
476
|
+
if (guess_hi <= guess) fprintf(stderr, "too big guess: %ld <= %ld\n", guess_hi, guess);
|
477
|
+
#endif
|
478
|
+
goto binsearch;
|
479
|
+
}
|
480
|
+
}
|
481
|
+
|
482
|
+
tm = GUESS(&guess);
|
483
|
+
if (!tm) goto error;
|
484
|
+
|
485
|
+
d = tmcmp(tptr, tm);
|
486
|
+
|
487
|
+
if (d < 0) {
|
488
|
+
guess_hi = guess;
|
489
|
+
tm_hi = *tm;
|
490
|
+
DEBUG_REPORT_GUESSRANGE;
|
491
|
+
}
|
492
|
+
else if (d > 0) {
|
493
|
+
guess_lo = guess;
|
494
|
+
tm_lo = *tm;
|
495
|
+
DEBUG_REPORT_GUESSRANGE;
|
496
|
+
}
|
497
|
+
else {
|
498
|
+
found:
|
499
|
+
if (!utc_p) {
|
500
|
+
/* If localtime is nonmonotonic, another result may exist. */
|
501
|
+
time_t guess2;
|
502
|
+
if (find_dst) {
|
503
|
+
guess2 = guess - 2 * 60 * 60;
|
504
|
+
tm = LOCALTIME(&guess2, result);
|
505
|
+
if (tm) {
|
506
|
+
if (tptr->tm_hour != (tm->tm_hour + 2) % 24 ||
|
507
|
+
tptr->tm_min != tm->tm_min ||
|
508
|
+
tptr->tm_sec != tm->tm_sec) {
|
509
|
+
guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
|
510
|
+
(tm->tm_min - tptr->tm_min) * 60 +
|
511
|
+
(tm->tm_sec - tptr->tm_sec);
|
512
|
+
if (tptr->tm_mday != tm->tm_mday)
|
513
|
+
guess2 += 24 * 60 * 60;
|
514
|
+
if (guess != guess2) {
|
515
|
+
tm = LOCALTIME(&guess2, result);
|
516
|
+
if (tm && tmcmp(tptr, tm) == 0) {
|
517
|
+
if (guess < guess2)
|
518
|
+
*tp = guess;
|
519
|
+
else
|
520
|
+
*tp = guess2;
|
521
|
+
return NULL;
|
522
|
+
}
|
523
|
+
}
|
524
|
+
}
|
525
|
+
}
|
526
|
+
}
|
527
|
+
else {
|
528
|
+
guess2 = guess + 2 * 60 * 60;
|
529
|
+
tm = LOCALTIME(&guess2, result);
|
530
|
+
if (tm) {
|
531
|
+
if ((tptr->tm_hour + 2) % 24 != tm->tm_hour ||
|
532
|
+
tptr->tm_min != tm->tm_min ||
|
533
|
+
tptr->tm_sec != tm->tm_sec) {
|
534
|
+
guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
|
535
|
+
(tm->tm_min - tptr->tm_min) * 60 +
|
536
|
+
(tm->tm_sec - tptr->tm_sec);
|
537
|
+
if (tptr->tm_mday != tm->tm_mday)
|
538
|
+
guess2 -= 24 * 60 * 60;
|
539
|
+
if (guess != guess2) {
|
540
|
+
tm = LOCALTIME(&guess2, result);
|
541
|
+
if (tm && tmcmp(tptr, tm) == 0) {
|
542
|
+
if (guess < guess2)
|
543
|
+
*tp = guess2;
|
544
|
+
else
|
545
|
+
*tp = guess;
|
546
|
+
return NULL;
|
547
|
+
}
|
548
|
+
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
}
|
552
|
+
}
|
553
|
+
*tp = guess;
|
554
|
+
return NULL;
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
/* Given argument has no corresponding time_t. Let's extrapolate. */
|
559
|
+
/*
|
560
|
+
* `Seconds Since the Epoch' in SUSv3:
|
561
|
+
* tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
|
562
|
+
* (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
|
563
|
+
* ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
|
564
|
+
*/
|
565
|
+
|
566
|
+
tptr_tm_yday = calc_tm_yday(tptr->tm_year, tptr->tm_mon, tptr->tm_mday);
|
567
|
+
|
568
|
+
*tp = guess_lo +
|
569
|
+
((tptr->tm_year - tm_lo.tm_year) * 365 +
|
570
|
+
((tptr->tm_year-69)/4) -
|
571
|
+
((tptr->tm_year-1)/100) +
|
572
|
+
((tptr->tm_year+299)/400) -
|
573
|
+
((tm_lo.tm_year-69)/4) +
|
574
|
+
((tm_lo.tm_year-1)/100) -
|
575
|
+
((tm_lo.tm_year+299)/400) +
|
576
|
+
tptr_tm_yday -
|
577
|
+
tm_lo.tm_yday) * 86400 +
|
578
|
+
(tptr->tm_hour - tm_lo.tm_hour) * 3600 +
|
579
|
+
(tptr->tm_min - tm_lo.tm_min) * 60 +
|
580
|
+
(tptr->tm_sec - (tm_lo.tm_sec == 60 ? 59 : tm_lo.tm_sec));
|
581
|
+
|
582
|
+
return NULL;
|
583
|
+
|
584
|
+
out_of_range:
|
585
|
+
return "time out of range";
|
586
|
+
|
587
|
+
error:
|
588
|
+
return "gmtime/localtime error";
|
589
|
+
}
|
590
|
+
|
290
591
|
void
|
291
592
|
tm_add_offset(struct tm *tm, long diff)
|
292
593
|
{
|
data/ext/strptime/strptime.c
CHANGED
@@ -35,7 +35,7 @@ VALUE rb_cStrptime;
|
|
35
35
|
{
|
36
36
|
|
37
37
|
#define END_INSNS_DISPATCH() \
|
38
|
-
rb_bug("unknown insn: %p", GET_CURRENT_INSN());
|
38
|
+
rb_bug("strptime: unknown insn: %p", GET_CURRENT_INSN()); \
|
39
39
|
} /* end of while loop */
|
40
40
|
|
41
41
|
#define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
|
@@ -421,31 +421,7 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen,
|
|
421
421
|
struct tm tm;
|
422
422
|
time_t t;
|
423
423
|
int gmt = gmtoff >= INT_MAX-1 ? INT_MAX-gmtoff : 2;
|
424
|
-
|
425
|
-
/* get current time with timezone */
|
426
|
-
rb_timespec_now(&ts);
|
427
|
-
{
|
428
|
-
static time_t ct;
|
429
|
-
static struct tm ctm;
|
430
|
-
static long ctmoff;
|
431
|
-
static long localoff;
|
432
|
-
if (ct != ts.tv_sec) {
|
433
|
-
ct = ts.tv_sec;
|
434
|
-
localtime_with_gmtoff_zone(&ct, &ctm, &ctmoff, NULL);
|
435
|
-
localoff = ctmoff;
|
436
|
-
}
|
437
|
-
if (gmtoff == INT_MAX) {
|
438
|
-
gmtoff = localoff;
|
439
|
-
}
|
440
|
-
else if (gmtoff == INT_MAX-1) {
|
441
|
-
gmtoff = 0;
|
442
|
-
}
|
443
|
-
if (gmtoff != ctmoff) {
|
444
|
-
tm_add_offset(&ctm, gmtoff - ctmoff);
|
445
|
-
ctmoff = gmtoff;
|
446
|
-
}
|
447
|
-
memcpy(&tm, &ctm, sizeof(struct tm));
|
448
|
-
}
|
424
|
+
const char *r;
|
449
425
|
|
450
426
|
/* overwrite time */
|
451
427
|
if (year != INT_MAX) {
|
@@ -466,6 +442,17 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen,
|
|
466
442
|
tm.tm_sec = sec;
|
467
443
|
}
|
468
444
|
else {
|
445
|
+
rb_timespec_now(&ts);
|
446
|
+
if (gmt) {
|
447
|
+
t = ts.tv_sec;
|
448
|
+
if (gmt == 2) t += gmtoff;
|
449
|
+
gmtime_r(&t, &tm);
|
450
|
+
}
|
451
|
+
else {
|
452
|
+
long off;
|
453
|
+
localtime_with_gmtoff_zone(&ts.tv_sec, &tm, &off, NULL);
|
454
|
+
gmtoff = (int)off;
|
455
|
+
}
|
469
456
|
if (mon != -1) goto setmonth;
|
470
457
|
if (mday != -1) goto setmday;
|
471
458
|
if (hour != -1) goto sethour;
|
@@ -473,8 +460,14 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen,
|
|
473
460
|
if (sec != -1) tm.tm_sec = sec;
|
474
461
|
}
|
475
462
|
|
476
|
-
|
477
|
-
|
463
|
+
if (gmt) {
|
464
|
+
t = timegm_noleapsecond(&tm);
|
465
|
+
if (gmt == 2) t -= gmtoff;
|
466
|
+
}
|
467
|
+
else {
|
468
|
+
r = find_time_t(&tm, gmt, &t);
|
469
|
+
if (r) fail();
|
470
|
+
}
|
478
471
|
tsp->tv_sec = t;
|
479
472
|
tsp->tv_nsec = nsec;
|
480
473
|
*gmtoffp = gmtoff;
|
@@ -484,7 +477,7 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen,
|
|
484
477
|
END_INSNS_DISPATCH();
|
485
478
|
|
486
479
|
/* unreachable */
|
487
|
-
rb_bug("
|
480
|
+
rb_bug("strptime_exec0: unreachable");
|
488
481
|
UNREACHABLE;
|
489
482
|
}
|
490
483
|
|
data/ext/strptime/strptime.h
CHANGED
@@ -10,6 +10,7 @@ struct tm * localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long
|
|
10
10
|
void rb_timespec_now(struct timespec *ts);
|
11
11
|
# endif
|
12
12
|
time_t timegm_noleapsecond(struct tm *tm);
|
13
|
+
const char *find_time_t(struct tm *tptr, int utc_p, time_t *tp);
|
13
14
|
void tm_add_offset(struct tm *tm, long diff);
|
14
15
|
|
15
16
|
#endif /* STRPTIME_H */
|
data/lib/strptime/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strptime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NARUSE, Yui
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|