From c4142c4c77fe227d9f3a73a349b70c42205aa41a Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Wed, 30 Nov 2016 13:52:32 +0530 Subject: [PATCH] add a utility submodule to define 'TZ' on Windows --- lib/jekyll.rb | 2 +- lib/jekyll/utils.rb | 1 + lib/jekyll/utils/win_tz.rb | 73 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 lib/jekyll/utils/win_tz.rb diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 6cfbd70f..75f6b250 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -119,7 +119,7 @@ module Jekyll # Returns nothing # rubocop:disable Style/AccessorMethodName def set_timezone(timezone) - ENV["TZ"] = timezone + ENV["TZ"] = Utils::Platforms.windows? ? Utils::WinTZ.calculate(timezone) : timezone end # rubocop:enable Style/AccessorMethodName diff --git a/lib/jekyll/utils.rb b/lib/jekyll/utils.rb index f870ea85..23bacdab 100644 --- a/lib/jekyll/utils.rb +++ b/lib/jekyll/utils.rb @@ -4,6 +4,7 @@ module Jekyll extend self autoload :Platforms, "jekyll/utils/platforms" autoload :Ansi, "jekyll/utils/ansi" + autoload :WinTZ, "jekyll/utils/win_tz" # Constants for use in #slugify SLUGIFY_MODES = %w(raw default pretty ascii).freeze diff --git a/lib/jekyll/utils/win_tz.rb b/lib/jekyll/utils/win_tz.rb new file mode 100644 index 00000000..0c2b5bd2 --- /dev/null +++ b/lib/jekyll/utils/win_tz.rb @@ -0,0 +1,73 @@ +module Jekyll + module Utils + module WinTZ + extend self + + # Public: Calculate the Timezone for Windows when the config file has a defined + # 'timezone' key. + # + # timezone - the IANA Time Zone specified in "_config.yml" + # + # Returns a string that ultimately re-defines ENV["TZ"] in Windows + def calculate(timezone) + External.require_with_graceful_fail("tzinfo") + tz = TZInfo::Timezone.get(timezone) + difference = Time.now.to_i - tz.now.to_i + # + # POSIX style definition reverses the offset sign. + # e.g. Eastern Standard Time (EST) that is 5Hrs. to the 'west' of Prime Meridian + # is denoted as: + # EST+5 (or) EST+05:00 + # Reference: http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html + sign = difference < 0 ? "-" : "+" + offset = sign == "-" ? "+" : "-" unless difference.zero? + # + # convert the difference (in seconds) to hours, as a rational number, and perform + # a modulo operation on it. + modulo = modulo_of(rational_hour(difference)) + # + # Format the hour as a two-digit number. + # Establish the minutes based on modulo expression. + hh = format("%02d", absolute_hour(difference).ceil) + mm = modulo.zero? ? "00" : "30" + + Jekyll.logger.debug "Timezone:", "#{timezone} #{offset}#{hh}:#{mm}" + # + # Note: The 3-letter-word below doesn't have a particular significance. + "WTZ#{sign}#{hh}:#{mm}" + end + + private + + # Private: Convert given seconds to an hour as a rational number. + # + # seconds - supplied as an integer, it is converted to a rational number. + # 3600 - no. of seconds in an hour. + # + # Returns a rational number. + def rational_hour(seconds) + seconds.to_r/3600 + end + + # Private: Convert given seconds to an hour as an absolute number. + # + # seconds - supplied as an integer, it is converted to its absolute. + # 3600 - no. of seconds in an hour. + # + # Returns an integer. + def absolute_hour(seconds) + seconds.abs/3600 + end + + # Private: Perform a modulo operation on a given fraction. + # + # fraction - supplied as a rational number, its numerator is divided + # by its denominator and the remainder returned. + # + # Returns an integer. + def modulo_of(fraction) + fraction.numerator % fraction.denominator + end + end + end +end