我有一个字符串:"31-02-2010"
,想要检查它是否为有效日期。
我需要一个方法,如果字符串是有效日期则返回true,否则返回false。
我有一个字符串:"31-02-2010"
,想要检查它是否为有效日期。
我需要一个方法,如果字符串是有效日期则返回true,否则返回false。
require 'date'
begin
Date.parse("31-02-2010")
rescue ArgumentError
# handle invalid date
end
这是一个简单的一行代码:
DateTime.parse date rescue nil
在现实生活中,我可能不会建议完全按照这种方式进行操作,因为这会强制调用方检查nil值,例如在格式化时。如果你返回一个默认的日期或错误信息,那么会更友好。
Date.strptime(date, '%d/%m/%Y') rescue nil
可以翻译为:尝试将字符串类型的日期转化为日期对象,格式为'%d/%m/%Y',如果无法转化则返回nil。 - bonafernandorescue
。 - smoythd, m, y = date_string.split '-'
Date.valid_date? y.to_i, m.to_i, d.to_i
is_valid?
?尝试了1.8、2.0和2.1,但它们似乎都没有这个函数。不过所有版本似乎都有valid_date?
。 - Henrik N解析日期可能会遇到一些棘手的问题,特别是当它们采用 MM/DD/YYYY 或 DD/MM/YYYY 格式时,例如在美国或欧洲使用的短日期格式。
Date#parse
试图确定要使用哪种格式,但在整年中许多月份有很多天数存在格式之间的歧义,这可能导致解析问题。
我建议找出用户所在的 LOCALE,然后基于此,您将知道如何使用 Date.strptime
智能解析。找到用户所在位置的最佳方法是在注册期间询问他们,然后在其偏好设置中提供更改选项。如果您通过某些巧妙的启发式方法挖掘出信息而不打扰用户,这很容易出现故障,因此请直接询问用户。
这是使用 Date.parse
进行的测试。我位于美国:
>> Date.parse('01/31/2001')
ArgumentError: invalid date
>> Date.parse('31/01/2001') #=> #<Date: 2001-01-31 (4903881/2,0,2299161)>
第一种日期格式是美国正确的格式:mm/dd/yyyy,但是 Date
不支持这种格式。第二种格式对于欧洲来说是正确的,但如果你的客户主要来自美国,你会得到很多解析错误的日期。
Ruby 的 Date.strptime
用法如下:
>> Date.strptime('12/31/2001', '%m/%d/%Y') #=> #<Date: 2001-12-31 (4904549/2,0,2299161)>
- hoyhoy?> Date.parse('31/01/2001') ArgumentError: 无效日期
01/01/2014
,哪一个是月,哪一个是日?在美国,月份是第一个,在世界其他地方,则是第二个。 - the Tin Man01/31/2001
是一个无效的日期,解析函数按照预期工作。 - QwertieDate.valid_date? *date_string.split('-').reverse.map(&:to_i)
require“date”
,否则会出现“未定义的方法”。 - Henrik NDate.valid_date? *Array.new(3).zip(date_string.split('-')).transpose.last.reverse.map(&:to_i)
- vincentp我想扩展 Date
类。
class Date
def self.parsable?(string)
begin
parse(string)
true
rescue ArgumentError
false
end
end
end
Date.parsable?("10-10-2010")
# => true
Date.parse("10-10-2010")
# => Sun, 10 Oct 2010
Date.parsable?("1")
# => false
Date.parse("1")
# ArgumentError: invalid date from (pry):106:in `parse'
另一种验证日期的方法:
date_hash = Date._parse(date.to_s)
Date.valid_date?(date_hash[:year].to_i,
date_hash[:mon].to_i,
date_hash[:mday].to_i)
Date.valid_date?(*Date._parse(date).values)
。 - Sunny如果您指定预期的日期格式,则更容易验证日期的正确性。但即使如此,对于我的用例来说,Ruby仍然过于宽容:
Date.parse("Tue, 2017-01-17", "%a, %Y-%m-%d") # works
Date.parse("Wed, 2017-01-17", "%a, %Y-%m-%d") # works - !?
很明显,这些字符串中至少有一个指定了错误的星期几,但是Ruby会快乐地忽略它。
这里有一个方法可以验证:date.strftime(format)
转换回与使用Date.strptime
解析的相同输入字符串,格式为format
。
module StrictDateParsing
# If given "Tue, 2017-01-17" and "%a, %Y-%m-%d", will return the parsed date.
# If given "Wed, 2017-01-17" and "%a, %Y-%m-%d", will error because that's not
# a Wednesday.
def self.parse(input_string, format)
date = Date.strptime(input_string, format)
confirmation = date.strftime(format)
if confirmation == input_string
date
else
fail InvalidDate.new(
"'#{input_string}' parsed as '#{format}' is inconsistent (eg, weekday doesn't match date)"
)
end
end
InvalidDate = Class.new(RuntimeError)
end
Date.today().iso8601
); %m
是零填充的。如果您想要其他内容,请参见https://ruby-doc.org/stdlib-2.4.0/libdoc/date/rdoc/Date.html#method-c-strptime。 - Nathan Long我发布这篇文章是因为它可能对某些人有用。不知道这是否是一种“好”的方法,但它适合我并且可以扩展。
class String
def is_date?
temp = self.gsub(/[-.\/]/, '')
['%m%d%Y','%m%d%y','%M%D%Y','%M%D%y'].each do |f|
begin
return true if Date.strptime(temp, f)
rescue
#do nothing
end
end
return false
end
end
这个String类的插件让你可以在第4行指定分隔符列表,然后在第5行指定有效格式列表。虽然不是什么高深的技术,但它使得扩展变得非常容易,并且让你可以轻松地检查一个字符串,例如:
"test".is_date?
"10-12-2010".is_date?
params[:some_field].is_date?
etc.
/(\d{1,2}[-\/]\d{1,2}[-\/]\d{4})|(\d{4}[-\/]\d{1,2}[-\/]\d{1,2})/.match("31-02-2010")
仅针对带有前导零、年份在后并带破折号的格式:
/(\d{2}-\d{2}-\d{4})/.match("31-02-2010")
[-/]表示可以是短横线或斜杠,必须对正斜杠进行转义。
您可以在http://gskinner.com/RegExr/上测试此功能。
添加以下行,如果使用第一个正则表达式,则所有行都将突出显示,不包括第一个和最后一个“/”(它们用于Ruby代码中)。
2004-02-01
2004/02/01
01-02-2004
1-2-2004
2004-2-1
32-13-2010
这样的日期,这是错误的。 - yagooar