mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[Bug #19106] Normalize time at 24:00:00 with a timezone object
This commit is contained in:
parent
ee86b57ee5
commit
011d4c57d2
2 changed files with 21 additions and 8 deletions
|
@ -612,6 +612,11 @@ module TestTimeTZ::WithTZ
|
||||||
assert_raise(ArgumentError) {time_class.new(2018, 9, 1, 12, 0, 0, tzarg, in: tzarg)}
|
assert_raise(ArgumentError) {time_class.new(2018, 9, 1, 12, 0, 0, tzarg, in: tzarg)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def subtest_hour24(time_class, tz, tzarg, tzname, abbr, utc_offset)
|
||||||
|
t = time_class.new(2000, 1, 1, 24, 0, 0, tzarg)
|
||||||
|
assert_equal([0, 0, 0, 2, 1, 2000], [t.sec, t.min, t.hour, t.mday, t.mon, t.year])
|
||||||
|
end
|
||||||
|
|
||||||
def subtest_now(time_class, tz, tzarg, tzname, abbr, utc_offset)
|
def subtest_now(time_class, tz, tzarg, tzname, abbr, utc_offset)
|
||||||
t = time_class.now(in: tzarg)
|
t = time_class.now(in: tzarg)
|
||||||
assert_equal(tz, t.zone)
|
assert_equal(tz, t.zone)
|
||||||
|
|
24
time.c
24
time.c
|
@ -2331,6 +2331,19 @@ find_timezone(VALUE time, VALUE zone)
|
||||||
return rb_check_funcall_default(klass, id_find_timezone, 1, &zone, Qnil);
|
return rb_check_funcall_default(klass, id_find_timezone, 1, &zone, Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Turn the special case 24:00:00 of already validated vtm into
|
||||||
|
* 00:00:00 the next day */
|
||||||
|
static void
|
||||||
|
vtm_day_wraparound(struct vtm *vtm)
|
||||||
|
{
|
||||||
|
if (vtm->hour < 24) return;
|
||||||
|
|
||||||
|
/* Assuming UTC and no care of DST, just reset hour and advance
|
||||||
|
* date, not to discard the validated vtm. */
|
||||||
|
vtm->hour = 0;
|
||||||
|
vtm_add_day(vtm, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VALUE mday, VALUE hour, VALUE min, VALUE sec, VALUE zone)
|
time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VALUE mday, VALUE hour, VALUE min, VALUE sec, VALUE zone)
|
||||||
{
|
{
|
||||||
|
@ -2386,6 +2399,7 @@ time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VA
|
||||||
|
|
||||||
if (!NIL_P(zone)) {
|
if (!NIL_P(zone)) {
|
||||||
tobj->timew = timegmw(&vtm);
|
tobj->timew = timegmw(&vtm);
|
||||||
|
vtm_day_wraparound(&vtm);
|
||||||
tobj->vtm = vtm;
|
tobj->vtm = vtm;
|
||||||
tobj->tm_got = 1;
|
tobj->tm_got = 1;
|
||||||
TZMODE_SET_LOCALTIME(tobj);
|
TZMODE_SET_LOCALTIME(tobj);
|
||||||
|
@ -2400,13 +2414,7 @@ time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VA
|
||||||
|
|
||||||
if (utc == UTC_ZONE) {
|
if (utc == UTC_ZONE) {
|
||||||
tobj->timew = timegmw(&vtm);
|
tobj->timew = timegmw(&vtm);
|
||||||
if (vtm.hour == 24) { /* special case: 24:00:00 only */
|
vtm_day_wraparound(&vtm);
|
||||||
/* Since no need to take care of DST in UTC, just reset
|
|
||||||
* hour and advance date, not to discard the validated
|
|
||||||
* vtm. */
|
|
||||||
vtm.hour = 0;
|
|
||||||
vtm_add_day(&vtm, 1);
|
|
||||||
}
|
|
||||||
tobj->vtm = vtm;
|
tobj->vtm = vtm;
|
||||||
tobj->tm_got = 1;
|
tobj->tm_got = 1;
|
||||||
TZMODE_SET_UTC(tobj);
|
TZMODE_SET_UTC(tobj);
|
||||||
|
@ -4105,7 +4113,7 @@ time_inspect(VALUE time)
|
||||||
GetTimeval(time, tobj);
|
GetTimeval(time, tobj);
|
||||||
str = strftimev("%Y-%m-%d %H:%M:%S", time, rb_usascii_encoding());
|
str = strftimev("%Y-%m-%d %H:%M:%S", time, rb_usascii_encoding());
|
||||||
subsec = w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE)));
|
subsec = w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE)));
|
||||||
if (FIXNUM_P(subsec) && FIX2LONG(subsec) == 0) {
|
if (subsec == INT2FIX(0)) {
|
||||||
}
|
}
|
||||||
else if (FIXNUM_P(subsec) && FIX2LONG(subsec) < TIME_SCALE) {
|
else if (FIXNUM_P(subsec) && FIX2LONG(subsec) < TIME_SCALE) {
|
||||||
long len;
|
long len;
|
||||||
|
|
Loading…
Reference in a new issue