문자열 "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
rescue
은 권장되지 않습니다.
d, 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?
그래도 모두 가지고있는 것 같습니다 .
파싱 날짜는 특히 미국 또는 유럽에서 사용되는 짧은 날짜와 같이 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)>
01/01/2014
월과 날짜는 무엇입니까? 미국에서는 1 월이 될 것이고, 나머지 세계에서는 2 번째가 될 것입니다.
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'
모든 날짜에 정규식을 사용해보십시오.
/(\d{1,2}[-\/]\d{1,2}[-\/]\d{4})|(\d{4}[-\/]\d{1,2}[-\/]\d{1,2})/.match("31-02-2010")
선행 0, 연도 및 대시가있는 형식의 경우 :
/(\d{2}-\d{2}-\d{4})/.match("31-02-2010")
[-/]는-또는 /를 의미하며 슬래시는 이스케이프되어야합니다. http://gskinner.com/RegExr/에서 테스트 할 수 있습니다.
다음 줄을 추가하면 첫 번째 및 마지막 /없이 첫 번째 정규식을 사용하면 모두 강조 표시됩니다 (루비 코드에서 사용하기위한 것임).
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
이 예제에 대해 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
방법:
require 'date'
def is_date_valid?(d)
Date.valid_date? *"#{Date.strptime(d,"%m/%d/%Y")}".split('-').map(&:to_i) rescue nil
end
용법:
config[:dates].split(",").all? { |x| is_date_valid?(x)}
config [: dates] = "12 / 10 / 2012,05 / 09 / 1520"인 경우 true 또는 false를 반환합니다.