kronic 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/HISTORY +3 -0
- data/README.rdoc +1 -3
- data/lib/js/kronic.js +154 -0
- data/spec/kronic_spec.rb +1 -3
- metadata +5 -4
data/Gemfile.lock
CHANGED
data/HISTORY
CHANGED
data/README.rdoc
CHANGED
@@ -18,12 +18,10 @@ Supported formats: Today, yesterday, tomorrow, last thursday, this thursday, 14
|
|
18
18
|
|
19
19
|
Install by grabbing the latest versions direct from github:
|
20
20
|
|
21
|
-
curl http://github.com/xaviershay/kronic/raw/master/lib/js/strftime.js > public/javascripts/strftime.js
|
22
21
|
curl http://github.com/xaviershay/kronic/raw/master/lib/js/kronic.js > public/javascripts/kronic.js
|
23
22
|
|
24
23
|
Use with the following script:
|
25
24
|
|
26
|
-
<script src="/javascripts/strftime.js" type="text/javascript"></script>
|
27
25
|
<script src="/javascripts/kronic.js" type="text/javascript"></script>
|
28
26
|
<script>
|
29
27
|
Kronic.parse("Today");
|
@@ -51,7 +49,7 @@ Kronic is tested on 1.8.7, 1.9.2, Rubinius 1.1, and JRuby 1.5.1.
|
|
51
49
|
rake
|
52
50
|
open spec/kronic_spec.rb
|
53
51
|
|
54
|
-
There are comments to help you along but it is pretty basic code, so everything should make sense pretty quickly. The javascript code is a direct translation of the ruby code, and as such it is undocumented - just refer back to the ruby code.
|
52
|
+
There are comments to help you along but it is pretty basic code, so everything should make sense pretty quickly. The javascript code is a direct translation of the ruby code, and as such it is undocumented - just refer back to the ruby code.
|
55
53
|
|
56
54
|
The exact same set of specs are run again the ruby and javascript libraries, so they should be 100% compatible.
|
57
55
|
|
data/lib/js/kronic.js
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
/* This code is a direct port of the ruby code.
|
2
|
+
* See kronic.rb for explanatory remarks.
|
3
|
+
*/
|
4
|
+
var Kronic = (function() {
|
5
|
+
var DELIMITER = /[,\s]+/;
|
6
|
+
var NUMBER = /^[0-9]+$/;
|
7
|
+
var NUMBER_WITH_ORDINAL = /^([0-9]+)(st|nd|rd|th)?$/;
|
8
|
+
var ISO_8601_DATE = /^([0-9]{4})-?(1[0-2]|0?[1-9])-?(3[0-1]|[1-2][0-9]|0?[1-9])$/;
|
9
|
+
|
10
|
+
var MONTH_NAMES = ["january", "jan", "february", "feb", "march", "mar", "april", "apr", "may", "may", "june", "jun", "july", "jul", "august", "aug", "september", "sep", "october", "oct", "november", "nov", "december", "dec"];
|
11
|
+
var DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
12
|
+
|
13
|
+
function trim(string) {
|
14
|
+
return string.replace(/^\s+|\s+$/g, '');
|
15
|
+
}
|
16
|
+
|
17
|
+
function map(array, func) {
|
18
|
+
var result = [];
|
19
|
+
for (x in array) {
|
20
|
+
result.push(func(array[x]));
|
21
|
+
}
|
22
|
+
return result;
|
23
|
+
}
|
24
|
+
|
25
|
+
function inject(array, initialValue, func) {
|
26
|
+
var accumulator = initialValue;
|
27
|
+
for (x in array) {
|
28
|
+
accumulator = func(accumulator, array[x]);
|
29
|
+
}
|
30
|
+
return accumulator;
|
31
|
+
}
|
32
|
+
|
33
|
+
function addDays(date, numberOfDays) {
|
34
|
+
return new Date(date * 1 + numberOfDays * 60 * 60 * 24 * 1000);
|
35
|
+
}
|
36
|
+
|
37
|
+
function titleize(str) {
|
38
|
+
return str.replace(/^\w/, function($0) { return $0.toUpperCase(); });
|
39
|
+
}
|
40
|
+
|
41
|
+
function parseNearbyDays(string, today) {
|
42
|
+
if (string == 'today') return today;
|
43
|
+
if (string == 'yesterday') return addDays(today, -1);
|
44
|
+
if (string == 'tomorrow') return addDays(today, +1);
|
45
|
+
}
|
46
|
+
|
47
|
+
function parseLastOrThisDay(string, today) {
|
48
|
+
var tokens = string.split(DELIMITER);
|
49
|
+
|
50
|
+
if (['last', 'this'].indexOf(tokens[0]) >= 0) {
|
51
|
+
var days = map([1,2,3,4,5,6,7], function(x) {
|
52
|
+
return addDays(today, tokens[0] == 'last' ? -x : x);
|
53
|
+
});
|
54
|
+
|
55
|
+
days = inject(days, {}, function(a, x) {
|
56
|
+
a[DAY_NAMES[x.getDay()].toLowerCase()] = x;
|
57
|
+
return a;
|
58
|
+
});
|
59
|
+
|
60
|
+
return days[tokens[1]];
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
function parseExactDay(string, today) {
|
65
|
+
var tokens = string.split(DELIMITER);
|
66
|
+
if (tokens.length >= 2) {
|
67
|
+
var matches = tokens[0].match(NUMBER_WITH_ORDINAL);
|
68
|
+
if (matches) {
|
69
|
+
return parseExactDateParts(matches[1], tokens[1], tokens[2], today);
|
70
|
+
} else {
|
71
|
+
matches = tokens[1].match(NUMBER_WITH_ORDINAL);
|
72
|
+
if (matches) {
|
73
|
+
return parseExactDateParts(matches[1], tokens[0], tokens[2], today);
|
74
|
+
} else {
|
75
|
+
return null;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
function parseExactDateParts(rawDay, rawMonth, rawYear, today) {
|
82
|
+
var day = rawDay * 1;
|
83
|
+
var month = monthFromName(rawMonth);
|
84
|
+
var year;
|
85
|
+
|
86
|
+
if (rawYear)
|
87
|
+
year = rawYear.match(NUMBER) ? rawYear * 1 : null;
|
88
|
+
else
|
89
|
+
year = today.getYear() + 1900;
|
90
|
+
|
91
|
+
if (!(day && month && year))
|
92
|
+
return null;
|
93
|
+
|
94
|
+
var result = new Date(year, month, day);
|
95
|
+
if (result > today && !rawYear)
|
96
|
+
result = new Date(year - 1, month, day);
|
97
|
+
return result;
|
98
|
+
}
|
99
|
+
|
100
|
+
function parseIso8601Date(string) {
|
101
|
+
if (string.match(ISO_8601_DATE)) {
|
102
|
+
var tokens = map(string.split('-'), function(x) { return x * 1; });
|
103
|
+
return (new Date(tokens[0], tokens[1] - 1, tokens[2]));
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
function monthFromName(month) {
|
108
|
+
monthIndex = MONTH_NAMES.indexOf(month);
|
109
|
+
return monthIndex >= 0 ? Math.floor(monthIndex / 2) : null;
|
110
|
+
}
|
111
|
+
|
112
|
+
return {
|
113
|
+
parse: function(string) {
|
114
|
+
var now = Kronic.today();
|
115
|
+
|
116
|
+
string = trim(string + '').toLowerCase();
|
117
|
+
return parseNearbyDays( string, now) ||
|
118
|
+
parseLastOrThisDay(string, now) ||
|
119
|
+
parseExactDay( string, now) ||
|
120
|
+
parseIso8601Date( string);
|
121
|
+
},
|
122
|
+
format: function(date, opts) {
|
123
|
+
if (!opts)
|
124
|
+
opts = {today: Kronic.today()};
|
125
|
+
|
126
|
+
var diff = Math.floor((date * 1 - opts.today * 1) / 60 / 60 / 24 / 1000);
|
127
|
+
|
128
|
+
switch (diff) {
|
129
|
+
case -7:
|
130
|
+
case -6:
|
131
|
+
case -5:
|
132
|
+
case -4:
|
133
|
+
case -3:
|
134
|
+
case -2: return "Last " + DAY_NAMES[date.getDay()];
|
135
|
+
case -1: return "Yesterday";
|
136
|
+
case 0: return "Today";
|
137
|
+
case 1: return "Tomorrow";
|
138
|
+
case 2:
|
139
|
+
case 3:
|
140
|
+
case 4:
|
141
|
+
case 5:
|
142
|
+
case 6:
|
143
|
+
case 7: return "This " + DAY_NAMES[date.getDay()];
|
144
|
+
default:
|
145
|
+
return date.getDate() + " " +
|
146
|
+
titleize(MONTH_NAMES[date.getMonth() * 2]) + " " +
|
147
|
+
(date.getYear() + 1900);
|
148
|
+
}
|
149
|
+
},
|
150
|
+
today: function() {
|
151
|
+
return new Date();
|
152
|
+
}
|
153
|
+
};
|
154
|
+
})();
|
data/spec/kronic_spec.rb
CHANGED
@@ -10,9 +10,7 @@ describe Kronic do
|
|
10
10
|
|
11
11
|
@js = V8::Context.new
|
12
12
|
@js['alert'] = proc {|s| puts s.inspect } # For debugging, not used normally
|
13
|
-
|
14
|
-
@js.eval(File.open(File.dirname(__FILE__) + "/../lib/js/#{file}.js").read)
|
15
|
-
end
|
13
|
+
@js.eval(File.open(File.dirname(__FILE__) + "/../lib/js/kronic.js").read)
|
16
14
|
@js.eval("Kronic")['today'] = proc { date(:today).to_time }
|
17
15
|
end
|
18
16
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 1.0.0
|
9
|
+
version: 1.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Xavier Shay
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-28 00:00:00 +11:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- spec/kronic_spec.rb
|
87
87
|
- spec/spec_helper.rb
|
88
88
|
- lib/kronic.rb
|
89
|
+
- lib/js/kronic.js
|
89
90
|
- Gemfile
|
90
91
|
- Gemfile.lock
|
91
92
|
- README.rdoc
|
@@ -122,6 +123,6 @@ rubyforge_project:
|
|
122
123
|
rubygems_version: 1.3.7
|
123
124
|
signing_key:
|
124
125
|
specification_version: 3
|
125
|
-
summary: A dirt simple library for parsing human readable dates
|
126
|
+
summary: A dirt simple library for parsing and formatting human readable dates
|
126
127
|
test_files: []
|
127
128
|
|