Module: FmRest::V1::Dates

Included in:
FmRest::V1
Defined in:
lib/fmrest/v1/dates.rb

Constant Summary collapse

FM_DATE_FORMAT =
"%m/%d/%Y"
FM_DATETIME_FORMAT =
"#{FM_DATE_FORMAT} %H:%M:%S"
FM_DATETIME_FORMAT_MATCHER =
/MM|mm|dd|HH|ss|yyyy/.freeze
FM_DATE_TO_STRPTIME_SUBSTITUTIONS =
{
  "MM"   => "%m",
  "dd"   => "%d",
  "yyyy" => "%Y",
  "HH"   => "%H",
  "mm"   => "%M",
  "ss"   => "%S"
}.freeze
FM_DATE_TO_REGEXP_SUBSTITUTIONS =
{
  "MM"   => '(?:0[1-9]|1[012])',
  "dd"   => '(?:0[1-9]|[12][0-9]|3[01])',
  "yyyy" => '\d{4}',
  "HH"   => '(?:[01]\d|2[0123])',
  "mm"   => '[0-5]\d',
  "ss"   => '[0-5]\d'
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(mod) ⇒ Object



28
29
30
31
32
33
# File 'lib/fmrest/v1/dates.rb', line 28

def self.extended(mod)
  mod.instance_eval do
    @date_strptime = {}
    @date_regexp = {}
  end
end

Instance Method Details

#convert_datetime_timezone(dt, timezone) ⇒ DateTime

Converts the given DateTime dt to the specified timezone setting offset, leaving everything else intact.

Parameters:

  • dt (DateTime)

    The datetime to convert

  • timezone (nil, Symbol, String)

    Accepted values are :utc, :local, or nil (in which case it leaves the given datetime intact)

Returns:

  • (DateTime)

    A new datetime with converted timezone



105
106
107
108
109
110
111
112
113
114
# File 'lib/fmrest/v1/dates.rb', line 105

def convert_datetime_timezone(dt, timezone)
  case timezone
  when :utc, "utc"
    dt.new_offset(0)
  when :local, "local"
    dt.new_offset(FmRest::V1.local_offset_for_datetime(dt))
  when nil
    dt
  end
end

#date_classesObject

Returns a list of all date classes recognized by fmrest-ruby, including FmRest::StringDate if defined. Useful for using in a case .. when statement.



94
95
96
# File 'lib/fmrest/v1/dates.rb', line 94

def date_classes
  [Date, defined?(FmRest::StringDate) && FmRest::StringDate].compact.freeze
end

#datetime_classesObject

Returns a list of all datetime classes recognized by fmrest-ruby, including FmRest::StringDateTime if defined. Useful for using in a case .. when statement.



86
87
88
# File 'lib/fmrest/v1/dates.rb', line 86

def datetime_classes
  [DateTime, Time, defined?(FmRest::StringDateTime) && FmRest::StringDateTime].compact.freeze
end

#fm_date_to_regexp(fm_format) ⇒ Regexp

Converts a FM date-time format to a Regexp. This is mostly used a quicker way of checking whether a FM field is a date field than Date|DateTime.strptime

Parameters:

  • fm_format (String)

    The FileMaker date-time format

Returns:

  • (Regexp)

    A reegular expression matching strings in the given FM date-time format



52
53
54
55
# File 'lib/fmrest/v1/dates.rb', line 52

def fm_date_to_regexp(fm_format)
  @date_regexp[fm_format] ||= 
    Regexp.new('\A' + fm_format.gsub(FM_DATETIME_FORMAT_MATCHER, FM_DATE_TO_REGEXP_SUBSTITUTIONS) + '\Z').freeze
end

#fm_date_to_strptime_format(fm_format) ⇒ String

Converts a FM date-time format to DateTime.strptime format

Parameters:

  • fm_format (String)

    The FileMaker date-time format

Returns:

  • (String)

    The DateTime.strpdate equivalent of the given FM date-time format



40
41
42
43
# File 'lib/fmrest/v1/dates.rb', line 40

def fm_date_to_strptime_format(fm_format)
  @date_strptime[fm_format] ||=
    fm_format.gsub(FM_DATETIME_FORMAT_MATCHER, FM_DATE_TO_STRPTIME_SUBSTITUTIONS).freeze
end

#local_offset_for_datetime(dt, zone = nil) ⇒ Rational

Takes a DateTime dt, and returns the correct local offset for that dt, daylight savings included, in fraction of a day.

By default, if ActiveSupport's Time.zone is set it will be used instead of the system timezone.

Parameters:

  • dt (DateTime)

    The DateTime to get the offset for

  • zone (nil, String, TimeZone) (defaults to: nil)

    The timezone to use to calculate the offset (defaults to system timezone, or ActiveSupport's Time.zone if set)

Returns:

  • (Rational)

    The offset in fraction of a day



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fmrest/v1/dates.rb', line 68

def local_offset_for_datetime(dt, zone = nil)
  dt = dt.new_offset(0)
  time = ::Time.utc(dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec)

  # Do we have ActiveSupport's TimeZone?
  time = if time.respond_to?(:in_time_zone)
    time.in_time_zone(zone || ::Time.zone)
  else
    time.localtime
  end

  Rational(time.utc_offset, 86400) # seconds in one day (24*60*60)
end