[Bug #19292] Re-initialize tm when wday or yday is not set
This commit is contained in:
parent
f527a0911d
commit
542e984d82
Notes:
git
2025-06-06 00:31:58 +00:00
@ -54,7 +54,8 @@ class TestTime < Test::Unit::TestCase
|
|||||||
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, "+09:99") }
|
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, "+09:99") }
|
||||||
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, "+09:99") }
|
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, "+09:99") }
|
||||||
|
|
||||||
assert_equal([0, 0, 0, 2, 1, 2000], Time.new(2000, 1, 1, 24, 0, 0, "-00:00").to_a[0, 6])
|
assert_equal([0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], Time.new(2000, 1, 1, 0, 0, 0, "-00:00").to_a)
|
||||||
|
assert_equal([0, 0, 0, 2, 1, 2000, 0, 2, false, "UTC"], Time.new(2000, 1, 1, 24, 0, 0, "-00:00").to_a)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_from_string
|
def test_new_from_string
|
||||||
|
29
time.c
29
time.c
@ -1790,6 +1790,7 @@ PACKED_STRUCT_UNALIGNED(struct time_object {
|
|||||||
(tobj1)->vtm.utc_offset = (tobj2)->vtm.utc_offset, \
|
(tobj1)->vtm.utc_offset = (tobj2)->vtm.utc_offset, \
|
||||||
(tobj1)->vtm.zone = (tobj2)->vtm.zone)
|
(tobj1)->vtm.zone = (tobj2)->vtm.zone)
|
||||||
|
|
||||||
|
static int zone_localtime(VALUE zone, VALUE time);
|
||||||
static VALUE time_get_tm(VALUE, struct time_object *);
|
static VALUE time_get_tm(VALUE, struct time_object *);
|
||||||
#define MAKE_TM(time, tobj) \
|
#define MAKE_TM(time, tobj) \
|
||||||
do { \
|
do { \
|
||||||
@ -1801,11 +1802,21 @@ static VALUE time_get_tm(VALUE, struct time_object *);
|
|||||||
do { \
|
do { \
|
||||||
MAKE_TM(time, tobj); \
|
MAKE_TM(time, tobj); \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
VALUE zone = (tobj)->vtm.zone; \
|
force_make_tm(time, tobj); \
|
||||||
if (!NIL_P(zone)) zone_localtime(zone, (time)); \
|
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
force_make_tm(VALUE time, struct time_object *tobj)
|
||||||
|
{
|
||||||
|
VALUE zone = tobj->vtm.zone;
|
||||||
|
if (!NIL_P(zone) && zone != str_empty && zone != str_utc) {
|
||||||
|
if (zone_localtime(zone, time)) return;
|
||||||
|
}
|
||||||
|
tobj->tm_got = 0;
|
||||||
|
time_get_tm(time, tobj);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
time_mark(void *ptr)
|
time_mark(void *ptr)
|
||||||
{
|
{
|
||||||
@ -2070,19 +2081,20 @@ vtm_add_day(struct vtm *vtm, int day)
|
|||||||
vtm->mday = 31;
|
vtm->mday = 31;
|
||||||
vtm->mon = 12; /* December */
|
vtm->mon = 12; /* December */
|
||||||
vtm->year = subv(vtm->year, INT2FIX(1));
|
vtm->year = subv(vtm->year, INT2FIX(1));
|
||||||
|
if (vtm->yday != 0)
|
||||||
vtm->yday = leap_year_v_p(vtm->year) ? 366 : 365;
|
vtm->yday = leap_year_v_p(vtm->year) ? 366 : 365;
|
||||||
}
|
}
|
||||||
else if (vtm->mday == 1) {
|
else if (vtm->mday == 1) {
|
||||||
const int8_t *days_in_month = days_in_month_in_v(vtm->year);
|
const int8_t *days_in_month = days_in_month_in_v(vtm->year);
|
||||||
vtm->mon--;
|
vtm->mon--;
|
||||||
vtm->mday = days_in_month[vtm->mon-1];
|
vtm->mday = days_in_month[vtm->mon-1];
|
||||||
vtm->yday--;
|
if (vtm->yday != 0) vtm->yday--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vtm->mday--;
|
vtm->mday--;
|
||||||
vtm->yday--;
|
if (vtm->yday != 0) vtm->yday--;
|
||||||
}
|
}
|
||||||
vtm->wday = (vtm->wday + 6) % 7;
|
if (vtm->wday != VTM_WDAY_INITVAL) vtm->wday = (vtm->wday + 6) % 7;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int leap = leap_year_v_p(vtm->year);
|
int leap = leap_year_v_p(vtm->year);
|
||||||
@ -2095,13 +2107,13 @@ vtm_add_day(struct vtm *vtm, int day)
|
|||||||
else if (vtm->mday == days_in_month_of(leap)[vtm->mon-1]) {
|
else if (vtm->mday == days_in_month_of(leap)[vtm->mon-1]) {
|
||||||
vtm->mon++;
|
vtm->mon++;
|
||||||
vtm->mday = 1;
|
vtm->mday = 1;
|
||||||
vtm->yday++;
|
if (vtm->yday != 0) vtm->yday++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vtm->mday++;
|
vtm->mday++;
|
||||||
vtm->yday++;
|
if (vtm->yday != 0) vtm->yday++;
|
||||||
}
|
}
|
||||||
vtm->wday = (vtm->wday + 1) % 7;
|
if (vtm->wday != VTM_WDAY_INITVAL) vtm->wday = (vtm->wday + 1) % 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2449,6 +2461,7 @@ time_init_vtm(VALUE time, struct vtm vtm, VALUE zone)
|
|||||||
|
|
||||||
if (utc == UTC_ZONE) {
|
if (utc == UTC_ZONE) {
|
||||||
tobj->timew = timegmw(&vtm);
|
tobj->timew = timegmw(&vtm);
|
||||||
|
vtm.isdst = 0; /* No DST in UTC */
|
||||||
vtm_day_wraparound(&vtm);
|
vtm_day_wraparound(&vtm);
|
||||||
tobj->vtm = vtm;
|
tobj->vtm = vtm;
|
||||||
tobj->tm_got = 1;
|
tobj->tm_got = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user