문자열이 유효한 날짜인지 확인하는 방법
문자열 "31-02-2010"이 있으며 유효한 날짜인지 확인하고 싶습니다. 이를 수행하는 가장 좋은 방법은 무엇입니까?
문자열이 유효한 날짜이면 true를 반환하고 그렇지 않으면 false를 반환하는 메서드가 필요합니다.
require 'date'
begin
Date.parse("31-02-2010")
rescue ArgumentError
# handle invalid date
end
d, m, y = date_string.split '-'
Date.valid_date? y.to_i, m.to_i, d.to_i
다음은 간단한 라이너입니다.
DateTime.parse date rescue nil
예를 들어 호출자가 nil을 확인하도록 강제하기 때문에 실제 생활의 모든 상황에서 정확하게 이것을 수행하는 것은 권장하지 않습니다. 특히 포맷 할 때. 기본 날짜 | 오류를 반환하면 더 친숙 할 수 있습니다.
파싱 날짜는 특히 미국 또는 유럽에서 사용되는 짧은 날짜와 같이 MM / DD / YYYY 또는 DD / MM / YYYY 형식 인 경우 일부 문제가 발생할 수 있습니다.
Date#parse 어떤 것을 사용할지 알아 내려고하지만, 형식 간의 모호함으로 인해 구문 분석 문제가 발생할 수있는 1 년 내내 한 달에 여러 날이 있습니다.
사용자의 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)>
Date.valid_date? *date_string.split('-').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)
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/
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).
2004-02-01
2004/02/01
01-02-2004
1-2-2004
2004-2-1
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:
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.
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.strptime according to 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
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:
"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
You can try the following, which is the simple way:
"31-02-2010".try(:to_date)
But you need to handle the exception.
Date.parse not raised exception for this examples:
Date.parse("12!12*2012")
=> Thu, 12 Apr 2018
Date.parse("12!12&2012")
=> Thu, 12 Apr 2018
I prefer this solution:
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
Method:
require 'date'
def is_date_valid?(d)
Date.valid_date? *"#{Date.strptime(d,"%m/%d/%Y")}".split('-').map(&:to_i) rescue nil
end
Usage:
config[:dates].split(",").all? { |x| is_date_valid?(x)}
This returns true or false if config[:dates] = "12/10/2012,05/09/1520"
참고URL : https://stackoverflow.com/questions/2955830/how-to-check-if-a-string-is-a-valid-date
'Programing' 카테고리의 다른 글
| IOUtils.toString (InputStream)에 해당하는 Guava (0) | 2020.08.12 |
|---|---|
| Windows 용 Docker 오류 : "BIOS에서 하드웨어 지원 가상화 및 데이터 실행 보호를 활성화해야합니다." (0) | 2020.08.11 |
| 단일 node.js 프로젝트의 몽구스 및 다중 데이터베이스 (0) | 2020.08.11 |
| for-in 루프에서 유형 캐스팅 (0) | 2020.08.11 |
| Rails 모델 유형 목록 (0) | 2020.08.11 |