Allow date filters to output ordinal days (#6773)

Merge pull request 6773
This commit is contained in:
Ana María Martínez Gómez 2018-03-05 23:15:59 +01:00 committed by jekyllbot
parent 5b77850dc9
commit ebcd830693
4 changed files with 180 additions and 65 deletions

View File

@ -91,6 +91,20 @@ you come up with your own tags via plugins.
</p>
</td>
</tr>
<tr>
<td>
<p class="name"><strong>Date to String in ordinal US style</strong></p>
<p>Format a date to ordinal, US, short format.</p>
</td>
<td class="align-center">
<p>
<code class="filter">{% raw %}{{ site.time | date_to_string: "ordinal", "US" }}{% endraw %}</code>
</p>
<p>
<code class="output">Nov 7th, 2008</code>
</p>
</td>
</tr>
<tr>
<td>
<p class="name"><strong>Date to Long String</strong></p>
@ -105,6 +119,20 @@ you come up with your own tags via plugins.
</p>
</td>
</tr>
<tr>
<td>
<p class="name"><strong>Date to Long String in ordinal UK style</strong></p>
<p>Format a date to ordinal, UK, long format.</p>
</td>
<td class="align-center">
<p>
<code class="filter">{% raw %}{{ site.time | date_to_long_string: "ordinal" }}{% endraw %}</code>
</p>
<p>
<code class="output">7th November 2008</code>
</p>
</td>
</tr>
<tr>
<td>
<p class="name"><strong>Where</strong></p>

View File

@ -2,7 +2,6 @@
require "addressable/uri"
require "json"
require "date"
require "liquid"
require_all "jekyll/filters"
@ -11,6 +10,7 @@ module Jekyll
module Filters
include URLFilters
include GroupingFilters
include DateFilters
# Convert a Markdown string into HTML output.
#
@ -67,55 +67,6 @@ module Jekyll
Utils.slugify(input, :mode => mode)
end
# Format a date in short format e.g. "27 Jan 2011".
#
# date - the Time to format.
#
# Returns the formatting String.
def date_to_string(date)
time(date).strftime("%d %b %Y")
end
# Format a date in long format e.g. "27 January 2011".
#
# date - The Time to format.
#
# Returns the formatted String.
def date_to_long_string(date)
return date if date.to_s.empty?
time(date).strftime("%d %B %Y")
end
# Format a date for use in XML.
#
# date - The Time to format.
#
# Examples
#
# date_to_xmlschema(Time.now)
# # => "2011-04-24T20:34:46+08:00"
#
# Returns the formatted String.
def date_to_xmlschema(date)
return date if date.to_s.empty?
time(date).xmlschema
end
# Format a date according to RFC-822
#
# date - The Time to format.
#
# Examples
#
# date_to_rfc822(Time.now)
# # => "Sun, 24 Apr 2011 12:34:46 +0000"
#
# Returns the formatted String.
def date_to_rfc822(date)
return date if date.to_s.empty?
time(date).rfc822
end
# XML escape a string for use. Replaces any special characters with
# appropriate HTML entity replacements.
#
@ -357,16 +308,6 @@ module Jekyll
.map!(&:last)
end
private
def time(input)
date = Liquid::Utils.to_date(input)
unless date.respond_to?(:to_time)
raise Errors::InvalidDateError,
"Invalid Date: '#{input.inspect}' is not a valid datetime."
end
date.to_time.dup.localtime
end
private
def item_property(item, property)
if item.respond_to?(:to_liquid)

View File

@ -0,0 +1,107 @@
# frozen_string_literal: true
module Jekyll
module Filters
module DateFilters
# Format a date in short format e.g. "27 Jan 2011".
# Ordinal format is also supported, in both the UK
# (e.g. "27th Jan 2011") and US ("e.g. Jan 27th, 2011") formats.
# UK format is the default.
#
# date - the Time to format.
# type - if "ordinal" the returned String will be in ordinal format
# style - if "US" the returned String will be in US format.
# Otherwise it will be in UK format.
#
# Returns the formatting String.
def date_to_string(date, type = nil, style = nil)
stringify_date(date, "%b", type, style)
end
# Format a date in long format e.g. "27 January 2011".
# Ordinal format is also supported, in both the UK
# (e.g. "27th January 2011") and US ("e.g. January 27th, 2011") formats.
# UK format is the default.
#
# date - the Time to format.
# type - if "ordinal" the returned String will be in ordinal format
# style - if "US" the returned String will be in US format.
# Otherwise it will be in UK format.
#
# Returns the formatted String.
def date_to_long_string(date, type = nil, style = nil)
stringify_date(date, "%B", type, style)
end
# Format a date for use in XML.
#
# date - The Time to format.
#
# Examples
#
# date_to_xmlschema(Time.now)
# # => "2011-04-24T20:34:46+08:00"
#
# Returns the formatted String.
def date_to_xmlschema(date)
return date if date.to_s.empty?
time(date).xmlschema
end
# Format a date according to RFC-822
#
# date - The Time to format.
#
# Examples
#
# date_to_rfc822(Time.now)
# # => "Sun, 24 Apr 2011 12:34:46 +0000"
#
# Returns the formatted String.
def date_to_rfc822(date)
return date if date.to_s.empty?
time(date).rfc822
end
private
# month_type: Notations that evaluate to 'Month' via `Time#strftime` ("%b", "%B")
# type: nil (default) or "ordinal"
# style: nil (default) or "US"
#
# Returns a stringified date or the empty input.
def stringify_date(date, month_type, type = nil, style = nil)
return date if date.to_s.empty?
time = time(date)
if type == "ordinal"
day = time.day
ordinal_day = "#{day}#{ordinal(day)}"
return time.strftime("#{month_type} #{ordinal_day}, %Y") if style == "US"
return time.strftime("#{ordinal_day} #{month_type} %Y")
end
time.strftime("%d #{month_type} %Y")
end
private
def ordinal(number)
return "th" if (11..13).cover?(number)
case number % 10
when 1 then "st"
when 2 then "nd"
when 3 then "rd"
else "th"
end
end
private
def time(input)
date = Liquid::Utils.to_date(input)
unless date.respond_to?(:to_time)
raise Errors::InvalidDateError,
"Invalid Date: '#{input.inspect}' is not a valid datetime."
end
date.to_time.dup.localtime
end
end
end
end

View File

@ -43,7 +43,7 @@ class TestFilters < JekyllUnitTest
"baseurl" => "/base",
"dont_show_posts_before" => @sample_time,
})
@sample_date = Date.parse("2013-03-27")
@sample_date = Date.parse("2013-03-02")
@time_as_string = "September 11, 2001 12:46:30 -0000"
@time_as_numeric = 1_399_680_607
@integer_as_string = "142857"
@ -210,6 +210,16 @@ class TestFilters < JekyllUnitTest
assert_equal "27 March 2013", @filter.date_to_long_string(@sample_time)
end
should "format a date with ordinal, US format" do
assert_equal "Mar 27th, 2013",
@filter.date_to_string(@sample_time, "ordinal", "US")
end
should "format a date with long, ordinal format" do
assert_equal "27th March 2013",
@filter.date_to_long_string(@sample_time, "ordinal")
end
should "format a time with xmlschema" do
assert_equal(
"2013-03-27T11:22:33+00:00",
@ -234,23 +244,32 @@ class TestFilters < JekyllUnitTest
context "with Date object" do
should "format a date with short format" do
assert_equal "27 Mar 2013", @filter.date_to_string(@sample_date)
assert_equal "02 Mar 2013", @filter.date_to_string(@sample_date)
end
should "format a date with long format" do
assert_equal "27 March 2013", @filter.date_to_long_string(@sample_date)
assert_equal "02 March 2013", @filter.date_to_long_string(@sample_date)
end
should "format a date with ordinal format" do
assert_equal "2nd Mar 2013", @filter.date_to_string(@sample_date, "ordinal")
end
should "format a date with ordinal, US, long format" do
assert_equal "March 2nd, 2013",
@filter.date_to_long_string(@sample_date, "ordinal", "US")
end
should "format a time with xmlschema" do
assert_equal(
"2013-03-27T00:00:00+00:00",
"2013-03-02T00:00:00+00:00",
@filter.date_to_xmlschema(@sample_date)
)
end
should "format a time according to RFC-822" do
assert_equal(
"Wed, 27 Mar 2013 00:00:00 +0000",
"Sat, 02 Mar 2013 00:00:00 +0000",
@filter.date_to_rfc822(@sample_date)
)
end
@ -265,6 +284,16 @@ class TestFilters < JekyllUnitTest
assert_equal "11 September 2001", @filter.date_to_long_string(@time_as_string)
end
should "format a date with ordinal, US format" do
assert_equal "Sep 11th, 2001",
@filter.date_to_string(@time_as_string, "ordinal", "US")
end
should "format a date with ordinal long format" do
assert_equal "11th September 2001",
@filter.date_to_long_string(@time_as_string, "ordinal", "UK")
end
should "format a time with xmlschema" do
assert_equal(
"2001-09-11T12:46:30+00:00",
@ -296,6 +325,16 @@ class TestFilters < JekyllUnitTest
assert_equal "10 May 2014", @filter.date_to_long_string(@time_as_numeric)
end
should "format a date with ordinal, US format" do
assert_equal "May 10th, 2014",
@filter.date_to_string(@time_as_numeric, "ordinal", "US")
end
should "format a date with ordinal, long format" do
assert_equal "10th May 2014",
@filter.date_to_long_string(@time_as_numeric, "ordinal")
end
should "format a time with xmlschema" do
assert_match(
"2014-05-10T00:10:07",