30 #define gmtime_r(tp, tm) ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL)
31 #define localtime_r(tp, tm) ((localtime_s((tm), (tp)) == 0) ? (tm) : NULL)
44 #ifndef NO_GETTIMEOFDAY
48 #define gmtime_r(t,r) gmtime(t)
49 #define localtime_r(t,r) (tzset(),localtime(t))
52 #ifndef USE_SYSTEM_TIMEGM
53 #define timegm my_timgm
56 is_leapyear(
unsigned int y)
58 return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
64 static const unsigned int ndays[2][12] = {
65 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
66 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
70 unsigned int *nday = (
unsigned int*) ndays[is_leapyear(tm->tm_year+1900)];
72 for (i = 70; i < tm->tm_year; ++
i)
73 r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
74 for (i = 0; i < tm->tm_mon; ++
i)
75 r += nday[i] * 24 * 60 * 60;
76 r += (tm->tm_mday - 1) * 24 * 60 * 60;
77 r += tm->tm_hour * 60 * 60;
96 static const char *timezone_names[] = {
103 static const char *mon_names[] = {
104 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
107 static const char *wday_names[] = {
108 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
123 mrb_time_update_datetime(
struct mrb_time *
self)
128 aid = gmtime_r(&self->sec, &self->datetime);
131 aid = localtime_r(&self->sec, &self->datetime);
133 if (!aid)
return NULL;
135 self->datetime = *aid;
155 tm->
sec = (time_t)sec;
156 tm->
usec = (sec - tm->
sec) * 1.0e6 + usec;
157 while (tm->
usec < 0) {
161 while (tm->
usec > 1.0e6) {
166 mrb_time_update_datetime(tm);
174 return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone));
183 #ifdef NO_GETTIMEOFDAY
185 static time_t last_sec = 0, last_usec = 0;
187 tm->
sec = time(NULL);
188 if (tm->
sec != last_sec) {
196 tm->
usec = last_usec;
202 gettimeofday(&tv, NULL);
204 tm->
usec = tv.tv_usec;
208 mrb_time_update_datetime(tm);
217 return mrb_time_wrap(mrb,
mrb_class_ptr(
self), current_mrb_time(mrb));
237 struct tm nowtime = { 0 };
239 nowtime.tm_year = (int)ayear - 1900;
240 nowtime.tm_mon = (int)amonth - 1;
241 nowtime.tm_mday = (int)aday;
242 nowtime.tm_hour = (int)ahour;
243 nowtime.tm_min = (int)amin;
244 nowtime.tm_sec = (int)asec;
245 nowtime.tm_isdst = -1;
247 nowsecs =
timegm(&nowtime);
250 nowsecs = mktime(&nowtime);
256 return time_alloc(mrb, nowsecs, ausec, timezone);
264 mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
267 &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
269 time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec,
MRB_TIMEZONE_UTC));
278 mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
281 &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
297 eq_p = tm1 && tm2 && tm1->
sec == tm2->
sec && tm1->
usec == tm2->
usec;
299 return mrb_bool_value(eq_p);
311 if (!tm1 || !tm2)
return mrb_nil_value();
312 if (tm1->
sec > tm2->
sec) {
313 return mrb_fixnum_value(1);
315 else if (tm1->
sec < tm2->
sec) {
316 return mrb_fixnum_value(-1);
320 return mrb_fixnum_value(1);
323 return mrb_fixnum_value(-1);
325 return mrb_fixnum_value(0);
353 return mrb_float_value(mrb, f);
369 return mrb_fixnum_value(tm->
datetime.tm_wday);
380 return mrb_fixnum_value(tm->
datetime.tm_yday + 1);
391 return mrb_fixnum_value(tm->
datetime.tm_year + 1900);
419 len = snprintf(buf,
sizeof(buf),
"%s %s %02d %02d:%02d:%02d %s%d",
420 wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
421 d->tm_hour, d->tm_min, d->tm_sec,
435 if (!tm)
return mrb_nil_value();
436 return mrb_fixnum_value(tm->
datetime.tm_mday);
448 return mrb_bool_value(tm->
datetime.tm_isdst);
463 mrb_time_update_datetime(tm2);
478 mrb_time_update_datetime(tm2);
490 return mrb_fixnum_value(tm->
datetime.tm_hour);
498 mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0,
499 amin = 0, asec = 0, ausec = 0;
511 &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
513 tm = current_mrb_time(mrb);
516 tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec,
MRB_TIMEZONE_LOCAL);
551 mrb_time_update_datetime(tm);
563 return mrb_fixnum_value(tm->
datetime.tm_mday);
574 return mrb_fixnum_value(tm->
datetime.tm_min);
585 return mrb_fixnum_value(tm->
datetime.tm_mon + 1);
596 return mrb_fixnum_value(tm->
datetime.tm_sec);
619 return mrb_fixnum_value(tm->
sec);
630 return mrb_fixnum_value(tm->
usec);
642 mrb_time_update_datetime(tm);