From ebcd8306938d46b8053d295299462e080be839f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?=
Date to String in ordinal US style
+Format a date to ordinal, US, short format.
+
+ {% raw %}{{ site.time | date_to_string: "ordinal", "US" }}{% endraw %}
+
+ Nov 7th, 2008
+
Date to Long String
@@ -105,6 +119,20 @@ you come up with your own tags via plugins.Date to Long String in ordinal UK style
+Format a date to ordinal, UK, long format.
+
+ {% raw %}{{ site.time | date_to_long_string: "ordinal" }}{% endraw %}
+
+ 7th November 2008
+
Where
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index 686995e1..9ec8b9e9 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -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) diff --git a/lib/jekyll/filters/date_filters.rb b/lib/jekyll/filters/date_filters.rb new file mode 100644 index 00000000..40028c88 --- /dev/null +++ b/lib/jekyll/filters/date_filters.rb @@ -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 diff --git a/test/test_filters.rb b/test/test_filters.rb index bd782ea8..3bb30d65 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -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",