phpf 1.0.0

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/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
+