跳至内容 跳至搜索

Active Support 持续时间

使用 Date#advanceTime#advance 分别提供准确的日期和时间测量。它主要支持 Numeric 上的方法。

1.month.ago       # equivalent to Time.now.advance(months: -1)
命名空间
方法
#
A
B
E
F
H
I
P
S
T
U

常量

PARTS = [:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze
 
PARTS_IN_SECONDS = { seconds: 1, minutes: SECONDS_PER_MINUTE, hours: SECONDS_PER_HOUR, days: SECONDS_PER_DAY, weeks: SECONDS_PER_WEEK, months: SECONDS_PER_MONTH, years: SECONDS_PER_YEAR }.freeze
 
SECONDS_PER_DAY = 86400
 
SECONDS_PER_HOUR = 3600
 
SECONDS_PER_MINUTE = 60
 
SECONDS_PER_MONTH = 2629746
 
SECONDS_PER_WEEK = 604800
 
SECONDS_PER_YEAR = 31556952
 
VARIABLE_PARTS = [:years, :months, :weeks, :days].freeze
 

属性

[R] value

类公共方法

build(value)

从秒值创建一个新的 Duration,该秒值被转换为各个部分。

ActiveSupport::Duration.build(31556952).parts # => {:years=>1}
ActiveSupport::Duration.build(2716146).parts  # => {:months=>1, :days=>1}
# File activesupport/lib/active_support/duration.rb, line 189
def build(value)
  unless value.is_a?(::Numeric)
    raise TypeError, "can't build an #{self.name} from a #{value.class.name}"
  end

  parts = {}
  remainder_sign = value <=> 0
  remainder = value.round(9).abs
  variable = false

  PARTS.each do |part|
    unless part == :seconds
      part_in_seconds = PARTS_IN_SECONDS[part]
      parts[part] = remainder.div(part_in_seconds) * remainder_sign
      remainder %= part_in_seconds

      unless parts[part].zero?
        variable ||= VARIABLE_PARTS.include?(part)
      end
    end
  end unless value == 0

  parts[:seconds] = remainder * remainder_sign

  new(value, parts, variable)
end

parse(iso8601duration)

从根据 ISO 8601 Duration 格式化的字符串创建一个新的 Duration

有关更多信息,请参阅 ISO 8601。此方法允许模式中存在负数部分。如果提供无效字符串,它将引发 ActiveSupport::Duration::ISO8601Parser::ParsingError

# File activesupport/lib/active_support/duration.rb, line 144
def parse(iso8601duration)
  parts = ISO8601Parser.new(iso8601duration).parse!
  new(calculate_total_seconds(parts), parts)
end

实例公共方法

%(other)

返回此 Duration 与另一个 DurationNumeric 的模。Numeric 值被视为秒。

# File activesupport/lib/active_support/duration.rb, line 312
def %(other)
  if Duration === other || Scalar === other
    Duration.build(value % other.value)
  elsif Numeric === other
    Duration.build(value % other)
  else
    raise_type_error(other)
  end
end

*(other)

将此 Duration 乘以 Numeric 并返回一个新的 Duration

# File activesupport/lib/active_support/duration.rb, line 287
def *(other)
  if Scalar === other || Duration === other
    Duration.new(value * other.value, @parts.transform_values { |number| number * other.value }, @variable || other.variable?)
  elsif Numeric === other
    Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable)
  else
    raise_type_error(other)
  end
end

+(other)

将另一个 DurationNumeric 添加到此 DurationNumeric 值被视为秒。

# File activesupport/lib/active_support/duration.rb, line 268
def +(other)
  if Duration === other
    parts = @parts.merge(other._parts) do |_key, value, other_value|
      value + other_value
    end
    Duration.new(value + other.value, parts, @variable || other.variable?)
  else
    seconds = @parts.fetch(:seconds, 0) + other
    Duration.new(value + other, @parts.merge(seconds: seconds), @variable)
  end
end

-(other)

从此 Duration 中减去另一个 DurationNumericNumeric 值被视为秒。

# File activesupport/lib/active_support/duration.rb, line 282
def -(other)
  self + (-other)
end

/(other)

将此 Duration 除以 Numeric 并返回一个新的 Duration

# File activesupport/lib/active_support/duration.rb, line 298
def /(other)
  if Scalar === other
    Duration.new(value / other.value, @parts.transform_values { |number| number / other.value }, @variable)
  elsif Duration === other
    value / other.value
  elsif Numeric === other
    Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable)
  else
    raise_type_error(other)
  end
end

<=>(other)

将一个 Duration 与另一个 DurationNumeric 进行比较。Numeric 值被视为秒。

# File activesupport/lib/active_support/duration.rb, line 258
def <=>(other)
  if Duration === other
    value <=> other.value
  elsif Numeric === other
    value <=> other
  end
end

==(other)

如果 other 也是具有相同 valueDuration 实例,或者如果 other == value,则返回 true

# File activesupport/lib/active_support/duration.rb, line 341
def ==(other)
  if Duration === other
    other.value == value
  else
    other == value
  end
end

after(time = ::Time.current)

别名:since

ago(time = ::Time.current)

计算一个新的 TimeDate,该时间与这个 Duration 所代表的时间一样远。

也称为:untilbefore
# File activesupport/lib/active_support/duration.rb, line 444
def ago(time = ::Time.current)
  sum(-1, time)
end

before(time = ::Time.current)

别名:ago

eql?(other)

如果 other 也是一个 Duration 实例,并且具有与该实例相同的部分,则返回 true

# File activesupport/lib/active_support/duration.rb, line 426
def eql?(other)
  Duration === other && other.value.eql?(value)
end

from_now(time = ::Time.current)

别名:since

hash()

# File activesupport/lib/active_support/duration.rb, line 430
def hash
  @value.hash
end

in_days()

以浮点数形式返回持续时间所涵盖的天数。

12.hours.in_days # => 0.5
# File activesupport/lib/active_support/duration.rb, line 399
def in_days
  in_seconds / SECONDS_PER_DAY.to_f
end

in_hours()

以浮点数形式返回持续时间所涵盖的小时数。

1.day.in_hours # => 24.0
# File activesupport/lib/active_support/duration.rb, line 392
def in_hours
  in_seconds / SECONDS_PER_HOUR.to_f
end

in_minutes()

以浮点数形式返回持续时间所涵盖的分钟数。

1.day.in_minutes # => 1440.0
# File activesupport/lib/active_support/duration.rb, line 385
def in_minutes
  in_seconds / SECONDS_PER_MINUTE.to_f
end

in_months()

以浮点数形式返回持续时间所涵盖的月数。

9.weeks.in_months # => 2.07
# File activesupport/lib/active_support/duration.rb, line 413
def in_months
  in_seconds / SECONDS_PER_MONTH.to_f
end

in_seconds()

别名:to_i

in_weeks()

以浮点数形式返回持续时间所涵盖的周数。

2.months.in_weeks # => 8.696
# File activesupport/lib/active_support/duration.rb, line 406
def in_weeks
  in_seconds / SECONDS_PER_WEEK.to_f
end

in_years()

以浮点数形式返回持续时间所涵盖的年数。

30.days.in_years # => 0.082
# File activesupport/lib/active_support/duration.rb, line 420
def in_years
  in_seconds / SECONDS_PER_YEAR.to_f
end

iso8601(precision: nil)

为该持续时间构建 ISO 8601 Duration 字符串。precision 参数可用于限制持续时间秒的精度。

# File activesupport/lib/active_support/duration.rb, line 473
def iso8601(precision: nil)
  ISO8601Serializer.new(self, precision: precision).serialize
end

parts()

返回定义持续时间的部件哈希的副本。

5.minutes.parts # => {:minutes=>5}
3.years.parts # => {:years=>3}
# File activesupport/lib/active_support/duration.rb, line 241
def parts
  @parts.dup
end

since(time = ::Time.current)

计算一个新的 TimeDate,该时间与这个 Duration 所代表的时间一样远。

也称为:from_nowafter
# File activesupport/lib/active_support/duration.rb, line 436
def since(time = ::Time.current)
  sum(1, time)
end

to_i()

返回此 Duration 所代表的秒数。

1.minute.to_i   # => 60
1.hour.to_i     # => 3600
1.day.to_i      # => 86400

请注意,这种转换对某些周期的持续时间做出了一些假设,例如,月份始终是年份的 1/12,年份是 365.2425 天。

# equivalent to (1.year / 12).to_i
1.month.to_i    # => 2629746

# equivalent to 365.2425.days.to_i
1.year.to_i     # => 31556952

在这种情况下,应使用 Ruby 的核心 DateTime 来进行精确的日期和时间运算。

也称为:in_seconds
# File activesupport/lib/active_support/duration.rb, line 377
def to_i
  @value.to_i
end

to_s()

返回持续时间所涵盖的秒数的字符串。有关更多信息,请查看to_i 方法。

1.day.to_s # => "86400"
# File activesupport/lib/active_support/duration.rb, line 353
def to_s
  @value.to_s
end

until(time = ::Time.current)

别名:ago