class Csvlint::Csvw::DateFormat

Constants

DATE_PATTERN_REGEXP
DATE_TIME_PATTERN_REGEXP
DEFAULT_REGEXP
FIELDS
TIME_PATTERN_REGEXP

Attributes

pattern[R]

Public Class Methods

new(pattern, datatype=nil) click to toggle source
# File lib/csvlint/csvw/date_format.rb, line 7
def initialize(pattern, datatype=nil)
  @pattern = pattern

  if @pattern.nil?
    @regexp = DEFAULT_REGEXP[datatype]
    @type = datatype
  else
    test_pattern = pattern.clone
    test_pattern.gsub!(/S+/, "")
    FIELDS.keys.sort_by{|f| -f.length}.each do |field|
      test_pattern.gsub!(field, "")
    end
    raise Csvw::DateFormatError, "unrecognised date field symbols in date format" if test_pattern =~ /[GyYuUrQqMLlwWdDFgEecahHKkjJmsSAzZOvVXx]/

    @regexp = DATE_PATTERN_REGEXP[@pattern]
    @type = @regexp.nil? ? "http://www.w3.org/2001/XMLSchema#time" : "http://www.w3.org/2001/XMLSchema#date"
    @regexp = @regexp || TIME_PATTERN_REGEXP[@pattern]
    @type = @regexp.nil? ? "http://www.w3.org/2001/XMLSchema#dateTime" : @type
    @regexp = @regexp || DATE_TIME_PATTERN_REGEXP[@pattern]

    if @regexp.nil?
      regexp = @pattern

      @type = "http://www.w3.org/2001/XMLSchema#date" if !(regexp =~ /HH/) && regexp =~ /yyyy/
      @type = "http://www.w3.org/2001/XMLSchema#time" if regexp =~ /HH/ && !(regexp =~ /yyyy/)
      @type = "http://www.w3.org/2001/XMLSchema#dateTime" if regexp =~ /HH/ && regexp =~ /yyyy/

      regexp = regexp.sub("HH", FIELDS["HH"].to_s)
      regexp = regexp.sub("mm", FIELDS["mm"].to_s)
      if @pattern =~ /ss\.S+/
        max_fractional_seconds = @pattern.split(".")[-1].length
        regexp = regexp.sub(/ss\.S+$/, "(?<second>#{FIELDS["ss"]}(\.[0-9]{1,#{max_fractional_seconds}})?)")
      else
        regexp = regexp.sub("ss", "(?<second>#{FIELDS["ss"]})")
      end

      if regexp =~ /yyyy/
        regexp = regexp.sub("yyyy", FIELDS["yyyy"].to_s)
        regexp = regexp.sub("MM", FIELDS["MM"].to_s)
        regexp = regexp.sub("M", FIELDS["M"].to_s)
        regexp = regexp.sub("dd", FIELDS["dd"].to_s)
        regexp = regexp.sub(/d(?=[-T \/\.])/, FIELDS["d"].to_s)
      end

      regexp = regexp.sub("XXX", FIELDS["XXX"].to_s)
      regexp = regexp.sub("XX", FIELDS["XX"].to_s)
      regexp = regexp.sub("X", FIELDS["X"].to_s)
      regexp = regexp.sub("xxx", FIELDS["xxx"].to_s)
      regexp = regexp.sub("xx", FIELDS["xx"].to_s)
      regexp = regexp.sub(/x(?!:)/, FIELDS["x"].to_s)

      @regexp = Regexp.new("^#{regexp}$")
    end
  end
end

Public Instance Methods

match(value) click to toggle source
# File lib/csvlint/csvw/date_format.rb, line 63
def match(value)
  value =~ @regexp ? true : false
end
parse(value) click to toggle source
# File lib/csvlint/csvw/date_format.rb, line 67
def parse(value)
  match = @regexp.match(value)
  return nil if match.nil?
  # STDERR.puts(@regexp)
  # STDERR.puts(value)
  # STDERR.puts(match.inspect)
  case @type
  when "http://www.w3.org/2001/XMLSchema#date"
    begin
      return Date.new(match["year"].to_i, match["month"].to_i, match["day"].to_i)
    rescue ArgumentError
      return nil
    end
  when "http://www.w3.org/2001/XMLSchema#dateTime"
    begin
      return DateTime.new(match["year"].to_i, match["month"].to_i, match["day"].to_i, match["hour"].to_i, match["minute"].to_i, (match.names.include?("second") ? match["second"].to_f : 0), match.names.include?("timezone") && match["timezone"] ? match["timezone"] : '')
    rescue ArgumentError
      return nil
    end
  else
    value = {}
    match.names.each do |field|
      unless match[field].nil?
        case field
        when "timezone"
          tz = match["timezone"]
          tz = "+00:00" if tz == 'Z'
          tz += ':00' if tz.length == 3
          tz = "#{tz[0..2]}:#{tz[3..4]}" unless tz =~ /:/
          value["timezone"] = tz
        when "second"
          value["second"] = match["second"].to_f
        else
          value[field] = match[field].to_i
        end
      end
    end
    return value
  end
end