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 +3 -0
- data/README.md +20 -0
- data/Rakefile +15 -0
- data/lib/date_molder.rb +56 -0
- data/lib/date_molder/parser.rb +37 -0
- data/lib/version.rb +3 -0
- data/spec/date_molder_spec.rb +76 -0
- data/spec/spec_helper.rb +6 -0
- metadata +65 -0
data/Gemfile
ADDED
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
|
data/lib/date_molder.rb
ADDED
@@ -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,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
|
data/spec/spec_helper.rb
ADDED
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
|