date_molder 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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