diff --git a/Gemfile b/Gemfile
index be1aca20f9a..d8a150527c4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -32,6 +32,8 @@ group :test do
gem "test-theme", :path => File.expand_path("test/fixtures/test-theme", __dir__)
gem "test-theme-skinny", :path => File.expand_path("test/fixtures/test-theme-skinny", __dir__)
gem "test-theme-symlink", :path => File.expand_path("test/fixtures/test-theme-symlink", __dir__)
+ gem "tzinfo", ">= 1", "< 3"
+ gem "tzinfo-data"
if RUBY_ENGINE == "jruby"
gem "http_parser.rb", "~> 0.6.0"
@@ -81,13 +83,6 @@ group :jekyll_optional_dependencies do
gem "liquid-c", "~> 4.0"
gem "yajl-ruby", "~> 1.4"
end
-
- # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
- # and associated library
- platforms :jruby, :mswin, :mingw, :x64_mingw do
- gem "tzinfo", "~> 1.2"
- gem "tzinfo-data"
- end
end
#
diff --git a/docs/_docs/installation/windows.md b/docs/_docs/installation/windows.md
index eacd92c6942..c7d77ed0fbb 100644
--- a/docs/_docs/installation/windows.md
+++ b/docs/_docs/installation/windows.md
@@ -121,22 +121,14 @@ While 'new' blogs created with Jekyll v3.4 and greater, will have the following
sites *will* have to update their `Gemfile` (and installed gems) to enable development on Windows:
```ruby
-# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
-gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
+# and associated library.
+platforms :mingw, :x64_mingw, :mswin, :jruby do
+ gem "tzinfo", ">= 1", "< 3"
+ gem "tzinfo-data"
+end
```
-
-
TZInfo 2.0 incompatibility
-
- Version 2.0 of the TZInfo library has introduced a change in how timezone offsets are calculated.
- This will result in incorrect date and time for your posts when the site is built with Jekyll 3.x on Windows.
-
-
- We therefore recommend that you lock the Timezone library to version 1.2 and above by listing
- gem 'tzinfo', '~> 1.2'
in your Gemfile
.
-
-
-
## Auto Regeneration
Jekyll uses the `listen` gem to watch for changes when the `--watch` switch is specified during a build or serve.
diff --git a/lib/jekyll/commands/new.rb b/lib/jekyll/commands/new.rb
index 150b4aa7360..f85026baf56 100644
--- a/lib/jekyll/commands/new.rb
+++ b/lib/jekyll/commands/new.rb
@@ -92,7 +92,7 @@ def gemfile_contents
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
platforms :mingw, :x64_mingw, :mswin, :jruby do
- gem "tzinfo", "~> 1.2"
+ gem "tzinfo", ">= 1", "< 3"
gem "tzinfo-data"
end
diff --git a/lib/jekyll/utils/win_tz.rb b/lib/jekyll/utils/win_tz.rb
index 9c55c42eac4..d6ffad43bd5 100644
--- a/lib/jekyll/utils/win_tz.rb
+++ b/lib/jekyll/utils/win_tz.rb
@@ -11,64 +11,35 @@ module WinTZ
# timezone - the IANA Time Zone specified in "_config.yml"
#
# Returns a string that ultimately re-defines ENV["TZ"] in Windows
- def calculate(timezone)
+ def calculate(timezone, now = Time.now)
External.require_with_graceful_fail("tzinfo") unless defined?(TZInfo)
tz = TZInfo::Timezone.get(timezone)
- difference = Time.now.to_i - tz.now.to_i
+
+ #
+ # Use period_for_utc and utc_total_offset instead of
+ # period_for and observed_utc_offset for compatibility with tzinfo v1.
+ offset = tz.period_for_utc(now.getutc).utc_total_offset
+
#
# 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.negative? ? "-" : "+"
- 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))
+ sign = offset.positive? ? "-" : "+"
+
+ rational_hours = offset.abs.to_r / 3600
+ hours = rational_hours.to_i
+ minutes = ((rational_hours - hours) * 60).to_i
+
#
- # Format the hour as a two-digit number.
- # Establish the minutes based on modulo expression.
- hh = format("%02d", :hour => absolute_hour(difference).ceil)
- mm = modulo.zero? ? "00" : "30"
+ # Format the hours and minutes as two-digit numbers.
+ time = format("%02d:%02d", :hours => hours, :minutes => minutes)
- Jekyll.logger.debug "Timezone:", "#{timezone} #{offset}#{hh}:#{mm}"
+ Jekyll.logger.debug "Timezone:", "#{timezone} #{sign}#{time}"
#
# 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
+ "WTZ#{sign}#{time}"
end
end
end
diff --git a/test/test_win_tz.rb b/test/test_win_tz.rb
new file mode 100644
index 00000000000..5e7eb896769
--- /dev/null
+++ b/test/test_win_tz.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require "helper"
+
+class TestWinTz < JekyllUnitTest
+ [["America/New_York", "WTZ+05:00"], ["Europe/Paris", "WTZ-01:00"]].each do |tz, expected|
+ should "use base offset in winter for #{tz}" do
+ result = Jekyll::Utils::WinTZ.calculate(tz, Time.utc(2021, 1, 1))
+ assert_equal expected, result
+ end
+ end
+
+ [["America/New_York", "WTZ+04:00"], ["Europe/Paris", "WTZ-02:00"]].each do |tz, expected|
+ should "apply DST in summer for #{tz}" do
+ result = Jekyll::Utils::WinTZ.calculate(tz, Time.utc(2021, 7, 1))
+ assert_equal expected, result
+ end
+ end
+
+ [["Australia/Eucla", "WTZ-08:45"], ["Pacific/Marquesas", "WTZ+09:30"]].each do |tz, expected|
+ should "handle non zero minutes for #{tz}" do
+ result = Jekyll::Utils::WinTZ.calculate(tz, Time.utc(2021, 1, 1))
+ assert_equal expected, result
+ end
+ end
+
+ should "return zero for UTC" do
+ result = Jekyll::Utils::WinTZ.calculate("UTC")
+ assert_equal "WTZ+00:00", result
+ end
+end