描述
我需要输入作为字符串日期的输入,可以是带有时区的完整日期时间格式,它可以是日期,它可以是24小时格式的时间,24小时格式的时区或时间在上午和下午或上述任何组合。
作为输出,我想获得当前(或给定)日期以及24小时格式和时区的时间,我们可以在ruby Time.parse()
中解析。我做了一些工作,你可以在下面找到源代码。我还为某些期望添加了rspec(测试用例)。
您可以根据需要提供自己的解决方案或更新我的来源。
实施例
注意:如果未提供日期,此处的预计日期为当前日期
'2200+5'
应转换为"2016-1-1T22:00:00 +0500"
'100'
应转换为"2016-1-1T01:00:00 +0000"
'1700+8'
应转换为"2016-1-1T17:00:00 +0800"
'5pm+8'
应转换为"2016-1-1T17:00:00 +0800"
'5am+8'
应转换为"2016-1-1T5:00:00 +0800"
'2016-12-15T2300+5'
应转换为'2016-12-15T23:00:00 +0500'
'1730'
应转换为"2016-1-1T17:30:00 +0000"
'530pm+8'
应转换为"2016-1-1T17:30:00 +0800"
'1210am+8'
应转换为"2016-1-1T12:10:00 +0800"
RSpec
describe "should convert datetime to accepted format"
Timecop.freeze(Time.utc(2016,1,1,2,0,0))
it {expect(parse('2200+5')).to eq({time: Time.parse("2016-1-1T22:00:00 +0500")})}
it {expect(parse('100')).to eq({time: Time.parse("2016-1-1T01:00:00 +0000")})}
it {expect(parse('1700+8')).to eq({time: Time.parse("2016-1-1T17:00:00 +0800")})}
it {expect(parse('5pm+8')).to eq({time: Time.parse("2016-1-1T17:00:00 +0800")})}
it {expect(parse('5am+8')).to eq({time: Time.parse("2016-1-1T5:00:00 +0800")})}
it {expect(parse('2016-12-15T2300+5')).to eq({time: Time.parse("2016-12-15T23:00:00 +0500")})}
it {expect(parse('1730')).to eq({time: Time.parse("2016-1-1T17:30:00 +0000")})}
Timecop.return
end
我做得太多了
# ensure 2 char in time format
def ensure_2_char_in_time(t)
return "0#{t}" if t.to_s.length == 1
t.to_s
end
def get_time_zone_from(aTimeParams)
date, tzm, tzm_type = nil
# get date, time, timezon from given string
if aTimeParams.include?('-') && aTimeParams.include?('T')
date, time_zone = aTimeParams.split('T')
else
time_zone = aTimeParams
end
# get time, zone from given string
if time_zone.include?('+')
tzm_type = '+'
time_str, tzm = aTimeParams.split('+')
elsif time_zone.include?('-')
tzm_type = '-'
time_str, tzm = aTimeParams.split('-')
else
tzm_type = '+'
time_str = aTimeParams
end
date = "#{Date.today.year}-#{Date.today.month}-#{Date.today.day}" if date.blank?
if time_str.include?('pm')
hour = ensure_2_char_in_time(time_str.to_i + 12)
min = '00'
elsif time_str.include?('am')
hour = ensure_2_char_in_time(time_str.to_i)
min = '00'
else
hour = ensure_2_char_in_time(time_str.to_i / 100)
min = ensure_2_char_in_time(time_str.to_i % 100)
end
if tzm.to_s.length <= 2
tzm_h = ensure_2_char_in_time tzm.to_i % 100
tzm_m = "00"
else
tzm_h = ensure_2_char_in_time tzm.to_i / 100
tzm_m = ensure_2_char_in_time tzm.to_i % 100
end
{
time: Time.parse("#{date}T#{hour}:#{min}:00 #{tzm_type}#{tzm_h}:#{tzm_m}"),
tzm: (tzm_h.to_i * 60 + tzm_m.to_i)
}
end
请告知我们进一步说明。
由于
答案 0 :(得分:1)
此代码适用于您提到的示例,然后是一些:
echo $(( $(cat maven_build.out | grep "Tests run" | grep -v "Time elapsed" | cut -d , -f 1 | cut -d " " -f 3 | tr "\n" "+") 0))
输出:
module FuzzyTimeParse
refine String do
# Removes the first regex match from self.
# Returns the matching substring if found, nil otherwise
def extract!(regex)
sub!(regex, '')
$&
end
end
refine Time.singleton_class do
def fuzzy_parse(date_or_time_or_something)
input = date_or_time_or_something.dup
input.extract!('am')
pm = input.extract!('pm') ? 12 : 0
timezone = input.extract!(/\s*(\+|-)\d$/).to_f || 0
timezone_hour = timezone.to_i
timezone_min = timezone * 60 % 60
if hour = input.extract!(/(?<![\d\:\-])\d\d?$/)
min = 0
else
min = input.extract!(/(?<!-)\d\d$/) || 0
input.extract!(':')
hour = input.extract!(/(?<![-\d])\d\d?$/) || 0
end
input.extract!(/T$/)
input.gsub!(/\s*/,'')
date = input.extract!(/\d\d\d\d\D?\d\d\D?\d\d/) || Time.now.strftime('%Y-%m-%d')
$stderr.puts "Warning : #{input} is still not parsed" unless input.empty?
date_time = format('%sT%02d:%02d:00 +%02d%02d', date, hour.to_i + pm, min, timezone_hour, timezone_min)
{ time: Time.parse(date_time) }
end
end
end
require 'timecop'
using FuzzyTimeParse
describe 'convert datetime to accepted format' do
before do
Timecop.freeze(Time.local(2016, 1, 1, 2, 0, 0))
end
it { expect(Time.fuzzy_parse('2200+5')).to eq(time: Time.parse('2016-1-1T22:00:00 +0500')) }
it { expect(Time.fuzzy_parse('100')).to eq(time: Time.parse('2016-1-1T01:00:00 +0000')) }
it { expect(Time.fuzzy_parse('1700+8')).to eq(time: Time.parse('2016-1-1T17:00:00 +0800')) }
it { expect(Time.fuzzy_parse('5pm+8')).to eq(time: Time.parse('2016-1-1T17:00:00 +0800')) }
it { expect(Time.fuzzy_parse('5am+8')).to eq(time: Time.parse('2016-1-1T5:00:00 +0800')) }
it { expect(Time.fuzzy_parse('2016-12-15T2300+5')).to eq(time: Time.parse('2016-12-15T23:00:00 +0500')) }
it { expect(Time.fuzzy_parse('2016-12-15 2300')).to eq(time: Time.parse('2016-12-15T23:00:00 +0000')) }
it { expect(Time.fuzzy_parse('2016-12-15 23:10 +7')).to eq(time: Time.parse('2016-12-15T23:10:00 +0700')) }
it { expect(Time.fuzzy_parse('1730')).to eq(time: Time.parse('2016-1-1T17:30:00 +0000')) }
it { expect(Time.fuzzy_parse('1210am+8')).to eq(time: Time.parse('2016-1-1T12:10:00 +0800')) }
it { expect(Time.fuzzy_parse('530pm+8')).to eq(time: Time.parse('2016-1-1T17:30:00 +0800')) }
it { expect(Time.fuzzy_parse('1730')).to eq(time: Time.parse('2016-1-1T17:30:00 +0000')) }
it { expect(Time.fuzzy_parse('17:30')).to eq(time: Time.parse('2016-1-1T17:30:00 +0000')) }
it { expect(Time.fuzzy_parse('17:30 +5')).to eq(time: Time.parse('2016-1-1T17:30:00 +0500')) }
it { expect(Time.fuzzy_parse('2016-12-03')).to eq(time: Time.parse('2016-12-03T00:00:00 +0000')) }
it { expect(Time.fuzzy_parse('2016-12-03 +2')).to eq(time: Time.parse('2016-12-03T00:00:00 +0200')) }
after do
Timecop.return
end
end
如果您不想重新发明轮子,Chronic gem可以帮助您,即使看起来需要手动定义时区:16 examples, 0 failures