Ruby on rails 如何在Rails中转换原始时间字符串?
在Rails(>=6)中,将表示时间的原始字符串转换为Ruby on rails 如何在Rails中转换原始时间字符串?,ruby-on-rails,ruby,Ruby On Rails,Ruby,在Rails(>=6)中,将表示时间的原始字符串转换为ActiveSupport::Duration对象的好方法是什么?例如,类似于: 45 min 1 h 我在中读到了一些答案,但问题是创业板不再被维护 module DurationParser class ParseError < StandardError; end # This is an example of how to extend it with aliases ALAISES = { hours:
ActiveSupport::Duration
对象的好方法是什么?例如,类似于:
45 min
1 h
我在中读到了一些答案,但问题是创业板不再被维护
module DurationParser
class ParseError < StandardError; end
# This is an example of how to extend it with aliases
ALAISES = {
hours: [:h, :hr],
minutes: [:m, :min],
seconds: [:s, :sec]
}
EXP = /^(?<value>[\d*|\.]*)\s*(?<token>\w*)?$/.freeze
# Parses a human readable string into a duration
# @example
# DurationParser.parse('2 hours, 1 minute')
# @return [ActiveSupport::Duration]
def self.parse(string)
string.split(/and|,/).map(&:strip).map do |pair|
matches = pair.match(EXP)
method = token_to_method(matches[:token])
raise ParseError unless method
(matches[:value].to_i).send(method)
end.reduce(&:+)
end
private
def self.token_to_method(token)
ActiveSupport::Duration::PARTS.find do |p|
p == token.downcase.pluralize.to_sym
end || ALAISES.find do |k,v|
v.include?(token.downcase.to_sym)
end&.first
end
end
当然,如果您希望使用可靠的机器可读的东西,而不是不可靠的字符串解析器。如果您可以确保字符串遵循特定格式,那么讨论中有一些答案不依赖gem。像这个还是这个。在您的情况下,您需要将当时的缩写转换为rails方法
h
->.hours
等regex不是我的强大套件,因此这可能会简化。谢谢!事实上ISO8601将是伟大的,但我没有一手的数据
require 'rails_helper'
RSpec.describe DurationParser do
describe '.parse' do
it "handles hours" do
expect(DurationParser.parse('1 h')).to eq 1.hour;
expect(DurationParser.parse('1 hr')).to eq 1.hour;
expect(DurationParser.parse('1 hour')).to eq 1.hour;
expect(DurationParser.parse('3 hours')).to eq 3.hours;
end
it "handles minutes" do
expect(DurationParser.parse('1 m')).to eq 1.minute;
expect(DurationParser.parse('1 min')).to eq 1.minute;
expect(DurationParser.parse('1 minute')).to eq 1.minute;
expect(DurationParser.parse('2 minutes')).to eq 2.minutes;
end
it "handles seconds" do
expect(DurationParser.parse('1 s')).to eq 1.second;
expect(DurationParser.parse('1 sec')).to eq 1.second;
expect(DurationParser.parse('1 second')).to eq 1.second;
expect(DurationParser.parse('15 seconds')).to eq 15.seconds;
end
it "handles comma delimeted strings" do
expect(DurationParser.parse('1 hour, 3 minutes, 15 seconds')).to eq(
1.hour + 3.minutes + 15.seconds
)
end
it "handles 'and' delimeted strings" do
expect(DurationParser.parse('1 hour and 3 minutes and 15 seconds')).to eq(
1.hour + 3.minutes + 15.seconds
)
end
it "handles mixed delimeter strings" do
expect(DurationParser.parse('1 hour and 3 minutes, 15 seconds')).to eq(
1.hour + 3.minutes + 15.seconds
)
end
it "raises when a bad token is passed" do
expect { DurationParser.parse('25 sols') }.to raise_error(DurationParser::ParseError)
end
end
end