phpf 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008 Tim Fletcher <tfletcher.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.html ADDED
@@ -0,0 +1,61 @@
1
+ <html>
2
+ <head>
3
+ <title>phpf</title>
4
+ <style type="text/css" media="screen">
5
+ html {
6
+ height: 100%;
7
+ margin-bottom: 1px;
8
+ }
9
+ body {
10
+ margin: 0;
11
+ padding: 30px;
12
+ }
13
+ h1, h2 {
14
+ font-family: Garamond, Rockwell, serif;
15
+ }
16
+ h2 {
17
+ margin-top: 1.5em;
18
+ }
19
+ code {
20
+ font-family: "Panic Sans", "Bitstream Vera Sans Mono", Consolas, Monaco, monospace;
21
+ font-size: 11px;
22
+ }
23
+ </style>
24
+ </head>
25
+ <body>
26
+
27
+
28
+ <h1>phpf <small>1.0.0</small></h1>
29
+
30
+ <p>A <a href="http://www.ruby-lang.org/">Ruby</a> port of <a href="http://www.php.net/date">PHP&rsquo;s date function</a>.</p>
31
+
32
+
33
+ <h2>HOWTO get it</h2>
34
+
35
+ <p>Use <a href="http://rubygems.org/">RubyGems</a> (<tt>gem install phpf</tt>),
36
+ or <a href="http://rubyforge.org/frs/?group_id=5524">download from RubyForge</a>.</p>
37
+
38
+
39
+ <h2>HOWTO use it</h2>
40
+
41
+ <p>Either use Time#phpf, or Kernel#date, e.g.</p>
42
+
43
+ <pre><code>require 'phpf'
44
+
45
+ time = Time.parse('1/1/2008 12:34:56')
46
+
47
+ time.phpf('jS F Y H:i') # => "1st January 2008 12:34"
48
+
49
+ time.to_i # => 1199190896
50
+
51
+ date('jS F Y H:i', 1199190896) # => "1st January 2008 12:34"
52
+ </code></pre>
53
+
54
+
55
+ <h2>See Also</h2>
56
+
57
+ <p><a href="http://simonwillison.net/2003/Oct/7/dateInPython/">PHP&rsquo;s date() function in Python</a></p>
58
+
59
+
60
+ </body>
61
+ </html>
data/Rakefile.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/gempackagetask'
4
+
5
+
6
+ GEMSPEC = Gem::Specification.new do |s|
7
+ s.name = 'phpf'
8
+ s.version = '1.0.0'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.has_rdoc = false
11
+ s.summary = "Port of PHP's date function."
12
+ s.description = s.summary
13
+ s.author = 'Tim Fletcher'
14
+ s.email = 'twoggle@gmail.com'
15
+ s.homepage = 'http://phpf.rubyforge.org/'
16
+ s.files = Dir.glob('lib/**/*') + %w( COPYING.txt Rakefile.rb README.html )
17
+ s.require_paths = ['lib']
18
+ end
19
+
20
+ Rake::GemPackageTask.new(GEMSPEC) { }
21
+
22
+ Rake::PackageTask.new(GEMSPEC.name, GEMSPEC.version) do |p|
23
+ p.need_tar_gz = true
24
+ p.package_files.include GEMSPEC.files
25
+ end
26
+
27
+ desc 'Run all the tests'
28
+ task :test do
29
+ if ARGV.length == 2 && ARGV.last =~ /SYM=(.)/
30
+ TEST_SYMBOL = $1.to_sym
31
+ end
32
+ require 'test/unit'
33
+ Test::Unit.run = false
34
+ $:.unshift 'lib'
35
+ require 'phpf/tests'
36
+ Test::Unit::AutoRunner.run
37
+ $SKIPPED_PHP_CHECKS.each do |format, version|
38
+ puts "- skipped check for %s (requires PHP %s)" % [format, version]
39
+ end
40
+ end
data/lib/phpf.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'phpf/tokenizing'
2
+ require 'phpf/evaluation'
3
+ require 'phpf/translations'
4
+ require 'time'
5
+
6
+ module PHPF
7
+ def self.format(string)
8
+ Symbol === string ? StandardFormats.const_get(string.to_s.upcase) : string
9
+ end
10
+
11
+ # cf. http://uk3.php.net/manual/en/ref.datetime.php#datetime.constants
12
+ #
13
+ # DATE_RFC822/DATE_COOKIE/DATE_RFC1123/DATE_RSS, DATE_ISO8601,
14
+ # and DATE_RFC2822 all have equivalent Ruby methods.
15
+ #
16
+ module StandardFormats
17
+ RFC850, RFC1036 = "l, d-M-y H:i:s T".freeze
18
+
19
+ RFC3339, W3C, ATOM = "Y-m-d\TH:i:sP".freeze
20
+ end
21
+ end
22
+
23
+ class Time
24
+ def self.epoch
25
+ @@epoch ||= parse('1st Jan 1970 00:00:00 UTC').freeze
26
+ end
27
+ def phpf(string)
28
+ PHPF.evaluate(PHPF.tokenize(PHPF.format(string)), self).join
29
+ end
30
+ end
31
+
32
+ class Integer
33
+ def to_time
34
+ Time.epoch + self
35
+ end
36
+ end
37
+
38
+ module Kernel
39
+ def date(format_string, time = Time.now)
40
+ time.to_i.to_time.phpf(format_string)
41
+ end
42
+ end
@@ -0,0 +1,55 @@
1
+ module PHPF
2
+ def self.evaluate(tokens, time)
3
+ tokens.map do |token|
4
+ translations.has_key?(token) ? call(translations[token], time) : token
5
+ end
6
+ end
7
+
8
+ private
9
+
10
+ def self.translate(symbol, &rule)
11
+ translations[@last_symbol = symbol] = rule
12
+ end
13
+
14
+ def self.only(php_version)
15
+ php_version_requirements[@last_symbol] = php_version
16
+ end
17
+
18
+ def self.test(time_string, expected_output)
19
+ test_cases[@last_symbol] << [time_string, expected_output]
20
+ end
21
+
22
+ def self.translations
23
+ @translations ||= {}
24
+ end
25
+
26
+ def self.call(translation, time)
27
+ translation.arity == 1 ? translation.call(time) : time.instance_eval(&translation)
28
+ end
29
+
30
+ def self.test_cases
31
+ @test_cases ||= Hash.new { |h, k| h[k] = [] }
32
+ end
33
+
34
+ def self.php_version_requirements
35
+ @php_version_requirements ||= {}
36
+ end
37
+
38
+ def self.epoch
39
+ '1st Jan 1970 00:00:00 UTC'
40
+ end
41
+
42
+ def self.ordinal(n)
43
+ return 'th' if (11..13).include?(n % 100)
44
+ case n % 10
45
+ when 1: 'st'
46
+ when 2: 'nd'
47
+ when 3: 'rd'
48
+ else 'th'
49
+ end
50
+ end
51
+
52
+ def self.date(time)
53
+ Date.new(time.year, time.month, time.mday)
54
+ end
55
+ end
data/lib/phpf/tests.rb ADDED
@@ -0,0 +1,93 @@
1
+ require 'test/unit'
2
+ require 'phpf'
3
+
4
+ $SKIPPED_PHP_CHECKS = {}
5
+
6
+ module PHPF
7
+ class Tests < Test::Unit::TestCase
8
+ class VersionString
9
+ def initialize(string)
10
+ @string = string.to_s
11
+ end
12
+ def to_s
13
+ @string
14
+ end
15
+ def <=>(v)
16
+ @string.split('.') <=> v.to_s.split('.')
17
+ end
18
+ include Comparable
19
+ end
20
+
21
+ unless defined?(PHP)
22
+ PHP = 'php'
23
+ end
24
+
25
+ PHP_VERSION = begin
26
+ (output = `#{PHP} -version`).empty? ? nil : VersionString.new(output[/(\d\.\d\.\d)/, 1])
27
+ end
28
+
29
+ def assert_expected_php_output(string, tokens, time)
30
+ php_code = 'echo date(%p, %d);' % [ PHPF.untokenize(tokens), time.to_i ]
31
+ php_output = `#{PHP} -r #{php_code.inspect}`
32
+
33
+ assert_equal string, php_output, "unexpected PHP output: from %p" % php_code
34
+ end
35
+
36
+ def required_version(tokens)
37
+ tokens.inject(nil) do |v, token|
38
+ next v unless token.is_a?(Symbol)
39
+ next v unless PHPF.php_version_requirements.has_key?(token)
40
+ version = VersionString.new(PHPF.php_version_requirements[token])
41
+ v.nil?? version : (v > version ? v : version)
42
+ end
43
+ end
44
+
45
+ def assert_evaluates_to(string, format, time_string)
46
+ tokens = case format
47
+ when String then
48
+ tokens = PHPF.tokenize(format)
49
+ assert_equal format, PHPF.untokenize(tokens)
50
+ tokens
51
+ when Symbol then [format]
52
+ when Array then format
53
+ end
54
+
55
+ time = Time.parse(time_string)
56
+
57
+ unless PHP_VERSION.nil?
58
+ if (required_version = required_version(tokens)).nil?
59
+ assert_expected_php_output string, tokens, time
60
+ elsif PHP_VERSION >= required_version
61
+ assert_expected_php_output string, tokens, time
62
+ else
63
+ $SKIPPED_PHP_CHECKS[format] = required_version
64
+ end
65
+ end
66
+
67
+ assert_equal string, PHPF.evaluate(tokens, time).to_s
68
+ end
69
+
70
+ PHPF.test_cases.each do |symbol, test_cases|
71
+ if !defined?(TEST_SYMBOL) || TEST_SYMBOL == symbol
72
+ define_method("test_evaluate_#{symbol}") do
73
+ test_cases.each do |(time_string, expected_output)|
74
+ assert_evaluates_to expected_output, symbol.to_s, time_string
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def test_php_examples # cf. http://php.net/date (Example #4)
81
+ time = Time.parse('March 10th, 2001, 5:16:18 pm')
82
+
83
+ assert_equal 'March 10, 2001, 5:16 pm', time.phpf('F j, Y, g:i a')
84
+ assert_equal '03.10.01', time.phpf('m.d.y')
85
+ assert_equal '10, 3, 2001', time.phpf('j, n, Y')
86
+ assert_equal '20010310', time.phpf('Ymd')
87
+ assert_equal '05-16-18, 10-03-01, 1631 1618 6 Satpm01', time.phpf('h-i-s, j-m-y, it is w Day')
88
+ assert_equal 'it is the 10th day.', time.phpf('\i\t \i\s \t\h\e jS \d\a\y.')
89
+ assert_equal '17:03:18 m is month', time.phpf('H:m:s \m \i\s \m\o\n\t\h')
90
+ assert_equal '17:16:18', time.phpf('H:i:s')
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,37 @@
1
+ module PHPF
2
+ FormatCharacters = 'dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU'
3
+
4
+ def self.tokenize(format_string)
5
+ tokens = []
6
+ until format_string.empty?
7
+ case format_string
8
+ when /^([#{FormatCharacters}])/
9
+ tokens << $1.to_sym
10
+ when /^\\([#{FormatCharacters}])/
11
+ tokens << $1
12
+ when /^([^\\#{FormatCharacters}]+?)(?=[\\#{FormatCharacters}])/
13
+ tokens << $1
14
+ when /^([^\\#{FormatCharacters}]+?)$/
15
+ tokens << $1
16
+ else
17
+ raise 'cannot tokenize format string: %p' % format_string
18
+ end
19
+ format_string = $'
20
+ end
21
+ return tokens
22
+ end
23
+
24
+ def self.untokenize(tokens)
25
+ tokens.map { |token| untok(token, token.to_s) }.join
26
+ end
27
+
28
+ private
29
+
30
+ def self.untok(token, string)
31
+ if Symbol === token
32
+ return string
33
+ else
34
+ FormatCharacters.include?(string) ? '\\' + string : string
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,244 @@
1
+ require 'date'
2
+
3
+ # cf. http://php.net/date
4
+ #
5
+ module PHPF
6
+
7
+ # d: Day of the month, 2 digits with leading zeros (e.g. 01 to 31)
8
+ #
9
+ translate(:d) { '%02d' % mday }
10
+ test '1st', '01'
11
+ test '23rd', '23'
12
+
13
+ # D: A textual representation of a day, three letters (e.g. Mon through Sun)
14
+ #
15
+ translate(:D) { Time::RFC2822_DAY_NAME[wday] }
16
+ test '9th Dec 2007', 'Sun'
17
+
18
+ # j: Day of the month without leading zeros (e.g. 1 to 31)
19
+ #
20
+ translate(:j) { mday }
21
+ test '1st', '1'
22
+ test '23rd', '23'
23
+
24
+ # l: A full textual representation of the day of the week
25
+ # e.g. Sunday through Saturday
26
+ #
27
+ translate(:l) { strftime('%A') }
28
+ test '9th Dec 2007', 'Sunday'
29
+
30
+ # N: ISO-8601 numeric representation of the day of the week
31
+ # e.g. 1 [for Monday] through 7 [for Sunday]
32
+ #
33
+ translate(:N) { |time| date(time).cwday }
34
+ only '5.1.0'
35
+ test '9th Dec 2007', '7'
36
+ test '10th Dec 2007', '1'
37
+
38
+ # S: English ordinal suffix for the day of the month
39
+ # e.g. st, nd, rd or th
40
+ #
41
+ translate(:S) { |time| ordinal(time.day) }
42
+ test '1st', 'st'
43
+ test '2nd', 'nd'
44
+ test '3rd', 'rd'
45
+ test '4th', 'th'
46
+
47
+ # w: Numeric representation of the day of the week
48
+ # e.g. 0 [for Sunday] through 6 [for Saturday]
49
+ #
50
+ translate(:w) { wday }
51
+ test '9th Dec 2007', '0'
52
+ test '10th Dec 2007', '1'
53
+
54
+ # z: The day of the year (starting from 0)
55
+ # e.g. 0 through 365
56
+ #
57
+ translate(:z) { yday - 1 }
58
+ test '1st Jan 2007', '0'
59
+ test '31st Dec 2007', '364'
60
+ test '31st Dec 2008', '365'
61
+
62
+ # W: ISO-8601 week number of year, weeks starting on Monday
63
+ # e.g. 42 [for the 42nd week in the year]
64
+ #
65
+ translate(:W) { |time| '%02d' % date(time).cweek }
66
+ test '24th Dec 2007 12:00', '52'
67
+ test '31st Dec 2007 12:00', '01'
68
+ test ' 1st Jan 2008 12:00', '01'
69
+ test ' 8th Jan 2008 12:00', '02'
70
+
71
+ # F: A full textual representation of a month (January through December)
72
+ #
73
+ translate(:F) { strftime('%B') }
74
+ test 'Jan', 'January'
75
+ test 'Dec', 'December'
76
+
77
+ # m: Numeric representation of a month, with leading zeros
78
+ # e.g. 01 through 12
79
+ #
80
+ translate(:m) { '%02d' % month }
81
+ test 'Jan', '01'
82
+ test 'Dec', '12'
83
+
84
+ # M: A short textual representation of a month
85
+ # e.g. Jan through Dec
86
+ #
87
+ translate(:M) { Time::RFC2822_MONTH_NAME[month - 1] }
88
+ test 'Jan', 'Jan'
89
+ test 'Dec', 'Dec'
90
+
91
+ # n: Numeric representation of a month, without leading zeros
92
+ # e.g. 1 through 12
93
+ #
94
+ translate(:n) { month }
95
+ test 'Jan', '1'
96
+ test 'Dec', '12'
97
+
98
+ # t: Number of days in the given month (28 through 31)
99
+ #
100
+ translate(:t) { |time| ((date(time) >> 1) - time.mday).day }
101
+ test 'Jan 2007', '31'
102
+ test 'Feb 2007', '28'
103
+ test 'Feb 2008', '29'
104
+
105
+ # L: 1 if it is a leap year, 0 otherwise
106
+ #
107
+ translate(:L) { Date.leap?(year) ? 1 : 0 }
108
+ test 'Jan 2007', '0'
109
+ test 'Jan 2008', '1'
110
+
111
+ # o: ISO-8601 year number. This has the same value as Y,
112
+ # except that if the ISO week number (W) belongs to the previous
113
+ # or next year, that year is used instead.
114
+ #
115
+ translate(:o) { |time| date(time).cwyear }
116
+ only '5.1.0'
117
+ test '24th Dec 2007 12:00', '2007'
118
+ test '31st Dec 2007 12:00', '2008'
119
+ test ' 1st Jan 2008 12:00', '2008'
120
+ test ' 8th Jan 2008 12:00', '2008'
121
+
122
+ # Y: A full numeric representation of a year
123
+ # e.g. 1999
124
+ #
125
+ translate(:Y) { year }
126
+ test 'Jan 1999', '1999'
127
+
128
+ # y: A two digit representation of a year
129
+ # e.g. 99 or 03
130
+ #
131
+ translate(:y) { strftime('%y') }
132
+ test 'Jan 1999', '99'
133
+
134
+ # a: Lowercase Ante meridiem and Post meridiem (am or pm)
135
+ #
136
+ translate(:a) { strftime('%p').downcase }
137
+ test '00:42', 'am'
138
+ test '12:42', 'pm'
139
+
140
+ # A: Uppercase Ante meridiem and Post meridiem (AM or PM)
141
+ #
142
+ translate(:A) { strftime('%p') }
143
+ test '00:42', 'AM'
144
+ test '12:42', 'PM'
145
+
146
+ # B: Swatch Internet time (000 through 999)
147
+ # cf. http://www.ypass.net/crap/internettime/
148
+ #
149
+ translate(:B) { '%03d' % (((utc.to_i + 3600) % 86400) / 86.4) }
150
+ test '1st Jan 2008 00:00:00 UTC', '041'
151
+
152
+ # g: 12-hour format of an hour without leading zeros (1 through 12)
153
+ #
154
+ translate(:g) { strftime('%I').to_i }
155
+ test '00:42', '12'
156
+ test '06:42', '6'
157
+ test '12:42', '12'
158
+ test '18:42', '6'
159
+
160
+ # G: 24-hour format of an hour without leading zeros (0 through 23)
161
+ #
162
+ translate(:G) { hour }
163
+ test '00:42', '0'
164
+ test '06:42', '6'
165
+ test '12:42', '12'
166
+ test '18:42', '18'
167
+
168
+ # h: 12-hour format of an hour with leading zeros (01 through 12)
169
+ #
170
+ translate(:h) { strftime('%I') }
171
+ test '00:42', '12'
172
+ test '06:42', '06'
173
+ test '12:42', '12'
174
+ test '18:42', '06'
175
+
176
+ # H: 24-hour format of an hour with leading zeros (00 through 23)
177
+ #
178
+ translate(:H) { strftime('%H') }
179
+ test '00:42', '00'
180
+ test '06:42', '06'
181
+ test '12:42', '12'
182
+ test '18:42', '18'
183
+
184
+ # i: Minutes with leading zeros (00 to 59)
185
+ #
186
+ translate(:i) { strftime('%M') }
187
+ test '00:00', '00'
188
+ test '00:12', '12'
189
+
190
+ # s: Seconds, with leading zeros (00 through 59)
191
+ #
192
+ translate(:s) { strftime('%S') }
193
+ test '00:00:00', '00'
194
+ test '00:00:12', '12'
195
+
196
+ # e: Timezone identifier
197
+ # e.g. UTC, GMT, Atlantic/Azores
198
+ #
199
+ # TODO
200
+
201
+ # O: Difference to Greenwich time (GMT) in hours
202
+ # e.g. +0200
203
+ #
204
+ # translate(:O) { '+%03d00' % (gmt_offset / 3600) }
205
+ # TODO
206
+
207
+ # P: Difference to Greenwich time (GMT) with colon between hours and minutes
208
+ # e.g. +02:00
209
+ #
210
+ # only '5.1.3'
211
+ # TODO
212
+
213
+ # T: Timezone abbreviation
214
+ # e.g. EST, MDT
215
+ #
216
+ # TODO
217
+
218
+ # Z: Timezone offset in seconds. The offset for timezones west of UTC
219
+ # is always negative, and for those east of UTC is always positive.
220
+ # e.g. -43200 through 50400
221
+ #
222
+ # TODO
223
+
224
+ # c: ISO 8601 date
225
+ # e.g. 2004-02-12T15:19:21+00:00
226
+ #
227
+ translate(:c) { iso8601.sub(/Z$/, '+00:00') }
228
+ only '5'
229
+ test '1st Jan 2008 00:00:00 UTC', '2008-01-01T00:00:00+00:00'
230
+ test '1st Jan 2008 12:34:56 PST', '2008-01-01T20:34:56+00:00'
231
+
232
+ # r: RFC 2822 formatted date
233
+ # e.g. Thu, 21 Dec 2000 16:01:07 +0200
234
+ #
235
+ translate(:r) { rfc2822 }
236
+ test '1st Jan 2008 00:00:00 GMT', 'Tue, 01 Jan 2008 00:00:00 +0000'
237
+
238
+ # U: Seconds since the Unix Epoch
239
+ #
240
+ translate(:U) { to_i }
241
+ test epoch, '0'
242
+ test '1st Jan 2008 00:00:00 UTC', '1199145600'
243
+
244
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phpf
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Fletcher
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-02-14 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Port of PHP's date function.
17
+ email: twoggle@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/phpf
26
+ - lib/phpf/evaluation.rb
27
+ - lib/phpf/tests.rb
28
+ - lib/phpf/tokenizing.rb
29
+ - lib/phpf/translations.rb
30
+ - lib/phpf.rb
31
+ - COPYING.txt
32
+ - Rakefile.rb
33
+ - README.html
34
+ has_rdoc: false
35
+ homepage: http://phpf.rubyforge.org/
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.0.1
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: Port of PHP's date function.
60
+ test_files: []
61
+