kronic 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +2 -0
- data/README.rdoc +24 -0
- data/lib/kronic.rb +58 -0
- data/spec/kronic_spec.rb +41 -0
- data/spec/spec_helper.rb +5 -0
- metadata +80 -0
data/HISTORY
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
= Kronic
|
2
|
+
|
3
|
+
A dirt simple library for parsing human readable dates (Today, Yesterday, Last Monday).
|
4
|
+
|
5
|
+
== Why not Chronic or Tickle
|
6
|
+
|
7
|
+
Chronic and Tickle both parse a *heap* of formats. That's not useful to me when they fail on cases I want (14 Sep), and also not useful because I don't need times or spans. I just want to replace my calendar picker.
|
8
|
+
|
9
|
+
In addition, Kronic can take a date and give you a human readable form, neither of which Chronic nor Tickle does.
|
10
|
+
|
11
|
+
Oh yeah, Kronic is less than 60 lines of code.
|
12
|
+
|
13
|
+
== Usage
|
14
|
+
|
15
|
+
gem install kronic
|
16
|
+
|
17
|
+
Kronic.parse("Today") # => Date.today
|
18
|
+
Kronic.format(Date.today) # => "Today"
|
19
|
+
|
20
|
+
See the specs for all the supported formats (there are not many).
|
21
|
+
|
22
|
+
== Future
|
23
|
+
|
24
|
+
I only need date selection in the past for my application, so Kronic only does that so far. I'm not opposed to support "next monday", patches welcome. Kronic will be totally timezone aware. It may or may not be now, I haven't specced it.
|
data/lib/kronic.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'active_support/duration'
|
3
|
+
require 'active_support/time_with_zone'
|
4
|
+
|
5
|
+
class Kronic
|
6
|
+
def self.parse(string)
|
7
|
+
string = string.downcase
|
8
|
+
today = Date.today
|
9
|
+
|
10
|
+
return Date.today if string == 'today'
|
11
|
+
return Date.yesterday if string == 'yesterday'
|
12
|
+
|
13
|
+
tokens = string.split(/\s+/)
|
14
|
+
|
15
|
+
if tokens[0] == 'last'
|
16
|
+
days = (1..7).map {|x|
|
17
|
+
(Date.today - x.days)
|
18
|
+
}.inject({}) {|a, x|
|
19
|
+
a.update(x.strftime("%A").downcase => x)
|
20
|
+
}
|
21
|
+
return days[tokens[1]]
|
22
|
+
end
|
23
|
+
|
24
|
+
if tokens[0] =~ /^[0-9]+$/
|
25
|
+
|
26
|
+
day = tokens[0].to_i
|
27
|
+
month = month_from_name(tokens[1])
|
28
|
+
year = tokens[2] ? tokens[2].to_i : today.year
|
29
|
+
|
30
|
+
return nil unless month
|
31
|
+
|
32
|
+
result = Date.new(year, month, day)
|
33
|
+
result -= 1.year if result > Date.today
|
34
|
+
return result
|
35
|
+
end
|
36
|
+
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.month_from_name(month)
|
41
|
+
months = (1..12).map {|x|
|
42
|
+
Date.new(2010, x, 1)
|
43
|
+
}.inject({}) {|a, x|
|
44
|
+
a.update(x.strftime("%B").downcase => x.month)
|
45
|
+
}
|
46
|
+
|
47
|
+
months[month] || months.detect {|name, number| name.starts_with?(month) }.last
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.format(date, opts = {})
|
51
|
+
case ((opts[:today] || Date.today).to_date - date.to_date).to_i
|
52
|
+
when 0 then "Today"
|
53
|
+
when 1 then "Yesterday"
|
54
|
+
when (2..7) then "Last " + date.strftime("%A")
|
55
|
+
else date.strftime("%e %B %Y").strip
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/kronic_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kronic do
|
4
|
+
def self.should_parse(string, date)
|
5
|
+
it "should parse '#{string}'" do
|
6
|
+
Kronic.parse(string).should == date
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.should_format(string, date)
|
11
|
+
it "should format '#{string}'" do
|
12
|
+
Kronic.format(date).should == string
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.date(key)
|
17
|
+
{
|
18
|
+
:today => Date.new(2010, 9, 19),
|
19
|
+
:monday => Date.new(2010, 9, 13),
|
20
|
+
:sep_4 => Date.new(2010, 9, 4)
|
21
|
+
}.fetch(key)
|
22
|
+
end
|
23
|
+
|
24
|
+
before :all do
|
25
|
+
Timecop.freeze(Date.new(2010, 9, 19))
|
26
|
+
end
|
27
|
+
|
28
|
+
should_parse('Today', date(:today))
|
29
|
+
should_parse('today', date(:today))
|
30
|
+
should_parse('Yesterday', date(:today) - 1.day)
|
31
|
+
should_parse('Last Monday', date(:monday))
|
32
|
+
should_parse('4 Sep', date(:sep_4))
|
33
|
+
should_parse('4 September', date(:sep_4))
|
34
|
+
should_parse('14 Sep 2008', Date.new(2008, 9, 14))
|
35
|
+
should_parse('bogus', nil)
|
36
|
+
|
37
|
+
should_format('Today', date(:today))
|
38
|
+
should_format('Yesterday', date(:today) - 1.day)
|
39
|
+
should_format('Last Monday', date(:monday))
|
40
|
+
should_format('14 September 2008', Date.new(2008, 9, 14))
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kronic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Xavier Shay
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-09-19 00:00:00 +01:00
|
17
|
+
default_executable:
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: activesupport
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description:
|
33
|
+
email:
|
34
|
+
- hello@xaviershay.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- spec/kronic_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
- lib/kronic.rb
|
45
|
+
- README.rdoc
|
46
|
+
- HISTORY
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/xaviershay/kronic
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.7
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: A dirt simple library for parsing human readable dates
|
79
|
+
test_files: []
|
80
|
+
|