Skip to content

Commit 4183d40

Browse files
committed
Refactor Time and move #compose/#from_array to TimeOperations module
1 parent d709c3b commit 4183d40

File tree

3 files changed

+116
-108
lines changed

3 files changed

+116
-108
lines changed

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ public boolean isTruffleBootMainMethod(SharedMethodInfo info) {
10011001
"/core/truffle/stat_operations.rb",
10021002
"/core/truffle/string_operations.rb",
10031003
"/core/truffle/backward.rb",
1004+
"/core/truffle/time_operations.rb",
10041005
"/core/truffle/truffleruby.rb",
10051006
"/core/splitter.rb",
10061007
"/core/stat.rb",

src/main/ruby/truffleruby/core/time.rb

Lines changed: 6 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@
3737
class Time
3838
include Comparable
3939

40-
MonthValue = {
41-
'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6,
42-
'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12
43-
}
44-
4540
def inspect
4641
str = strftime('%Y-%m-%d %H:%M:%S')
4742

@@ -371,103 +366,6 @@ def at(sec, sub_sec = undefined, unit = undefined, **kwargs)
371366
time
372367
end
373368

374-
def from_array(sec, min, hour, mday, month, year, nsec, is_dst, is_utc, utc_offset)
375-
# Ensure all the user provided numeric values fit into int type.
376-
# sec and nsec are handled separately.
377-
Primitive.rb_num2int(min)
378-
Primitive.rb_num2int(hour)
379-
Primitive.rb_num2int(mday)
380-
Primitive.rb_num2int(month)
381-
Primitive.rb_num2int(year)
382-
383-
# handle sec and nsec
384-
if Primitive.is_a?(sec, String)
385-
sec = sec.to_i
386-
elsif nsec
387-
sec = Truffle::Type.coerce_to(sec || 0, Integer, :to_int)
388-
else
389-
s = Truffle::Type.coerce_to_exact_num(sec || 0)
390-
391-
sec = s.to_i
392-
nsec_frac = s % 1.0
393-
394-
if s < 0 && nsec_frac > 0
395-
sec -= 1
396-
end
397-
398-
nsec = (nsec_frac * 1_000_000_000 + 0.5).to_i
399-
end
400-
401-
nsec ||= 0
402-
403-
Primitive.time_s_from_array(self, sec, min, hour, mday, month, year, nsec, is_dst, is_utc, utc_offset)
404-
end
405-
private :from_array
406-
407-
def compose(offset, p1, p2 = nil, p3 = nil, p4 = nil, p5 = nil, p6 = nil, p7 = nil,
408-
yday = undefined, is_dst = undefined, tz = undefined)
409-
if Primitive.undefined?(tz)
410-
unless Primitive.undefined?(is_dst)
411-
raise ArgumentError, 'wrong number of arguments (9 for 1..8)'
412-
end
413-
414-
y = p1
415-
m = p2
416-
d = p3
417-
hr = p4
418-
min = p5
419-
sec = p6
420-
usec = p7
421-
is_dst = -1
422-
else
423-
y = p6
424-
m = p5
425-
d = p4
426-
hr = p3
427-
min = p2
428-
sec = p1
429-
usec = 0
430-
is_dst = is_dst ? 1 : 0
431-
end
432-
433-
if Primitive.is_a?(m, String) or m.respond_to?(:to_str)
434-
m = StringValue(m)
435-
m = MonthValue[m.upcase] || m.to_i
436-
437-
raise ArgumentError, 'month argument out of range' unless m
438-
else
439-
m = Truffle::Type.coerce_to(m || 1, Integer, :to_int)
440-
end
441-
442-
y = Primitive.is_a?(y, String) ? y.to_i : Truffle::Type.coerce_to(y, Integer, :to_int)
443-
d = Primitive.is_a?(d, String) ? d.to_i : Truffle::Type.coerce_to(d || 1, Integer, :to_int)
444-
hr = Primitive.is_a?(hr, String) ? hr.to_i : Truffle::Type.coerce_to(hr || 0, Integer, :to_int)
445-
min = Primitive.is_a?(min, String) ? min.to_i : Truffle::Type.coerce_to(min || 0, Integer, :to_int)
446-
447-
nsec = nil
448-
if Primitive.is_a?(usec, String)
449-
nsec = usec.to_i * 1000
450-
elsif usec
451-
nsec = (usec * 1000).to_i
452-
end
453-
454-
case offset
455-
when :utc
456-
is_dst = -1
457-
is_utc = true
458-
offset = nil
459-
when :local
460-
is_utc = false
461-
offset = nil
462-
else
463-
is_dst = -1
464-
is_utc = false
465-
end
466-
467-
from_array(sec, min, hr, d, m, y, nsec, is_dst, is_utc, offset)
468-
end
469-
private :compose
470-
471369
def new(year = undefined, month = nil, day = nil, hour = nil, minute = nil, second = nil, utc_offset = nil, **options)
472370
if utc_offset && options[:in]
473371
raise ArgumentError, 'timezone argument given as positional and keyword arguments'
@@ -478,18 +376,18 @@ def new(year = undefined, month = nil, day = nil, hour = nil, minute = nil, seco
478376
if Primitive.undefined?(year)
479377
utc_offset ? self.now.getlocal(utc_offset) : self.now
480378
elsif Primitive.nil? utc_offset
481-
compose(:local, year, month, day, hour, minute, second)
379+
Truffle::TimeOperations.compose(self, :local, year, month, day, hour, minute, second)
482380
elsif utc_offset == :std
483-
compose(:local, second, minute, hour, day, month, year, nil, nil, false, nil)
381+
Truffle::TimeOperations.compose(self, :local, second, minute, hour, day, month, year, nil, nil, false, nil)
484382
elsif utc_offset == :dst
485-
compose(:local, second, minute, hour, day, month, year, nil, nil, true, nil)
383+
Truffle::TimeOperations.compose(self, :local, second, minute, hour, day, month, year, nil, nil, true, nil)
486384
else
487385
if utc_offset_in_utc?(utc_offset)
488386
utc_offset = :utc
489387
else
490388
utc_offset = Truffle::Type.coerce_to_utc_offset(utc_offset)
491389
end
492-
compose(utc_offset, year, month, day, hour, minute, second)
390+
Truffle::TimeOperations.compose(self, utc_offset, year, month, day, hour, minute, second)
493391
end
494392
end
495393

@@ -512,12 +410,12 @@ def now(**options)
512410
end
513411

514412
def local(*args)
515-
compose(:local, *args)
413+
Truffle::TimeOperations.compose(self, :local, *args)
516414
end
517415
alias_method :mktime, :local
518416

519417
def gm(*args)
520-
compose(:utc, *args)
418+
Truffle::TimeOperations.compose(self, :utc, *args)
521419
end
522420
alias_method :utc, :gm
523421
end
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. This
4+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
5+
# redistribute it and/or modify it under the terms of the:
6+
#
7+
# Eclipse Public License version 2.0, or
8+
# GNU General Public License version 2, or
9+
# GNU Lesser General Public License version 2.1.
10+
11+
module Truffle
12+
module TimeOperations
13+
MonthValue = {
14+
'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6,
15+
'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12
16+
}
17+
18+
def self.compose(time_class, utc_offset, p1, p2 = nil, p3 = nil, p4 = nil, p5 = nil, p6 = nil, p7 = nil,
19+
yday = undefined, is_dst = undefined, tz = undefined)
20+
if Primitive.undefined?(tz)
21+
unless Primitive.undefined?(is_dst)
22+
raise ArgumentError, 'wrong number of arguments (9 for 1..8)'
23+
end
24+
25+
year = p1
26+
month = p2
27+
mday = p3
28+
hour = p4
29+
min = p5
30+
sec = p6
31+
usec = p7
32+
is_dst = -1
33+
else
34+
year = p6
35+
month = p5
36+
mday = p4
37+
hour = p3
38+
min = p2
39+
sec = p1
40+
usec = 0
41+
is_dst = is_dst ? 1 : 0
42+
end
43+
44+
if Primitive.is_a?(month, String) or month.respond_to?(:to_str)
45+
month = StringValue(month)
46+
month = MonthValue[month.upcase] || month.to_i
47+
48+
raise ArgumentError, 'month argument out of range' unless month
49+
else
50+
month = Truffle::Type.coerce_to(month || 1, Integer, :to_int)
51+
end
52+
53+
year = Primitive.is_a?(year, String) ? year.to_i : Truffle::Type.coerce_to(year, Integer, :to_int)
54+
mday = Primitive.is_a?(mday, String) ? mday.to_i : Truffle::Type.coerce_to(mday || 1, Integer, :to_int)
55+
hour = Primitive.is_a?(hour, String) ? hour.to_i : Truffle::Type.coerce_to(hour || 0, Integer, :to_int)
56+
min = Primitive.is_a?(min, String) ? min.to_i : Truffle::Type.coerce_to(min || 0, Integer, :to_int)
57+
58+
nsec = nil
59+
if Primitive.is_a?(usec, String)
60+
nsec = usec.to_i * 1000
61+
elsif usec
62+
nsec = (usec * 1000).to_i
63+
end
64+
65+
case utc_offset
66+
when :utc
67+
is_dst = -1
68+
is_utc = true
69+
utc_offset = nil
70+
when :local
71+
is_utc = false
72+
utc_offset = nil
73+
else
74+
is_dst = -1
75+
is_utc = false
76+
end
77+
78+
# Ensure all the user provided numeric values fit into the Java Integer type.
79+
# sec and nsec are handled separately.
80+
Primitive.rb_num2int(min)
81+
Primitive.rb_num2int(hour)
82+
Primitive.rb_num2int(mday)
83+
Primitive.rb_num2int(month)
84+
Primitive.rb_num2int(year)
85+
86+
# handle sec and nsec
87+
if Primitive.is_a?(sec, String)
88+
sec = sec.to_i
89+
elsif nsec
90+
sec = Truffle::Type.coerce_to(sec || 0, Integer, :to_int)
91+
else
92+
s = Truffle::Type.coerce_to_exact_num(sec || 0)
93+
94+
sec = s.to_i
95+
nsec_frac = s % 1.0
96+
97+
if s < 0 && nsec_frac > 0
98+
sec -= 1
99+
end
100+
101+
nsec = (nsec_frac * 1_000_000_000 + 0.5).to_i
102+
end
103+
104+
nsec ||= 0
105+
106+
Primitive.time_s_from_array(time_class, sec, min, hour, mday, month, year, nsec, is_dst, is_utc, utc_offset)
107+
end
108+
end
109+
end

0 commit comments

Comments
 (0)