我有一个包含多个日期和时间的数组:
[ "24/Oct/2014:13:43:15 -0600",
"25/Oct/2014:14:47:25 -0600",
"24/Oct/2014:13:46:15 -0600" ]
我一直在努力。
["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]
我尝试使用gsub
替换不需要的空格,但它只删除了冒号。我怎么能删除它?
答案 0 :(得分:2)
有很多方法可以将日期字符串作为String对象进行操作。在您的情况下,两个此类选项包括String#partition和String#match。例如:
dates = [
"24/Oct/2014:13:43:15 -0600",
"25/Oct/2014:14:47:25 -0600",
"24/Oct/2014:13:46:15 -0600"
]
dates.map { |date| date.match(/\A[^:]+/).to_s }
dates.map { |date| date.partition(?:)[0] }
两种方法都将返回一个字符串数组,如下所示:
#=> ["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]
将此类日期作为String对象处理的主要问题是您假设字符串表示将始终相同。如果您知道自己的数据,那很好,但将日期视为日期通常会更好。例如,您可以使用Date#parse(有或没有Date#strftime)自动处理常见表示,如下所示:
require 'date'
# Remove #to_s if you want to return actual Date objects for
# further processing, rather than an array of strings.
dates.map { |date| Date.parse(date).to_s }
#=> ["2016-10-24", "2016-10-25", "2016-10-24"]
# This will only return strings, but that's what you originally
# asked for.
dates.map { |date| Date.parse(date).strftime '%d/%b/%Y' }
#=> ["24/Oct/2016", "25/Oct/2016", "24/Oct/2016"]
Date和DateTime库也包含其他解析器。当然,如果您使用非标准输入格式,则可以将Date#strptime与自定义模板一起使用。
这里的重点是,将多个String对象起作用,但通常最好将日期作为Date或DateTime对象处理,以避免边缘情况,验证输入并引发异常,例如:
dates.map { |date| Date.rfc2822 date }
ArgumentError:无效日期
适当的时候。你应该尽可能地利用这样的核心功能。
答案 1 :(得分:1)
arr = ["24/Oct/2014:13:43:15 -0600",
"05/Oct/2014:14:47:25 -0600",
"24/Oct/2014:13:46:15 -0600"]
如果你确定日期字符串的格式是正确的,并且代表有效日期,你可以简单地写
arr.map { |s| s[0,11] }
#=> ["24/Oct/2014", "05/Oct/2014", "24/Oct/2014"]
另一方面,如果要检查日期字符串的有效性,您可能希望将每个日期字符串转换为日期对象,然后将该对象转换为所需的字符串格式。这样,如果日期字符串无效,则会引发异常。
require 'date'
arr.map { |s| DateTime.strptime(s, '%d/%b/%Y:%H:%M:%S %z').strftime('%d/%b/%Y') }
#=> ["24/Oct/2014", "05/Oct/2014", "24/Oct/2014"]
这使用方法DateTime::strptime和DateTime#strftime。日期格式字符串在strftime
的文档中进行了解释。
假设
arr = ["42/Oct/2014:13:43:15 -0600"]
然后
arr.map { |s| DateTime.strptime(s, '%d/%b/%Y:%H:%M:%S %z').strftime('%d/%b/%Y') }
#=> ArgumentError: invalid date
您可以使用DateTime::parse代替strptime
将日期字符串转换为Date
个对象,但在识别无效日期方面却相当薄弱。例如:
DateTime.parse "123456/01-02abc"
#=> #<DateTime: 123456-01-02T00:00:00+00:00 ((46812439j,0s,0n),...
DateTime.parse "-7/8"
#=> #<DateTime: 2016-07-08T00:00:00+00:00 ((2457578j,0s,0n),...
DateTime.parse "He demanded 1/2 of the pie"
#=> #<DateTime: 2016-01-02T00:00:00+00:00 ((2457390j,0s,0n),...
答案 2 :(得分:0)
只需在:
上拆分并弃掉其余部分:
times = [ "24/Oct/2014:13:43:15 -0600", "25/Oct/2014:14:47:25 -0600", "24/Oct/2014:13:46:15 -0600" ]
times.map do |time|
time.split(':').first
end
# => ["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]
如果您想就地执行此操作并修改数组,请使用map!
。