date_molder 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # DateMolder
2
+ Generates format string for `strftime` from date string.
3
+
4
+ ## Installation
5
+
6
+ gem install date_molder
7
+
8
+ ## Usage
9
+
10
+ DateMolder.build_format("May 12, 2012, 07:34PM +0300") #=> "%B %e, %Y, %I:%M%p %z"
11
+
12
+ `DateMolder` heavily relies on `Time.parse` and `Date._parse` functions.
13
+ It means that `DateMolder` can generate format for every string that is correctly parsed by those methods.
14
+
15
+ ### Alternatives
16
+
17
+ See [Stamp](https://github.com/jeremyw/stamp) gem that serves similar purpose. However `DateMolder` has several benefits:
18
+
19
+ * parses strings like '9pm'
20
+ * supports time zones
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rake'
2
+
3
+ require File.join(File.dirname(__FILE__), "lib/version.rb")
4
+
5
+ task :build do
6
+ system "gem build date_molder.gemspec"
7
+ end
8
+
9
+ task :install => :build do
10
+ system "gem install date_molder-#{DateMolder::VERSION}.gem"
11
+ end
12
+
13
+ task :release => :build do
14
+ system "gem push date_molder-#{DateMolder::VERSION}.gem"
15
+ end
@@ -0,0 +1,56 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'date_molder')
2
+ require 'time'
3
+ require 'parser'
4
+
5
+ module DateMolder
6
+
7
+ DATE_FORMATS = {
8
+ :wday => %w{A a u w},
9
+ :year => %w{Y C y},
10
+ :mon => %w{m _m -m B ^B b ^b},
11
+ :mday => %w{e d -d j},
12
+ }
13
+
14
+ AMPM_HOUR = %w{l -l I}
15
+ SIMPLE_HOUR = %w{k -k H}
16
+
17
+ ADDITIONAL_FORMATS = {
18
+ :meridian => %w{p P},
19
+ :zone => %w{z Z}
20
+ }
21
+
22
+ extend self
23
+
24
+ def build_format(str)
25
+ formats = build_formats(str)
26
+ parser = Parser.new(str, formats)
27
+ find_solution(parser.parse)
28
+ end
29
+
30
+ private
31
+
32
+ def find_solution(solutions)
33
+ solutions.select do |format|
34
+ !/[[:digit:]]/.match(format)
35
+ end.sort_by(&:size).first
36
+ end
37
+
38
+ def build_formats(str)
39
+ time_hash = Date._parse(str)
40
+ formats = DATE_FORMATS.merge(build_time_formats(str))
41
+ formats.select! { |key, _| time_hash[key] }
42
+ formats.merge(ADDITIONAL_FORMATS)
43
+ end
44
+
45
+ def build_time_formats(str)
46
+ {
47
+ :hour => ampm_format?(str) ? AMPM_HOUR : SIMPLE_HOUR,
48
+ :min => ['M']
49
+ }
50
+ end
51
+
52
+ def ampm_format?(str)
53
+ !!/#{Time.parse(str).strftime("%p")}/i.match(str)
54
+ end
55
+
56
+ end
@@ -0,0 +1,37 @@
1
+ module DateMolder
2
+ class Parser
3
+ attr_accessor :init, :formats, :solutions, :parsed_time
4
+
5
+ def initialize(str, formats)
6
+ @str = str
7
+ @init = str.dup
8
+ @formats = formats
9
+ @solutions= []
10
+ @parsed_time = Time.parse(str)
11
+ end
12
+
13
+ def parse
14
+ parse_internal(@str, 0)
15
+ end
16
+
17
+ private
18
+
19
+ def parse_internal(str, index)
20
+ if index >= @formats.keys.size
21
+ @solutions << str if @parsed_time.strftime(str) == @init
22
+ return @solutions
23
+ end
24
+ @formats[@formats.keys[index]].each do |val|
25
+ if m = build_format_regexp(val).match(str)
26
+ parse_internal(str.sub(m[0], "%#{val}"), index + 1)
27
+ end
28
+ end
29
+ parse_internal(str, index + 1) if index + 1 <= @formats.keys.size
30
+ @solutions
31
+ end
32
+
33
+ def build_format_regexp(value)
34
+ /(#{Regexp.escape(@parsed_time.strftime("%#{value}"))})/i
35
+ end
36
+ end
37
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module DateMolder
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe DateMolder do
4
+
5
+ describe ".build_format" do
6
+
7
+ subject { DateMolder.build_format(str) }
8
+
9
+ context "simple date 1" do
10
+ let(:str) { "6 May, 2012" }
11
+ it { should == "%-d %B, %Y" }
12
+ end
13
+
14
+ context "simple date 2" do
15
+ let(:str) { "May, 06, 2012" }
16
+ it { should == "%B, %d, %Y" }
17
+ end
18
+
19
+ context "simple date 3" do
20
+ let(:str) { "JAN, 06, 2012" }
21
+ it { should == "%^b, %d, %Y" }
22
+ end
23
+
24
+ context "simple date 4" do
25
+ let(:str) { "2012 JAN 06" }
26
+ it { should == "%Y %^b %d" }
27
+ end
28
+
29
+ context "simple time in 12 clock" do
30
+ let(:str) { "12:34pm" }
31
+ it { should == "%l:%M%P" }
32
+ end
33
+
34
+ context "simple time in 24 clock" do
35
+ let(:str) { "17:34" }
36
+ it { should == "%k:%M" }
37
+ end
38
+
39
+ context "simple time in 24 clock zero-padded" do
40
+ let(:str) { "07:34" }
41
+ it { should == "%H:%M" }
42
+ end
43
+
44
+ context "simple time in 12 clock zero-padded" do
45
+ let(:str) { "07:34AM" }
46
+ it { should == "%I:%M%p" }
47
+ end
48
+
49
+ context "time without minutes" do
50
+ let(:str) { "9pm" }
51
+ it { should == "%-l%P"}
52
+ end
53
+
54
+ context "time with zone" do
55
+ let(:str) { "11:34pm +0300" }
56
+ it { should == "%l:%M%P %z"}
57
+ end
58
+
59
+ context "time with zone" do
60
+ let(:str) { "11:34pm EEST" }
61
+ it { should == "%l:%M%P %Z"}
62
+ end
63
+
64
+ context "month and day" do
65
+ let(:str) { "March, 2"}
66
+ it { should == "%B,%e" }
67
+ end
68
+
69
+ context "full date and time" do
70
+ let(:str) { "May 12, 2012, 07:34PM +0300" }
71
+ it { should == "%B %e, %Y, %I:%M%p %z" }
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require File.join(File.dirname(__FILE__), "../lib/date_molder.rb")
3
+
4
+ RSpec.configure do |c|
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: date_molder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Innokenty Mikhailov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &21122800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>'
20
+ - !ruby/object:Gem::Version
21
+ version: 2.8.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *21122800
25
+ description: Generates an strftime format using human readable date.
26
+ email: anotheroneman@yahoo.com
27
+ executables: []
28
+ extensions: []
29
+ extra_rdoc_files: []
30
+ files:
31
+ - lib/date_molder.rb
32
+ - lib/version.rb
33
+ - lib/date_molder/parser.rb
34
+ - Gemfile
35
+ - Rakefile
36
+ - README.md
37
+ - spec/spec_helper.rb
38
+ - spec/date_molder_spec.rb
39
+ homepage: https://github.com/gregolsen/date_molder
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.15
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: strftime format generator
63
+ test_files:
64
+ - spec/spec_helper.rb
65
+ - spec/date_molder_spec.rb