Sha256: 97d8bfa793df3f57d4c915b63f07aa01f4b7996b18b70e271284c12dae507668

Contents?: true

Size: 1.21 KB

Versions: 2

Compression:

Stored size: 1.21 KB

Contents

# frozen_string_literal: true

module ActiveFields
  module Casters
    class DateTimeCaster < BaseCaster
      MAX_PRECISION = RUBY_VERSION >= "3.2" ? 9 : 6 # AR max precision is 6 for old Rubies

      def serialize(value)
        value = value.iso8601 if value.is_a?(Date)
        casted_value = caster.serialize(value)

        casted_value.iso8601(precision) if casted_value.acts_like?(:time)
      end

      def deserialize(value)
        value = value.iso8601 if value.is_a?(Date)
        casted_value = caster.deserialize(value)

        apply_precision(casted_value).in_time_zone if casted_value.acts_like?(:time)
      end

      private

      def caster
        ActiveRecord::Type::DateTime.new
      end

      # Use maximum precision by default to prevent the caster from truncating useful time information
      # before precision is applied later
      def precision
        [options[:precision], MAX_PRECISION].compact.min
      end

      def apply_precision(value)
        number_of_insignificant_digits = 9 - precision
        round_power = 10**number_of_insignificant_digits
        rounded_off_nsec = value.nsec % round_power

        value.change(nsec: value.nsec - rounded_off_nsec)
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
active_fields-1.1.0 lib/active_fields/casters/date_time_caster.rb
active_fields-1.0.0 lib/active_fields/casters/date_time_caster.rb