lib/lazier/datetime.rb in lazier-1.0.7 vs lib/lazier/datetime.rb in lazier-2.0.0
- old
+ new
@@ -17,11 +17,11 @@
# @param short [Boolean] If return the abbreviated representations.
# @return [Array] Return string representations of days.
def days(short = true)
days = ::Lazier.settings.date_names[short ? :short_days : :long_days]
(1..7).to_a.collect { |i|
- {:value => i.to_s, :label=> days[i - 1]}
+ {value: i.to_s, label: days[i - 1]}
}
end
# Returns strings representations of months.
@@ -30,11 +30,11 @@
# @param short [Boolean] If return the abbreviated representations.
# @return [Array] Return string representations of months.
def months(short = true)
months = ::Lazier.settings.date_names[short ? :short_months : :long_months]
(1..12).collect { |i|
- {:value => i.to_s.rjust(2, "0"), :label=> months.at(i - 1)}
+ {value: i.to_s.rjust(2, "0"), label: months.at(i - 1)}
}
end
# Returns a range of years.
#
@@ -54,11 +54,11 @@
# @param reference [Fixnum] The ending (or middle, if `also_future` is `true`) value of the range. Defaults to the current year.
# @param as_objects [Boolean] If to return years in hashes with `:value` and `label` keys.
# @return [Array] A range of years. Every entry is
def years(offset = 10, also_future = true, reference = nil, as_objects = false)
y = reference || ::Date.today.year
- (y - offset..(also_future ? y + offset : y)).collect { |year| as_objects ? {:value => year, :label => year} : year }
+ (y - offset..(also_future ? y + offset : y)).collect { |year| as_objects ? {value: year, label: year} : year }
end
# Returns all the availabe timezones.
#
# @return [Array]All the zone available.
@@ -123,25 +123,14 @@
# @return [Date] The Easter date for the year.
def easter(year = nil)
year = ::Date.today.year if !year.is_integer?
# Compute using Anonymouse Gregorian Algorithm: http://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm
- a = year % 19
- b = (year / 100.0).floor
- c = year % 100
- d = (b / 4.0).floor
- e = b % 4
- f = ((b + 8) / 25.0).floor
- g = ((b - f + 1) / 3.0).floor
- h = ((19 * a) + b - d - g + 15) % 30
- i = (c / 4.0).floor
- k = c % 4
- l = (32 + (2 * e) + (2 * i) - h - k) % 7
- m = ((a + (11 * h) + (22 * l)) / 451.0).floor
+ a, b, c = easter_independent(year)
+ x, e, i, k = easter_dependent(b, c)
+ day, month = easter_summarize(easter_finalize(a, x, e, i, k))
- day = ((h + l - (7 * m) + 114) % 31) + 1
- month = ((h + l - (7 * m) + 114) / 31.0).floor
::Date.civil(year, month, day)
end
# Lookups a custom datetime format.
# @see Settings#setup_date_formats
@@ -169,10 +158,57 @@
rv = false
end
rv
end
+
+ private
+ # Part one of Easter calculation.
+ #
+ # @param year [Fixnum] The year to compute the date for.
+ # @return [Array] Partial variables for calculus.
+ def easter_independent(year)
+ [year % 19, (year / 100.0).floor, year % 100]
+ end
+
+ # Part two of Easter calculation.
+ #
+ # @param b [Fixnum] Variable from #easter_independent.
+ # @param c [Fixnum] Variable from #easter_independent.
+ # @return [Array] Partial variables for calculus.
+ def easter_dependent(b, c)
+ [
+ b - (b / 4.0).floor - ((b - ((b + 8) / 25.0).floor + 1) / 3.0).floor,
+ b % 4,
+ (c / 4.0).floor,
+ c % 4
+ ]
+ end
+
+ # Part three of Easter calculation.
+ #
+ # @param a [Fixnum] Variable from #easter_independent.
+ # @param x [Fixnum] Variable from #easter_independent.
+ # @param e [Fixnum] Variable from #easter_dependent.
+ # @param i [Fixnum] Variable from #easter_dependent.
+ # @param k [Fixnum] Variable from #easter_dependent.
+ # @return [Array] Partial variables for calculus.
+ def easter_finalize(a, x, e, i, k)
+ h = ((19 * a) + x + 15) % 30
+ l = (32 + (2 * e) + (2 * i) - h - k) % 7
+
+ [h, l, ((a + (11 * h) + (22 * l)) / 451.0).floor]
+ end
+
+ # Final part of Easter calculation.
+ #
+ # @param prev [Fixnum] Variable from #easter_finalize.
+ # @return [Array] Day and month of Easter daye.
+ def easter_summarize(prev)
+ h, l, m = prev
+ [((h + l - (7 * m) + 114) % 31) + 1, ((h + l - (7 * m) + 114) / 31.0).floor]
+ end
end
# Returns the UTC::Time representation of the current datetime.
#
# @return [UTC::Time] The UTC::Time representation of the current datetime.
@@ -208,36 +244,12 @@
# @param format [String] A format or a custom format name to use for formatting.
# @return [String] The formatted date.
def lstrftime(format = nil)
rv = nil
names = ::Lazier.settings.date_names
-
- final_format = ::DateTime.custom_format(format).ensure_string.gsub(/(%{1,2}:?[abz])/i) do |match|
- mrv = match
-
- # Handling of %z is to fix ruby 1.8 bug in OSX: http://bugs.ruby-lang.org/issues/2396
- if match !~ /^%%/ then
- case match
- when "%a"
- mrv = names[:short_days][self.wday]
- when "%A"
- mrv = names[:long_days][self.wday]
- when "%b"
- mrv = names[:short_months][self.month - 1]
- when "%B"
- mrv = names[:long_months][self.month - 1]
- when "%z"
- mrv = ::Lazier.is_ruby_18? ? self.formatted_offset(false) : nil
- when "%:z"
- mrv = ::Lazier.is_ruby_18? ? self.formatted_offset(true) : nil
- end
- end
-
- mrv ? mrv.sub("%", "%%") : match
- end
-
- self.strftime(final_format)
+ substitutions = {"%a" => names[:short_days][self.wday], "%A" => names[:long_days][self.wday], "%b" => names[:short_months][self.month - 1], "%B" => names[:long_months][self.month - 1]}
+ self.strftime(::DateTime.custom_format(format).ensure_string.gsub(/(?<!%)(%[ab])/i) {|mo| substitutions[mo] })
end
# Formats a datetime in the current timezone.
#
# @param format [String] The format to use for formatting.
@@ -303,27 +315,17 @@
# @param with_dst [Boolean] If include DST version of the zones.
# @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
# @return [Array] A list of names of timezones.
def list_all(with_dst = true, dst_label = nil)
dst_label ||= "(DST)"
- dst_key = "DST-#{dst_label}"
+
@zones_names ||= { "STANDARD" => ::ActiveSupport::TimeZone.all.collect(&:to_s) }
+ @zones_names["DST[#{dst_label}]-STANDARD"] ||= ::ActiveSupport::TimeZone.all.collect { |zone|
+ zone.aliases.collect { |zone_alias| [zone.to_str(zone_alias), (zone.uses_dst? && zone_alias !~ /(#{Regexp.quote(dst_label)})$/) ? zone.to_str_with_dst(dst_label, nil, zone_alias) : nil] }
+ }.flatten.compact.uniq.sort { |a,b| ::ActiveSupport::TimeZone.compare(a, b) } # Sort by name
- if with_dst && @zones_names[dst_key].blank? then
- @zones_names[dst_key] = []
-
- ::ActiveSupport::TimeZone.all.each do |zone|
- zone.aliases.each do |zone_alias|
- @zones_names[dst_key] << zone.to_str(zone_alias)
- @zones_names[dst_key] << zone.to_str_with_dst(dst_label, nil, zone_alias) if zone.uses_dst? && zone_alias !~ /(#{Regexp.quote(dst_label)})$/
- end
- end
-
- @zones_names[dst_key]= @zones_names[dst_key].uniq.compact.sort { |a,b| ::ActiveSupport::TimeZone.compare(a, b) } # Sort by name
- end
-
- @zones_names[with_dst ? dst_key : "STANDARD"]
+ @zones_names["#{with_dst ? "DST[#{dst_label}]-" : ""}STANDARD"]
end
# Returns a string representation of a timezone.
#
# ```ruby
@@ -380,36 +382,21 @@
left.ensure_string.split(" ", 2)[1] <=> right.ensure_string.split(" ", 2)[1]
end
end
# Returns a list of valid aliases (city names) for this timezone (basing on offset).
- #
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
# @return [Array] A list of aliases for this timezone
- def aliases(dst_label = nil)
- reference = self.name
- reference = self.class::MAPPING[self.name] if self.class::MAPPING.has_key?(self.name) # We are an alias
- reference = reference.gsub("_", " ")
+ def aliases
+ reference = self.class::MAPPING.fetch(self.name, self.name).gsub("_", " ")
- if @aliases.blank? then
- # First we search for aliases by name
- @aliases = [reference]
-
- self.class::MAPPING.each do |name, zone|
- if zone.gsub("_", " ") == reference then
- if name == "International Date Line West" || name == "UTC" || name.include?("(US & Canada)")
- @aliases << name
- else
- @aliases << reference.gsub(/\/.*/, "/" + name)
- end
- end
+ @aliases ||= ([reference] + self.class::MAPPING.collect { |name, zone|
+ if zone.gsub("_", " ") == reference then
+ (["International Date Line West", "UTC"].include?(name) || name.include?("(US & Canada)")) ? name : reference.gsub(/\/.*/, "/#{name}")
+ else
+ nil
end
-
- @aliases = @aliases.uniq.compact.sort
- end
-
- @aliases
+ }).uniq.compact.sort
end
# Returns the current offset for this timezone, taking care of Daylight Saving Time (DST).
#
# @param rational [Boolean] If to return the offset as a Rational.
@@ -477,22 +464,21 @@
#
# @param rational [Boolean] If to return the offset as a Rational.
# @param year [Fixnum] The year to which refer to. Defaults to the current year.
# @return [Fixnum|Rational] The correction for dst.
def dst_correction(rational = false, year = nil)
- period = self.dst_period(year)
- rv = period ? period.std_offset : 0
- rational ? self.class.rationalize_offset(rv) : rv
+ self.dst_offset(rational, year, :std_offset)
end
# Returns the standard offset for this timezone timezone when the Daylight Saving Time (DST) is active.
#
# @param rational [Boolean] If to return the offset as a Rational.
# @param year [Fixnum] The year to which refer to. Defaults to the current year.
+ # @param method [Symbol] The method to use for getting the offset. Default is total offset from UTC.
# @return [Fixnum|Rational] The DST offset for this timezone or `0`, if the timezone doesn't use DST for that year.
- def dst_offset(rational = false, year = nil)
+ def dst_offset(rational = false, year = nil, method = :utc_total_offset)
period = self.dst_period(year)
- rv = period ? period.utc_total_offset : 0
+ rv = period ? period.send(method) : 0
rational ? self.class.rationalize_offset(rv) : rv
end
# Returns the name for this zone with Daylight Saving Time (DST) active.
#
\ No newline at end of file