mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
time: add missing timezone offset methods and tests
implement gmt_offset, utc_offset, and gmtoff methods as aliases to complete the ruby time api. all three methods return timezone offset in seconds, with utc times returning 0 and local times returning the appropriate offset value. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1583,6 +1583,39 @@ time_saturday(mrb_state *mrb, mrb_value self)
|
||||
return time_wday_p(mrb, self, 6);
|
||||
}
|
||||
|
||||
/*
|
||||
* ISO 15.2.19.7.12
|
||||
* ISO 15.2.19.7.14
|
||||
* ISO 15.2.19.7.29
|
||||
*/
|
||||
/*
|
||||
* call-seq:
|
||||
* time.gmt_offset -> integer
|
||||
* time.utc_offset -> integer
|
||||
* time.gmtoff -> integer
|
||||
*
|
||||
* Returns the offset in seconds between the timezone of time and UTC.
|
||||
*
|
||||
* Time.local(2000, 1, 1).gmt_offset #=> 32400 (JST: UTC+9)
|
||||
* Time.utc(2000, 1, 1).utc_offset #=> 0 (UTC)
|
||||
* Time.local(2000, 7, 1).gmtoff #=> 32400 (or 28800 if DST)
|
||||
*/
|
||||
static mrb_value
|
||||
time_utc_offset(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_time *tm = time_get_ptr(mrb, self);
|
||||
|
||||
if (tm->timezone == MRB_TIMEZONE_UTC) {
|
||||
return mrb_fixnum_value(0); /* UTC is always offset 0 */
|
||||
}
|
||||
|
||||
/* For local times, calculate offset = local_time_t - utc_time_t */
|
||||
time_t utc_time_t = timegm(&tm->datetime); /* Convert datetime as UTC */
|
||||
mrb_int offset_seconds = (mrb_int)(tm->sec - utc_time_t);
|
||||
|
||||
return mrb_fixnum_value(offset_seconds);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_time_gem_init(mrb_state* mrb)
|
||||
{
|
||||
@@ -1656,12 +1689,9 @@ mrb_mruby_time_gem_init(mrb_state* mrb)
|
||||
mrb_define_method_id(mrb, tc, MRB_SYM_Q(friday), time_friday, MRB_ARGS_NONE());
|
||||
mrb_define_method_id(mrb, tc, MRB_SYM_Q(saturday), time_saturday, MRB_ARGS_NONE());
|
||||
|
||||
/*
|
||||
methods not available:
|
||||
gmt_offset(15.2.19.7.12)
|
||||
gmtoff(15.2.19.7.14)
|
||||
utc_offset(15.2.19.7.29)
|
||||
*/
|
||||
mrb_define_method_id(mrb, tc, MRB_SYM(gmt_offset), time_utc_offset, MRB_ARGS_NONE()); /* 15.2.19.7.12 */
|
||||
mrb_define_method_id(mrb, tc, MRB_SYM(gmtoff), time_utc_offset, MRB_ARGS_NONE()); /* 15.2.19.7.14 */
|
||||
mrb_define_method_id(mrb, tc, MRB_SYM(utc_offset), time_utc_offset, MRB_ARGS_NONE()); /* 15.2.19.7.29 */
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -219,8 +219,24 @@ assert('Time#utc?', '15.2.19.7.28') do
|
||||
assert_predicate(Time.at(1300000000).utc, :utc?)
|
||||
end
|
||||
|
||||
# ATM not implemented
|
||||
# assert('Time#utc_offset', '15.2.19.7.29') do
|
||||
assert('Time#utc_offset, #gmt_offset, #gmtoff', '15.2.19.7.12, 15.2.19.7.14, 15.2.19.7.29') do
|
||||
# UTC times should have zero offset
|
||||
utc_time = Time.utc(2000, 1, 1)
|
||||
assert_equal(0, utc_time.utc_offset)
|
||||
|
||||
# Local times should return integer offsets in seconds
|
||||
local_time = Time.local(2000, 1, 1)
|
||||
assert_kind_of(Integer, local_time.utc_offset)
|
||||
|
||||
# Test that offset values make sense (should be multiple of 900 seconds = 15 minutes)
|
||||
assert_equal(0, local_time.utc_offset % 900)
|
||||
|
||||
# All three methods should be aliases returning identical values
|
||||
assert_equal(utc_time.utc_offset, utc_time.gmt_offset)
|
||||
assert_equal(utc_time.utc_offset, utc_time.gmtoff)
|
||||
assert_equal(local_time.utc_offset, local_time.gmt_offset)
|
||||
assert_equal(local_time.utc_offset, local_time.gmtoff)
|
||||
end
|
||||
|
||||
assert('Time#wday', '15.2.19.7.30') do
|
||||
assert_equal(0, Time.gm(2012, 12, 23).wday)
|
||||
|
||||
Reference in New Issue
Block a user