我有一个字符串: "31-02-2010"
并且想要检查它是否是有效日期。最好的方法是什么?
我需要一个方法,如果字符串是有效日期,则返回true,否则返回false。
我有一个字符串: "31-02-2010"
并且想要检查它是否是有效日期。最好的方法是什么?
我需要一个方法,如果字符串是有效日期,则返回true,否则返回false。
Answers:
require 'date'
begin
Date.parse("31-02-2010")
rescue ArgumentError
# handle invalid date
end
这是一个简单的班轮:
DateTime.parse date rescue nil
我可能不建议您在现实生活中的每种情况下都严格执行此操作,因为您迫使调用者检查是否为零。特别是在格式化时。如果返回默认日期|错误,则可能会更友好。
Date.strptime(date, '%d/%m/%Y') rescue nil
rescue
不建议使用内联。
解析日期可能会遇到一些麻烦,尤其是当它们采用MM / DD / YYYY或DD / MM / YYYY格式时,例如在美国或欧洲使用的短日期。
Date#parse
试图找出要使用的格式,但是一年中一个月中的很多天,格式之间的歧义会导致解析问题。
我建议您找出用户的本地地址,然后基于此,您将知道如何使用 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)>
01/01/2014
,那么哪个月和哪一天?在美国,月度排名第一,世界其他地区排名第二。
Date.valid_date? *date_string.split('-').reverse.map(&:to_i)
require "date"
首先需要获得“未定义的方法”。
Date.valid_date? *Array.new(3).zip(date_string.split('-')).transpose.last.reverse.map(&:to_i)
我想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)
对于所有日期,请尝试使用正则表达式:
/(\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
错误的日期。
'00/00/0000'
,'99-99/9999'
并且可能是候选值。
如果指定所需的日期格式,则更容易验证日期的正确性。但是,即使那样,对于我的用例来说,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
被零填充。如果你想要的东西不同,请参阅ruby-doc.org/stdlib-2.4.0/libdoc/date/rdoc/...
发布此消息是因为以后可能有用。不知道这是否是一种“好”方法,但这对我有用并且可以扩展。
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.
require 'date'
#new_date and old_date should be String
# Note we need a ()
def time_between(new_date, old_date)
new_date = (Date.parse new_date rescue nil)
old_date = (Date.parse old_date rescue nil)
return nil if new_date.nil? || old_date.nil?
(new_date - old_date).to_i
end
puts time_between(1,2).nil?
#=> true
puts time_between(Time.now.to_s,Time.now.to_s).nil?
#=> false
您可以尝试以下简单的方法:
"31-02-2010".try(:to_date)
但是您需要处理异常。
对于此示例,Date.parse没有引发异常:
Date.parse("12!12*2012")
=> Thu, 12 Apr 2018
Date.parse("12!12&2012")
=> Thu, 12 Apr 2018
我更喜欢这种解决方案:
Date.parse("12!12*2012".gsub(/[^\d,\.,\-]/, ''))
=> ArgumentError: invalid date
Date.parse("12-12-2012".gsub(/[^\d,\.,\-]/, ''))
=> Wed, 12 Dec 2012
Date.parse("12.12.2012".gsub(/[^\d,\.,\-]/, ''))
=> Wed, 12 Dec 2012