Ruby-on-rails 如何检查字符串是否为有效日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2955830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if a string is a valid date
提问by Salil
I have a string: "31-02-2010"and want to check whether or not it is a valid date.
What is the best way to do it?
我有一个字符串:"31-02-2010"并且想检查它是否是一个有效的日期。最好的方法是什么?
I need a method which which returns true if the string is a valid date and false if it is not.
我需要一个方法,如果字符串是有效日期,则返回 true,否则返回 false。
采纳答案by mpd
require 'date'
begin
Date.parse("31-02-2010")
rescue ArgumentError
# handle invalid date
end
回答by robert_murray
Here is a simple one liner:
这是一个简单的单衬:
DateTime.parse date rescue nil
I probably wouldn't recommend doing exactly this in every situation in real life as you force the caller to check for nil, eg. particularly when formatting. If you return a default date|error it may be friendlier.
我可能不建议在现实生活中的每一种情况下都这样做,因为你强迫调用者检查 nil,例如。特别是在格式化时。如果您返回默认日期|错误,它可能会更友好。
回答by Sohan
d, m, y = date_string.split '-'
Date.valid_date? y.to_i, m.to_i, d.to_i
回答by the Tin Man
Parsing dates can run into some gotcha's, especially when they are in a MM/DD/YYYY or DD/MM/YYYY format, such as short dates used in U.S. or Europe.
解析日期可能会遇到一些问题,尤其是当它们采用 MM/DD/YYYY 或 DD/MM/YYYY 格式时,例如美国或欧洲使用的短日期。
Date#parseattempts to figure out which to use, but there are many days in a month throughout the year when ambiguity between the formats can cause parsing problems.
Date#parse试图找出使用哪个,但在一年中的一个月中有很多天格式之间的歧义会导致解析问题。
I'd recommend finding out what the LOCALE of the user is, then, based on that, you'll know how to parse intelligently using Date.strptime. The best way to find where a user is located is to ask them during sign-up, and then provide a setting in their preferences to change it. Assuming you can dig it out by some clever heuristic and not bother the user for that information, is prone to failure so just ask.
我建议找出用户的 LOCALE 是什么,然后,基于此,您将知道如何使用Date.strptime. 找到用户所在位置的最佳方法是在注册时询问他们,然后在他们的首选项中提供一个设置来更改它。假设您可以通过一些巧妙的启发式方法将其挖掘出来,并且不会因为该信息而打扰用户,则很容易失败,因此只需询问即可。
This is a test using Date.parse. I'm in the U.S.:
这是一个使用Date.parse. 我在美国:
>> Date.parse('01/31/2001')
ArgumentError: invalid date
>> Date.parse('31/01/2001') #=> #<Date: 2001-01-31 (4903881/2,0,2299161)>
The first was the correct format for the U.S.: mm/dd/yyyy, but Date didn't like it. The second was correct for Europe, but if your customers are predominately U.S.-based, you'll get a lot of badly parsed dates.
第一个是美国的正确格式:mm/dd/yyyy,但 Date 不喜欢它。第二个对欧洲来说是正确的,但如果您的客户主要是美国客户,您会得到很多解析错误的日期。
Ruby's Date.strptimeis used like:
Ruby 的Date.strptime用法如下:
>> Date.strptime('12/31/2001', '%m/%d/%Y') #=> #<Date: 2001-12-31 (4904549/2,0,2299161)>
回答by Samer Buna
Date.valid_date? *date_string.split('-').reverse.map(&:to_i)
Date.valid_date? *date_string.split('-').reverse.map(&:to_i)
回答by ironsand
I'd like to extend Dateclass.
我想扩展Date课程。
class Date
def self.parsable?(string)
begin
parse(string)
true
rescue ArgumentError
false
end
end
end
example
例子
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'
回答by Slava Zharkov
Another way to validate date:
验证日期的另一种方法:
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)
回答by Nathan Long
A stricter solution
更严格的解决方案
It's easier to verify the correctness of a date if you specify the date format you expect. However, even then, Ruby is a bit too tolerant for my use case:
如果指定期望的日期格式,则更容易验证日期的正确性。然而,即便如此,Ruby 对我的用例来说还是有点太宽容了:
Date.parse("Tue, 2017-01-17", "%a, %Y-%m-%d") # works
Date.parse("Wed, 2017-01-17", "%a, %Y-%m-%d") # works - !?
Clearly, at least one of these strings specifies the wrong weekday, but Ruby happily ignores that.
显然,这些字符串中至少有一个指定了错误的工作日,但 Ruby 很高兴地忽略了这一点。
Here's a method that doesn't; it validates that date.strftime(format)converts back to the same input string that it parsed with Date.strptimeaccording to format.
这是一个没有的方法;它验证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
回答by MrFox
Try regex for all dates:
为所有日期尝试正则表达式:
/(\d{1,2}[-\/]\d{1,2}[-\/]\d{4})|(\d{4}[-\/]\d{1,2}[-\/]\d{1,2})/.match("31-02-2010")
For only your format with leading zeroes, year last and dashes:
仅适用于带有前导零、最后一年和破折号的格式:
/(\d{2}-\d{2}-\d{4})/.match("31-02-2010")
the [-/] means either - or /, the forward slash must be escaped. You can test this on http://gskinner.com/RegExr/
[-/] 表示 - 或 /,必须对正斜杠进行转义。您可以在http://gskinner.com/RegExr/ 上对此进行测试
add the following lines, they will all be highlighted if you use the first regex, without the first and last / (they are for use in ruby code).
添加以下几行,如果您使用第一个正则表达式,它们将全部突出显示,而没有第一个和最后一个 /(它们用于 ruby 代码)。
2004-02-01
2004/02/01
01-02-2004
1-2-2004
2004-2-1
回答by Dave Sanders
Posting this because it might be of use to someone later. No clue if this is a "good" way to do it or not, but it works for me and is extendible.
发布这个是因为它可能对以后的人有用。不知道这是否是一种“好”的方法,但它对我有用并且可以扩展。
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
This add-on for String class lets you specify your list of delimiters in line 4 and then your list of valid formats in line 5. Not rocket science, but makes it really easy to extend and lets you simply check a string like so:
这个 String 类的附加组件允许您在第 4 行中指定分隔符列表,然后在第 5 行中指定有效格式列表。 不是火箭科学,但使其非常容易扩展,并让您只需检查字符串,如下所示:
"test".is_date?
"10-12-2010".is_date?
params[:some_field].is_date?
etc.

