⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.rb

📁 A Hotel Management System based on Ruby on Rails.
💻 RB
字号:
module ActiveRecord
  module Validations
    module DateTime
      module Parser
        class DateParseError < StandardError #:nodoc:
        end
        class TimeParseError < StandardError #:nodoc:
        end
        class DateTimeParseError < StandardError #:nodoc:
        end
        
        class << self
          def parse_date(value)
            raise if value.blank?
            return value if value.is_a?(Date)
            return value.to_date if value.is_a?(Time)
            raise unless value.is_a?(String)
            
            year, month, day = case value.strip
              # 22/1/06, 22\1\06 or 22.1.06
              when /\A(\d{1,2})[\\\/\.-](\d{1,2})[\\\/\.-](\d{2}|\d{4})\Z/
                ActiveRecord::Validations::DateTime.us_date_format ? [$3, $1, $2] : [$3, $2, $1]
              # 22 Feb 06 or 1 jun 2001
              when /\A(\d{1,2}) (\w{3,9}) (\d{2}|\d{4})\Z/
                [$3, $2, $1]
              # July 1 2005
              when /\A(\w{3,9}) (\d{1,2}) (\d{2}|\d{4})\Z/
                [$3, $1, $2]
              # 2006-01-01
              when /\A(\d{4})-(\d{2})-(\d{2})\Z/
                [$1, $2, $3]
              # Not a valid date string
              else raise
            end
            
            Date.new(unambiguous_year(year), month_index(month), day.to_i)
          rescue
            raise DateParseError
          end
          
          def parse_time(value)
            raise if value.blank?
            return value if value.is_a?(Time)
            return value.to_time if value.is_a?(Date)
            raise unless value.is_a?(String)
            
            hour, minute, second = case value.strip
              # 12 hour with minute: 7.30pm, 11:20am, 2 20PM
              when /\A(\d{1,2})[\. :](\d{2})\s?(am|pm)\Z/i
                [full_hour($1, $3), $2]
              # 12 hour without minute: 2pm, 11Am, 7 pm
              when /\A(\d{1,2})\s?(am|pm)\Z/i
                [full_hour($1, $2)]
              # 24 hour: 22:30, 03.10, 12 30
              when /\A(\d{2})[\. :](\d{2})([\. :](\d{2}))?\Z/
                [$1, $2, $4]
              # Not a valid time string
              else raise
            end
            
            Time.send(ActiveRecord::Base.default_timezone, 2000, 1, 1, hour.to_i, minute.to_i, second.to_i)
          rescue
            raise TimeParseError
          end
          
          def parse_date_time(value)            raise if value.blank?
            return value if value.is_a?(Time)
            return value.to_time if value.is_a?(Date)
            raise unless value.is_a?(String)
            
            value = value.strip
            
            # The basic approach is to attempt to parse a date from the front of the string, splitting on spaces.
            # Once a date has been parsed, a time is extracted from the rest of the string.
            split_index = 0
            until false do
              split_index = value.index(' ', split_index == 0 ? 0 : split_index + 1)
              break if !split_index or (date = parse_date(value[0..split_index]) rescue nil)
            end
            
            time = parse_time(value[split_index + 1..value.size]) if split_index
            
            Time.send(ActiveRecord::Base.default_timezone, date.year, date.month, date.day, time.hour, time.min, time.sec)
          rescue
            raise DateTimeParseError
          end
          
          def full_hour(hour, meridian)
            hour = hour.to_i            if meridian.strip.downcase == 'am'
              hour == 12 ? 0 : hour
            else
              hour == 12 ? hour : hour + 12
            end          end
          
          def month_index(month)
            return month.to_i if month.to_i.nonzero?
            Date::ABBR_MONTHNAMES.index(month.capitalize) || Date::MONTHNAMES.index(month.capitalize)
          end
          
          # Extract a 4-digit year from a 2-digit year.
          # If the number is less than 20, assume year 20#{number}
          # otherwise use 19#{number}. Ignore if already 4 digits.
          #
          # Eg:
          #    10 => 2010, 60 => 1960, 00 => 2000, 1963 => 1963
          def unambiguous_year(year)
            year = "#{year.to_i < 20 ? '20' : '19'}#{year}" if year.length == 2
            year.to_i
          end
        end
      end
    end
  end
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -