stamp-0.6.0/0000755000004100000410000000000012377076035012703 5ustar www-datawww-datastamp-0.6.0/Rakefile0000644000004100000410000000037012377076035014350 0ustar www-datawww-datarequire 'bundler/gem_tasks' require 'cucumber/rake/task' Cucumber::Rake::Task.new(:features) Cucumber::Rake::Task.new('features:wip', 'Run Cucumber features that are a work in progress') do |t| t.profile = 'wip' end task :default => :features stamp-0.6.0/Gemfile0000644000004100000410000000004712377076035014177 0ustar www-datawww-datasource "https://rubygems.org" gemspec stamp-0.6.0/stamp.gemspec0000644000004100000410000000144012377076035015373 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "stamp/version" Gem::Specification.new do |s| s.name = "stamp" s.version = Stamp::VERSION s.authors = ["Jeremy Weiskotten"] s.email = ["jeremy@terriblelabs.com"] s.homepage = "https://github.com/jeremyw/stamp" s.summary = %Q{Date and time formatting for humans.} s.description = %Q{Format dates and times based on human-friendly examples, not arcane strftime directives.} s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- features/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.add_development_dependency 'cucumber' s.add_development_dependency 'rake' end stamp-0.6.0/features/0000755000004100000410000000000012377076035014521 5ustar www-datawww-datastamp-0.6.0/features/step_definitions/0000755000004100000410000000000012377076035020067 5ustar www-datawww-datastamp-0.6.0/features/step_definitions/stamp_steps.rb0000644000004100000410000000156012377076035022760 0ustar www-datawww-datamodule StampStepHelpers def month(month_name) Date::MONTHNAMES.index(month_name) || Date::ABBR_MONTHNAMES.index(month_name) end end World(StampStepHelpers) Given /^the date (\w+) (\d+), (\d{4})$/ do |month_name, day, year| @target = Date.new(year.to_i, month(month_name), day.to_i) end Given /^the time (\w+) (\d+), (\d+) at (\d{2}):(\d{2}):(\d{2})$/ do |month_name, day, year, hours, minutes, seconds| @target = Time.local(year.to_i, month(month_name), day.to_i, hours.to_i, minutes.to_i, seconds.to_i) end Given /^the time zone is "(.*?)"$/ do |zone| ENV['TZ'] = zone end When /^I stamp the example "([^"]*)"$/ do |example| @stamped = @target.stamp(example) end Then /^I produce "([^"]*)"$/ do |expected| assert_equal expected.strip, @stamped.strip end When /^I call "([^"]*)" with "([^"]*)"$/ do |method, arg| @stamped = @target.send(method, arg) end stamp-0.6.0/features/stamp.feature0000644000004100000410000001302412377076035017222 0ustar www-datawww-data@stamp Feature: Stamping a date In order to format dates in a more programmer-friendly way the stamp method formats a date given a human-readable example. @date Scenario Outline: Formatting dates by example Given the date September 8, 2011 When I stamp the example "" Then I produce "" Examples: | example | output | | January | September | | Jan | Sep | | Jan 1 | Sep 8 | | Jan 01 | Sep 08 | | Jan 10 | Sep 08 | | Jan 1, 1999 | Sep 8, 2011 | | Jan 12, 1999 | Sep 08, 2011 | | 1 Jan 1999 | 8 Sep 2011 | | 1/1/1999 | 9/8/2011 | | 31/01/2013 | 08/09/2011 | | 13 January 1999 | 08 September 2011 | | Monday | Thursday | | Tue, Jan 1 | Thu, Sep 8 | | Tuesday, January 1, 1999 | Thursday, September 8, 2011 | | 01/1999 | 09/2011 | | 01/01 | 09/08 | | 01/31 | 09/08 | | 01/99 | 09/11 | | 01/01/1999 | 09/08/2011 | | 12/31/99 | 09/08/11 | | 31/12 | 08/09 | | 31/12/99 | 08/09/11 | | 31-Jan-1999 | 08-Sep-2011 | | 1999-01-01 | 2011-09-08 | | 1999-12-31 | 2011-09-08 | | DOB: 12-31-1999 | DOB: 09-08-2011 | @date Scenario Outline: Formatting dates with ordinal days Given the date When I stamp the example "" Then I produce "" Examples: | date | example | output | | Jan 1, 1999 | July 4th | January 1st | | Jan 2, 1999 | Dec 3rd | Jan 2nd | | Jan 3, 1999 | Dec 2nd | Jan 3rd | | Jan 4, 1999 | Jul 1st | Jan 4th | | Jan 5, 1999 | Dec 1st | Jan 5th | | Jan 6, 1999 | Dec 1st | Jan 6th | | Jan 7, 1999 | Dec 1st | Jan 7th | | Jan 8, 1999 | Dec 1st | Jan 8th | | Jan 9, 1999 | Dec 1st | Jan 9th | | Jan 10, 1999 | Dec 1st | Jan 10th | | Jan 11, 1999 | Dec 1st | Jan 11th | | Jan 12, 1999 | Dec 1st | Jan 12th | | Jan 13, 1999 | Dec 1st | Jan 13th | | Jan 14, 1999 | Dec 1st | Jan 14th | | Jan 20, 1999 | Dec 1st | Jan 20th | | Jan 21, 1999 | Dec 1st | Jan 21st | | Jan 22, 1999 | Dec 1st | Jan 22nd | | Jan 23, 1999 | Dec 1st | Jan 23rd | | Jan 24, 1999 | Dec 1st | Jan 24th | | Jan 1, 1999 | 4th of July | 1st of January | | Jan 1, 1999 | 4th of July, 1999 | 1st of January, 1999 | @time Scenario Outline: Formatting times by example Given the time zone is "EST" And the time February 8, 2011 at 13:31:27 When I stamp the example "" Then I produce "" Examples: | example | output | | 8:59 am | 1:31 pm | | 8:59am | 1:31pm | | 08:59 AM | 01:31 PM | | 08:59 PM | 01:31 PM | | 23:59 | 13:31 | | 8:59:59 am | 1:31:27 pm | | 08:59:59 AM | 01:31:27 PM | | 08:59:59 PM | 01:31:27 PM | | 23:59:59 | 13:31:27 | | 8:59 PST | 1:31 EST | @date @time Scenario Outline: Formatting dates and times by example Given the time September 8, 2011 at 13:31:27 When I stamp the example "" Then I produce "" Examples: | example | output | | Jan 1, 1999 8:59 am | Sep 8, 2011 1:31 pm | | 08:59 AM 1999-12-31 | 01:31 PM 2011-09-08 | | Date: Jan 1, 1999 Time: 8:59 am | Date: Sep 8, 2011 Time: 1:31 pm | Scenario: strftime directives just get passed through Given the date December 21, 2012 When I stamp the example "John Cusack was in a movie about Jan (%-m) %e, %Y, but it wasn't very good." Then I produce "John Cusack was in a movie about Dec (%-m) %e, %Y, but it wasn't very good." Scenario: Plain text just gets passed through Given the date June 1, 1926 When I stamp the example "Marilyn Monroe was born on January 9, 1999." Then I produce "Marilyn Monroe was born on June 1, 1926." Scenario Outline: Aliases for the stamp method Given the date December 9, 2011 When I call "" with "1999-01-31" Then I produce "2011-12-09" Examples: | alias | | stamp_like | | format_like | stamp-0.6.0/features/support/0000755000004100000410000000000012377076035016235 5ustar www-datawww-datastamp-0.6.0/features/support/env.rb0000644000004100000410000000053312377076035017353 0ustar www-datawww-datarequire 'bundler' begin Bundler.setup(:default, :development) rescue Bundler::BundlerError => e $stderr.puts e.message $stderr.puts "Run `bundle install` to install missing gems" exit e.status_code end $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib') require 'stamp' require 'test/unit/assertions' World(Test::Unit::Assertions) stamp-0.6.0/LICENSE.txt0000644000004100000410000000204512377076035014527 0ustar www-datawww-dataCopyright (c) 2011 Jeremy Weiskotten Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. stamp-0.6.0/.travis.yml0000644000004100000410000000012112377076035015006 0ustar www-datawww-datarvm: - 1.8.7 - 1.9.2 - 1.9.3 - 2.0.0 - 2.1.2 - ree - rbx - jruby stamp-0.6.0/lib/0000755000004100000410000000000012377076035013451 5ustar www-datawww-datastamp-0.6.0/lib/stamp.rb0000644000004100000410000000252412377076035015125 0ustar www-datawww-datarequire "date" require "time" require "stamp/emitters/modifiable" require "stamp/emitters/am_pm" require "stamp/emitters/ambiguous" require "stamp/emitters/composite" require "stamp/emitters/delegate" require "stamp/emitters/lookup" require "stamp/emitters/ordinal" require "stamp/emitters/string" require "stamp/emitters/two_digit" require "stamp/disambiguator" require "stamp/translator" require "stamp/version" module Stamp # Formats a date/time using a human-friendly example as a template. # # @param [String] example a human-friendly date/time example # @param [Hash] options # @option options [Boolean] :memoize (true) # # @return [String] the formatted date or time # # @example # Date.new(2012, 12, 21).stamp("Jan 1, 1999") #=> "Dec 21, 2012" def stamp(example) memoize_stamp_emitters(example).format(self) end alias :stamp_like :stamp alias :format_like :stamp private # Memoizes the set of emitter objects for the given +example+ in # order to improve performance. def memoize_stamp_emitters(example) @@memoized_stamp_emitters ||= {} @@memoized_stamp_emitters[example] ||= stamp_emitters(example) end def stamp_emitters(example) emitters = Translator.new.translate(example) Disambiguator.new(emitters).disambiguate! end end Date.send(:include, ::Stamp) Time.send(:include, ::Stamp) stamp-0.6.0/lib/stamp/0000755000004100000410000000000012377076035014575 5ustar www-datawww-datastamp-0.6.0/lib/stamp/disambiguator.rb0000644000004100000410000000055612377076035017762 0ustar www-datawww-dataclass Disambiguator attr_reader :emitters def initialize(emitters) @emitters = emitters end def disambiguate! emitters.replace_each! do |emitter| disambiguate(emitter) end end private def disambiguate(emitter) if emitter.respond_to?(:disambiguate) emitter.disambiguate(emitters) else emitter end end end stamp-0.6.0/lib/stamp/version.rb0000644000004100000410000000004512377076035016606 0ustar www-datawww-datamodule Stamp VERSION = "0.6.0" end stamp-0.6.0/lib/stamp/emitters/0000755000004100000410000000000012377076035016431 5ustar www-datawww-datastamp-0.6.0/lib/stamp/emitters/lookup.rb0000644000004100000410000000121612377076035020267 0ustar www-datawww-datamodule Stamp module Emitters class Lookup attr_reader :field # @param [field] the field to be formatted (e.g. +:month+, +:year+) # @param [lookup] an array of the string values to be formatted (e.g. +Date::DAYNAMES+) # or a +call+able that returns the formatted value def initialize(field, lookup=nil) @field = field @lookup = lookup end def format(target) lookup(target.send(field)) end def lookup(value) if @lookup.respond_to?(:call) @lookup.call(value) else @lookup[value] end end end end endstamp-0.6.0/lib/stamp/emitters/string.rb0000644000004100000410000000046112377076035020265 0ustar www-datawww-datamodule Stamp module Emitters class String attr_reader :value def initialize(value) @value = value end def format(target) value end def <<(emitter) value << emitter.value end def field nil end end end endstamp-0.6.0/lib/stamp/emitters/am_pm.rb0000644000004100000410000000046112377076035020050 0ustar www-datawww-datamodule Stamp module Emitters class AmPm include Modifiable AM = 'am' PM = 'pm' def initialize(&block) @modifier = block end def format(target) modify(target.hour < 12 ? AM : PM) end def field nil end end end endstamp-0.6.0/lib/stamp/emitters/two_digit.rb0000644000004100000410000000076212377076035020754 0ustar www-datawww-datamodule Stamp module Emitters # Emits the given field as a two-digit number with a leading # zero if necessary. class TwoDigit include Modifiable attr_reader :field # @param [field] the field to be formatted (e.g. +:month+, +:year+) def initialize(field, &block) @field = field @modifier = block end def format(target) value = modify(target.send(field)) value < 10 ? "0#{value}" : value end end end endstamp-0.6.0/lib/stamp/emitters/composite.rb0000644000004100000410000000160612377076035020763 0ustar www-datawww-datamodule Stamp module Emitters class Composite include Enumerable attr_reader :emitters def initialize(emitters=[]) @emitters = emitters end def format(target) # NOTE using #each to build string because benchmarking shows # that it's ~20% faster than .map.join('') result = '' emitters.each { |e| result << e.format(target).to_s } result end def <<(emitter) Array(emitter).each { |e| emitters << e } end def each(&block) emitters.each(&block) end def -(others) emitters - Array(others) end # Replace each element as we iterate with the result of the given block. def replace_each! emitters.each_with_index do |emitter, index| emitters[index] = yield(emitter) end self end end end end stamp-0.6.0/lib/stamp/emitters/ambiguous.rb0000644000004100000410000000100012377076035020740 0ustar www-datawww-datamodule Stamp module Emitters class Ambiguous attr_reader :potential_emitters def initialize(*emitters) @potential_emitters = emitters end def field nil end def disambiguate(emitters) other_emitters = emitters - self known_fields = other_emitters.map { |e| e.field }.compact potential_emitters.reject do |potential_emitter| known_fields.include?(potential_emitter.field) end.first end end end end stamp-0.6.0/lib/stamp/emitters/modifiable.rb0000644000004100000410000000017112377076035021050 0ustar www-datawww-datamodule Modifiable def modify(value) if @modifier @modifier.call(value) else value end end endstamp-0.6.0/lib/stamp/emitters/delegate.rb0000644000004100000410000000054712377076035020536 0ustar www-datawww-datamodule Stamp module Emitters class Delegate include Modifiable attr_reader :field # @param [field] the field to be formatted (e.g. +:month+, +:year+) def initialize(field, &block) @field = field @modifier = block end def format(target) modify(target.send(field)) end end end endstamp-0.6.0/lib/stamp/emitters/ordinal.rb0000644000004100000410000000133312377076035020406 0ustar www-datawww-datamodule Stamp module Emitters class Ordinal attr_reader :field # @param [field] the field to be formatted (e.g. +:month+, +:year+) def initialize(field) @field = field end def format(target) ordinalize(target.send(field)) end # Cribbed from ActiveSupport::Inflector # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb def ordinalize(number) number.to_s + if (11..13).include?(number % 100) 'th' else case number % 10 when 1; 'st' when 2; 'nd' when 3; 'rd' else 'th' end end end end end endstamp-0.6.0/lib/stamp/translator.rb0000644000004100000410000001163112377076035017315 0ustar www-datawww-datamodule Stamp class Translator # Full list of time zone abbreviations from # http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations TIME_ZONE_ABBREVIATIONS = %w{ ACDT ACST ACT ADT AEDT AEST AFT AKDT AKST AMST AMT ART AST AWDT AWST AZOST AZT BDT BIOT BIT BOT BRT BST BTTCAT CCT CDT CEDT CEST CET CHADT CHAST CHOT ChST CHUT CIST CIT CKT CLST CLT COST COT CST CT CVT CWST CXT DAVT DDUT DFT EASST EAST EAT ECT EDT EEDT EEST EET EGST EGT EIT EST FET FJT FKST FKT FNT GALT GAMT GET GFT GILT GIT GMT GST GYT HADT HAEC HAST HKT HMT HOVT HST ICT IDT IOT IRDT IRKT IRST IST JST KGT KOST KRAT KST LHST LINT MAGT MART MAWT MDT MET MEST MHT MIST MIT MMT MSK MST MUT MVT MYT NCT NDT NFT NPT NST NT NUT NZDT NZST OMST ORAT PDT PET PETT PGT PHOT PHT PKT PMDT PMST PONT PST RET ROTT SAKT SAMT SAST SBT SCT SGT SLT SRT SST SYOT TAHT THA TFT TJT TKT TLT TMT TOT TVT UCT ULAT UTC UYST UYT UZT VET VLAT VOLT VOST VUT WAKT WAST WAT WEDT WEST WET WST YAKT YEKT } TIMEZONE_REGEXP = /^(#{TIME_ZONE_ABBREVIATIONS.join('|')})$/ MONTHNAMES_REGEXP = /^(#{Date::MONTHNAMES.compact.join('|')})$/i ABBR_MONTHNAMES_REGEXP = /^(#{Date::ABBR_MONTHNAMES.compact.join('|')})$/i DAYNAMES_REGEXP = /^(#{Date::DAYNAMES.join('|')})$/i ABBR_DAYNAMES_REGEXP = /^(#{Date::ABBR_DAYNAMES.join('|')})$/i ONE_DIGIT_REGEXP = /^\d{1}$/ TWO_DIGIT_REGEXP = /^\d{2}$/ FOUR_DIGIT_REGEXP = /^\d{4}$/ TIME_REGEXP = /(\d{1,2})(:)(\d{2})(\s*)(:)?(\d{2})?(\s*)?([ap]m)?/i MERIDIAN_LOWER_REGEXP = /^(a|p)m$/ MERIDIAN_UPPER_REGEXP = /^(A|P)M$/ ORDINAL_DAY_REGEXP = /^(\d{1,2})(st|nd|rd|th)$/ # Disambiguate based on value OBVIOUS_24_HOUR = 13..23 OBVIOUS_DAY = 13..31 OBVIOUS_YEAR = 32..99 TWO_DIGIT_YEAR_EMITTER = Emitters::TwoDigit.new(:year) { |year| year % 100 } TWO_DIGIT_MONTH_EMITTER = Emitters::TwoDigit.new(:month) TWO_DIGIT_DAY_EMITTER = Emitters::TwoDigit.new(:day) HOUR_TO_12_HOUR = lambda { |h| ((h - 1) % 12) + 1 } def translate(example) # extract any substrings that look like times, like "23:59" or "8:37 am" before, time_example, after = example.partition(TIME_REGEXP) # build emitters from the example date emitters = Emitters::Composite.new emitters << build_emitters(before.split(/\b/)) do |token| date_emitter(token) end # build emitters from the example time unless time_example.empty? time_parts = time_example.scan(TIME_REGEXP).first emitters << build_emitters(time_parts) do |token| time_emitter(token) end end # recursively process any remaining text emitters << translate(after) unless after.empty? emitters end # Transforms tokens that look like date/time parts to emitter objects. def build_emitters(tokens) tokens.map do |token| yield(token) || Emitters::String.new(token) end end def time_emitter(token) case token when MERIDIAN_LOWER_REGEXP Emitters::AmPm.new when MERIDIAN_UPPER_REGEXP Emitters::AmPm.new { |v| v.upcase } when TWO_DIGIT_REGEXP Emitters::Ambiguous.new( two_digit_hour_emitter(token), Emitters::TwoDigit.new(:min), Emitters::TwoDigit.new(:sec)) when ONE_DIGIT_REGEXP # 12-hour clock without leading zero Emitters::Delegate.new(:hour, &HOUR_TO_12_HOUR) end end def two_digit_hour_emitter(token) case token.to_i when OBVIOUS_24_HOUR # 24-hour clock Emitters::TwoDigit.new(:hour) else # 12-hour clock with leading zero Emitters::TwoDigit.new(:hour, &HOUR_TO_12_HOUR) end end def date_emitter(token) case token when MONTHNAMES_REGEXP Emitters::Lookup.new(:month, Date::MONTHNAMES) when ABBR_MONTHNAMES_REGEXP Emitters::Lookup.new(:month, Date::ABBR_MONTHNAMES) when DAYNAMES_REGEXP Emitters::Lookup.new(:wday, Date::DAYNAMES) when ABBR_DAYNAMES_REGEXP Emitters::Lookup.new(:wday, Date::ABBR_DAYNAMES) when TIMEZONE_REGEXP Emitters::Delegate.new(:zone) when FOUR_DIGIT_REGEXP Emitters::Delegate.new(:year) when ORDINAL_DAY_REGEXP Emitters::Ordinal.new(:day) when TWO_DIGIT_REGEXP value = token.to_i case value when OBVIOUS_DAY TWO_DIGIT_DAY_EMITTER when OBVIOUS_YEAR TWO_DIGIT_YEAR_EMITTER else Emitters::Ambiguous.new( TWO_DIGIT_MONTH_EMITTER, TWO_DIGIT_DAY_EMITTER, TWO_DIGIT_YEAR_EMITTER) end when ONE_DIGIT_REGEXP Emitters::Ambiguous.new( Emitters::Delegate.new(:month), Emitters::Delegate.new(:day)) end end end end stamp-0.6.0/cucumber.yml0000644000004100000410000000007112377076035015231 0ustar www-datawww-data--- default: --tags ~@wip --strict wip: --tags @wip --wipstamp-0.6.0/metadata.yml0000644000004100000410000000456312377076035015216 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: stamp version: !ruby/object:Gem::Version version: 0.6.0 platform: ruby authors: - Jeremy Weiskotten autorequire: bindir: bin cert_chain: [] date: 2014-08-21 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: cucumber requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' description: Format dates and times based on human-friendly examples, not arcane strftime directives. email: - jeremy@terriblelabs.com executables: [] extensions: [] extra_rdoc_files: [] files: - ".gitignore" - ".travis.yml" - ".yardopts" - CONTRIBUTING.md - Gemfile - LICENSE.txt - README.md - Rakefile - cucumber.yml - features/stamp.feature - features/step_definitions/stamp_steps.rb - features/support/env.rb - lib/stamp.rb - lib/stamp/disambiguator.rb - lib/stamp/emitters/am_pm.rb - lib/stamp/emitters/ambiguous.rb - lib/stamp/emitters/composite.rb - lib/stamp/emitters/delegate.rb - lib/stamp/emitters/lookup.rb - lib/stamp/emitters/modifiable.rb - lib/stamp/emitters/ordinal.rb - lib/stamp/emitters/string.rb - lib/stamp/emitters/two_digit.rb - lib/stamp/translator.rb - lib/stamp/version.rb - stamp.gemspec homepage: https://github.com/jeremyw/stamp licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: Date and time formatting for humans. test_files: - features/stamp.feature - features/step_definitions/stamp_steps.rb - features/support/env.rb stamp-0.6.0/.gitignore0000644000004100000410000000005512377076035014673 0ustar www-datawww-data*.gem .bundle .yardoc doc pkg/* /Gemfile.lockstamp-0.6.0/.yardopts0000644000004100000410000000002212377076035014543 0ustar www-datawww-data--markup markdown stamp-0.6.0/CONTRIBUTING.md0000644000004100000410000000137512377076035015142 0ustar www-datawww-data## Contributing to stamp * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it * Fork the project * Run `bundle install` * Run `rake` to execute the cucumber specs and make sure they all pass * Start a feature/bugfix branch * Commit and push until you are happy with your contribution * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.stamp-0.6.0/checksums.yaml.gz0000444000004100000410000000041412377076035016170 0ustar www-datawww-dataSe;R0 D"#ɶ,R08=%fvr~}XYl!+W4dtty/\XܱFdXQNp:x.^&Ц%^M%% sro(I%3wH{A "zgo4DsWr-!4Mfs f !*脁= aً欄E[u,fZ1+&rc*9x uM FНstamp-0.6.0/README.md0000644000004100000410000000650712377076035014172 0ustar www-datawww-data# stamp Format dates and times based on human-friendly examples, not arcane [strftime](http://strfti.me) directives. [![Build Status](https://secure.travis-ci.org/jeremyw/stamp.png)](http://travis-ci.org/jeremyw/stamp) ## Installation Just `gem install stamp`, or add stamp to your Gemfile and `bundle install`. ## Usage Your Ruby dates and times get a powerful new method: `stamp`. You might be concerned that "stamp" isn't descriptive enough for developers reading your code who aren't familiar with this gem. If that's the case, the following aliases are provided: * `stamp_like` * `format_like` ### Dates Give `Date#stamp` an example date string with whatever month, day, year, and weekday parts you'd like, and your date will be formatted accordingly: ```ruby date = Date.new(2011, 6, 9) date.stamp("March 1, 1999") #=> "June 9, 2011" date.stamp("Jan 1, 1999") #=> "Jun 9, 2011" date.stamp("Jan 01") #=> "Jun 09" date.stamp("Sunday, May 1, 2000") #=> "Thursday, June 9, 2011" date.stamp("Sun Aug 5") #=> "Thu Jun 9" date.stamp("12/31/99") #=> "06/09/11" date.stamp("DOB: 12/31/2000") #=> "DOB: 06/09/2011" ``` It even formats ordinal days! ```ruby date.stamp("November 5th") #=> "June 9th" date.stamp("1st of Jan") #=> "9th of Jun" ``` ### Times `Time#stamp` supports the same kinds of examples as `Date`, but also formats hours, minutes, and seconds when it sees colon-separated values. ```ruby time = Time.utc(2011, 6, 9, 20, 52, 30) time.stamp("3:00 AM") #=> "8:52 PM" time.stamp("01:00:00 AM") #=> "08:52:30 PM" time.stamp("23:59") #=> "20:52" time.stamp("23:59:59") #=> "20:52:30" time.stamp("Jan 1 at 01:00 AM") #=> "Jun 9 at 08:52 PM" time.stamp("23:59 UTC") #=> "20:52 PST" ``` ## Features * Abbreviated and full names of months and weekdays are recognized. * Days with or without a leading zero work instinctively. * Standard time zone abbreviations are recognized; e.g. "UTC", "PST", "EST". * Include any extraneous text you'd like; e.g. "DOB:". ### Disambiguation by value You can use any month, weekday, day, or year value that makes sense in your examples, and stamp can often infer your intent based on context, but there may be times that you need to use unambiguous values to make your intent more explicit. For example, "01/09" could refer to January 9, September 1, or January 2009. More explicit examples include "12/31", "31/12", and "12/99". Using unambiguous values will also help people who read the code in the future, including yourself, understand your intent. ### Rails Integration Stamp makes it easy to configure your Rails application's common date and time formats in a more self-documenting way with `DATE_FORMATS`: ```ruby # config/initializers/date_formats.rb Date::DATE_FORMATS[:short] = Proc.new { |date| date.stamp("Sun Jan 5") } Time::DATE_FORMATS[:military] = Proc.new { |time| time.stamp("5 January 23:59") } ``` To use your formats: ```ruby Date.today.to_s(:short) #=> "Sat Jul 16" Time.now.to_s(:military) #=> "16 July 15:35" ``` ### Limitations * `DateTime` should inherit stamp behavior from `Date`, but it hasn't been thoroughly tested. Patches welcome! ## Copyright Copyright (c) 2011 Jeremy Weiskotten (@doctorzaius). See LICENSE.txt for further details.