parsi-date 0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in .gemspec
4
+ gemspec
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ parsi-date (0.1.pre)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rake (0.9.2.2)
11
+ rspec (2.11.0)
12
+ rspec-core (~> 2.11.0)
13
+ rspec-expectations (~> 2.11.0)
14
+ rspec-mocks (~> 2.11.0)
15
+ rspec-core (2.11.1)
16
+ rspec-expectations (2.11.3)
17
+ diff-lcs (~> 1.1.3)
18
+ rspec-mocks (2.11.3)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ bundler
25
+ parsi-date!
26
+ rake
27
+ rspec
@@ -0,0 +1,285 @@
1
+ # encoding: utf-8
2
+
3
+ require 'date'
4
+
5
+ module Parsi
6
+ MONTHNAMES = [nil] + %w(فروردین اردیبهشت خرداد تیر مرداد شهریور مهر آبان آذر دی بهمن اسفند)
7
+ ABBR_MONTHNAMES = [nil] + %w(Far Ord Kho Tir Mor Sha Meh Abn Azr Dey Bah Esf)
8
+ DAYNAMES = %w(شنده یک‌شنده دوشنده سه‌شنده چهارشنده چنج‌شنده جمعه)
9
+ ABBR_DAYNAMES = %w(ش ۱ش ۲ش ۳ش ۴ش ۵ش ج)
10
+ [MONTHNAMES, ABBR_MONTHNAMES, DAYNAMES, ABBR_DAYNAMES].each &:freeze
11
+
12
+ class Date
13
+ include Comparable
14
+
15
+ attr_reader :year, :month, :day
16
+
17
+ DAYS_TO_FIRST_OF_MONTH = [nil, 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336]
18
+ DAYS_IN_MONTH = [nil, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]
19
+ JALALI_EPOCH = 1948320.5
20
+
21
+ class << self
22
+
23
+ def leap? year
24
+ ((((((year - ((year > 0) ? 474 : 473)) % 2820) + 474) + 38) * 682) % 2816) < 682
25
+ end
26
+ alias :exist? :leap?
27
+
28
+ def valid? year, month, day
29
+ return false unless year.is_a?(Fixnum) && month.is_a?(Fixnum) && day.is_a?(Fixnum)
30
+ return true if leap?(year) && month == 12 && day == 30
31
+
32
+ 1 <= month && month <= 12 && 1 <= day && day <= DAYS_IN_MONTH[month]
33
+ end
34
+
35
+ def jd jday=0
36
+ jday = jday.floor
37
+
38
+ depoch = (jday - Date.new(475, 1, 1).jd).floor
39
+ cycle = depoch / 1029983
40
+ cyear = depoch % 1029983
41
+
42
+ if cyear == 1029982
43
+ ycycle = 2820
44
+ else
45
+ aux1 = cyear / 366
46
+ aux2 = cyear % 366
47
+ ycycle = (2134 * aux1 + 2816 * aux2 + 2815) / 1028522 + aux1 + 1
48
+ end
49
+ year = ycycle + 2820 * cycle + 474
50
+ year -= 1 if year <= 0
51
+
52
+ yday = jday - Date.new(year, 1, 1).jd + 1
53
+ month = (yday <= 186) ? (yday / 31.0).ceil : ((yday - 6) / 30.0).ceil
54
+ day = (jday - Date.new(year, month, 1).jd + 1).floor
55
+ Date.new year, month, day
56
+ end
57
+
58
+ alias :civil :new
59
+
60
+ def ordinal year, ydays=1
61
+ jd = Date.new(year, 1, 1).jd + ydays - 1
62
+ Date.jd jd
63
+ end
64
+
65
+ def parse string, comp=true
66
+ # TODO: Add more parse options, for example parse '۴ام فروردین ۱۳۹۱'
67
+ m = string.match /(?<year>\d+)(\/|-| )(?<month>\d+)(\/|-| )(?<day>\d+)/
68
+ m ||= string.match /(?<year>\d+)(?<month>\d{2})(?<day>\d{2})/
69
+ if m.nil?
70
+ raise ArgumentError.new 'invalid date'
71
+ else
72
+ year, month, day = m[:year].to_i, m[:month].to_i, m[:day].to_i
73
+ if comp && m[:year].length == 2
74
+ centry = Date.today.year / 100
75
+ year = (m[:year].prepend centry.to_s).to_i
76
+ end
77
+ if Date.valid? year, month, day
78
+ Date.new year, month, day
79
+ else
80
+ raise ArgumentError.new 'invalid date'
81
+ end
82
+ end
83
+ end
84
+
85
+ def today
86
+ Date.jd ::Date.today.jd
87
+ end
88
+
89
+ def tomorrow ; today + 1 end
90
+ def yesterday; today - 1 end
91
+ end
92
+
93
+ def initialize year=0, month=1, day=1
94
+ raise ArgumentError.new 'invalid date' unless Date.valid? year, month, day
95
+ @year, @month, @day = year, month, day
96
+ end
97
+
98
+ alias :mon :month
99
+ alias :mday :day
100
+
101
+ def to_s sep='/'
102
+ "%d%s%02d%s%02d" % [year, sep, month, sep, day]
103
+ end
104
+
105
+ def inspect
106
+ "#<#{self.class}: #{to_s('-')}>"
107
+ end
108
+
109
+ def jd
110
+ @jd ||= begin
111
+ epbase = year - ((year >= 0) ? 474 : 473)
112
+ epyear = 474 + epbase % 2820
113
+
114
+ day + DAYS_TO_FIRST_OF_MONTH[month] +
115
+ (epyear * 682 - 110) / 2816 +
116
+ (epyear - 1) * 365 +
117
+ (epbase / 2820 * 1029983) +
118
+ (JALALI_EPOCH - 1) + 0.5
119
+ end
120
+ end
121
+
122
+ def mjd ; (jd - 2400001).floor end
123
+ def ld ; (jd - 2299160).floor end
124
+ def ajd ; gregorian.ajd end
125
+ def amjd ; gregorian.amjd end
126
+
127
+ def wday
128
+ (gregorian.wday + 1) % 7
129
+ end
130
+
131
+ def cwday
132
+ wday + 1
133
+ end
134
+
135
+ def yday
136
+ (jd - first_of_year.jd + 1).to_i
137
+ end
138
+
139
+ def leap?
140
+ Date.leap? year
141
+ end
142
+
143
+ def to_gregorian
144
+ ::Date.jd jd
145
+ end
146
+ alias :gregorian :to_gregorian
147
+
148
+ def strftime format='%Y/%m/%d'
149
+ format.
150
+ gsub('%%', 'PERCENT_SUBSTITUTION_MARKER').
151
+ gsub('%+', '%a %b %e %H:%M:%S %Z %Y').
152
+ gsub('%c', '%a %-d %B %Y').
153
+ gsub('%x', '%D').
154
+ gsub('%D', '%y/%m/%d').
155
+ gsub('%F', '%Y-%m-%d').
156
+ gsub('%v', '%e-%b-%Y').
157
+ gsub('%Y', year.to_s).
158
+ gsub('%C', (year / 100).to_s).
159
+ gsub('%y', (year % 100).to_s).
160
+ gsub('%m', '%02d' % month).
161
+ gsub('%_m', '% 2d' % month).
162
+ gsub('%-m', month.to_s).
163
+ gsub('%^B', '%B').
164
+ gsub('%B', Parsi::MONTHNAMES[month]).
165
+ gsub('%h', '%b').
166
+ gsub('%b', Parsi::ABBR_MONTHNAMES[month]).
167
+ gsub('%^b', Parsi::ABBR_MONTHNAMES[month].capitalize).
168
+ gsub('%d', '%02d' % day).
169
+ gsub('%e', '% 2d' % day).
170
+ gsub('%-d', day.to_s).
171
+ gsub('%j', '%03d' % yday.to_s).
172
+ gsub('%A', Parsi::DAYNAMES[wday]).
173
+ gsub('%a', Parsi::ABBR_DAYNAMES[wday]).
174
+ gsub('%u', cwday.to_s).
175
+ gsub('%w', wday.to_s).
176
+ gsub('%n', "\n").
177
+ gsub('%t', "\t").
178
+ gsub('PERCENT_SUBSTITUTION_MARKER', '%')
179
+ end
180
+
181
+ def + days
182
+ raise TypeError.new 'expected numeric' unless days.is_a? Numeric
183
+ Date.jd jd + days
184
+ end
185
+
186
+ def - days
187
+ self + -days
188
+ end
189
+
190
+ def >> monthes
191
+ raise TypeError.new 'expected numeric' unless monthes.is_a? Numeric
192
+ monthes = year * 12 + month + monthes
193
+ y = monthes / 12
194
+ m = monthes % 12
195
+ y -= 1 and m = 12 if m == 0
196
+ d = day
197
+ d -= 1 until Date.valid? y, m, d
198
+ Date.new y, m, d
199
+ end
200
+
201
+ def << monthes
202
+ self >> -monthes
203
+ end
204
+
205
+ def <=> other
206
+ if other.respond_to? :jd
207
+ jd <=> other.jd
208
+ elsif other.is_a? Numeric
209
+ jd <=> other
210
+ else
211
+ raise ArgumentError.new "comparison of #{self.class} with #{other.class} failed"
212
+ end
213
+ end
214
+
215
+ def step limit, by=1
216
+ date = self
217
+ comp_op = %w(== <= >=)[by <=> 0]
218
+ while date.send comp_op, limit
219
+ yield date
220
+ date += by
221
+ end
222
+ self
223
+ end
224
+
225
+ def upto max, &block
226
+ step max, 1, &block
227
+ end
228
+
229
+ def downto min, &block
230
+ step min, -1, &block
231
+ end
232
+
233
+ def next
234
+ self + 1
235
+ end
236
+ alias :succ :next
237
+
238
+ def next_day n=1
239
+ self + n
240
+ end
241
+
242
+ def next_month n=1
243
+ self >> n
244
+ end
245
+
246
+ def next_year n=1
247
+ self >> (n * 12)
248
+ end
249
+
250
+ def prev_day n=1
251
+ self - n
252
+ end
253
+
254
+ def prev_month n=1
255
+ self << n
256
+ end
257
+
258
+ def prev_year n=1
259
+ self << (n * 12)
260
+ end
261
+
262
+ def shanbe? ; wday == 0 end
263
+ def yekshanbe? ; wday == 1 end
264
+ def doshanbe? ; wday == 2 end
265
+ def seshanbe? ; wday == 3 end
266
+ def chaharshanbe? ; wday == 4 end
267
+ def panjshanbe? ; wday == 5 end
268
+ def jomee? ; wday == 6 end
269
+
270
+ private
271
+ def first_of_year
272
+ @first_of_year ||= Date.ordinal year
273
+ end
274
+ end
275
+ end
276
+
277
+ class Date
278
+ def to_parsi
279
+ Parsi::Date.jd jd
280
+ end
281
+ alias :to_persian :to_parsi
282
+ alias :to_jalali :to_parsi
283
+ alias :parsi :to_parsi
284
+ alias :jalali :to_parsi
285
+ end
@@ -0,0 +1,101 @@
1
+ module Parsi
2
+ class DateTime < Date
3
+ include Comparable
4
+
5
+ attr_reader :hour, :minute, :second, :offset
6
+
7
+ class << self
8
+ def valid_time? hour=0, minute=0, second=0, offset=0
9
+ if 0 <= hour && hour <= 23 &&
10
+ 0 <= minute && minute <= 59 &&
11
+ 0 <= second && second <= 59
12
+ #TODO: Add offset validation
13
+ true
14
+ else
15
+ false
16
+ end
17
+ end
18
+
19
+ def jd jd=0
20
+ date = Date.jd jd.to_i
21
+ h = (jd - jd.to_i) * 24
22
+ m = (h - h.to_i) * 60
23
+ s = (m - m.to_i) * 60
24
+ DateTime.new date.year, date.month, date.day, h.to_i, m.to_i, s.to_i
25
+ end
26
+
27
+ def now
28
+ now = ::DateTime.now
29
+ today = now.to_date.to_parsi
30
+ DateTime.new today.year, today.month, today.day, now.hour, now.minute, now.second, now.offset
31
+ end
32
+ end
33
+
34
+ def initialize year=0, month=1, day=1, hour=0, minute=0, second=0, offset=0
35
+ raise ArgumentError.new 'invalid time' unless
36
+ DateTime.valid_time? hour, minute, second
37
+
38
+ super year, month, day
39
+ @hour, @minute, @second, @offset = hour, minute, second, offset
40
+ end
41
+
42
+ def zone sep=':'
43
+ f = offset * 24.0
44
+ "%s%02d%s%02d" % [(f >= 0 ? '+' : '-'), f.floor, sep, (f % 1) * 60]
45
+ end
46
+
47
+ def to_s sep='/'
48
+ "%sT%02d:%02d:%02d%s" % [super(sep), hour, minute, second, zone]
49
+ end
50
+
51
+ def inspect
52
+ "#<#{self.class}: #{to_s('-')}>"
53
+ end
54
+
55
+ def strftime format='%Y/%m/%d %H:%M:%S'
56
+ gregorian.strftime super format
57
+ end
58
+
59
+ def to_date
60
+ Date.new year, month, day
61
+ end
62
+
63
+ def to_gregorian
64
+ @gregorian ||= begin
65
+ ::DateTime.new super.year, super.month, super.day, hour, minute, second, zone
66
+ end
67
+ end
68
+ alias :gregorian :to_gregorian
69
+
70
+ def + days
71
+ date = super
72
+ DateTime.new date.year, date.month, date.day, hour, minute, second, offset
73
+ end
74
+
75
+ def >> monthes
76
+ date = super
77
+ DateTime.new date.year, date.month, date.day, hour, minute, second, offset
78
+ end
79
+
80
+ def <=> other
81
+ if other.is_a? Date
82
+ to_gregorian <=> other.to_gregorian
83
+ elsif other.is_a? ::Date
84
+ to_gregorian <=> other
85
+ else
86
+ raise ArgumentError.new "comparison of #{self.class} with #{other.class} failed"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ class DateTime
93
+ def to_parsi
94
+ date = super
95
+ Parsi::DateTime.new date.year, date.month, date.day, hour, minute, second, offset
96
+ end
97
+ alias :to_persian :to_parsi
98
+ alias :to_jalali :to_parsi
99
+ alias :parsi :to_parsi
100
+ alias :jalali :to_parsi
101
+ end
@@ -0,0 +1,5 @@
1
+ module Parsi
2
+ class Date
3
+ VERSION = "0.1.pre"
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'version'
3
+
4
+ Gem::Specification.new do |s|
5
+
6
+ # Description Meta...
7
+ s.name = 'parsi-date'
8
+ s.version = Parsi::Date::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.author = 'Hassan Zamani'
11
+ s.email = 'hsn.zamani@gmail.com'
12
+ s.homepage = 'http://github.com/hzamani/parsi-date'
13
+ s.summary = 'Parsi (Jalali, Iranian, Persian) date library for Ruby'
14
+ s.description = "A Parsi date library for Ruby whitch provides much of Ruby's built-in date class"
15
+
16
+
17
+ # Load Paths...
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ['lib']
22
+
23
+
24
+ # Dependencies (installed via 'bundle install')...
25
+ s.add_development_dependency("bundler")
26
+ s.add_development_dependency("rake")
27
+ s.add_development_dependency("rspec")
28
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date#ajd" do
4
+ it "determines the Astronomical Julian day" do
5
+ Parsi::Date.civil(1391, 8, 6).ajd.should == Rational(4912455, 2)
6
+ end
7
+ end
8
+
9
+ describe "Parsi::Date#amjd" do
10
+ it "determines the Astronomical Modified Julian day" do
11
+ Parsi::Date.civil(1391, 8, 6).amjd.should == 56227
12
+ end
13
+ end
14
+
15
+ describe "Parsi::Date#mjd" do
16
+ it "determines the Modified Julian day" do
17
+ Parsi::Date.civil(1391, 8, 6).mjd.should == 56227
18
+ end
19
+ end
20
+
21
+ describe "Parsi::Date#ld" do
22
+ it "determines the Modified Julian day" do
23
+ Parsi::Date.civil(1391, 8, 6).ld.should == 157068
24
+ end
25
+ end
26
+
27
+ describe "Parsi::Date#year" do
28
+ it "determines the year" do
29
+ Parsi::Date.civil(1391, 8, 6).year.should == 1391
30
+ end
31
+ end
32
+
33
+ describe "Parsi::Date#yday" do
34
+ it "determines the year" do
35
+ Parsi::Date.civil(1391, 1, 17).yday.should == 17
36
+ Parsi::Date.civil(1391, 8, 6).yday.should == 222
37
+ end
38
+ end
39
+
40
+ describe "Parsi::Date#mon" do
41
+ it "determines the month" do
42
+ Parsi::Date.civil(1391, 1, 17).mon.should == 1
43
+ Parsi::Date.civil(1391, 8, 6).mon.should == 8
44
+ end
45
+ end
46
+
47
+ describe "Parsi::Date#mday" do
48
+ it "determines the day of the month" do
49
+ Parsi::Date.civil(1391, 1, 17).mday.should == 17
50
+ Parsi::Date.civil(1391, 10, 28).mday.should == 28
51
+ end
52
+ end
53
+
54
+ describe "Parsi::Date#wday" do
55
+ it "determines the week day" do
56
+ Parsi::Date.civil(1391, 1, 17).wday.should == 5
57
+ Parsi::Date.civil(1391, 8, 6).wday.should == 0
58
+ end
59
+ end
60
+
61
+ describe "Parsi::Date#cwday" do
62
+ it "determines the commercial week day" do
63
+ Parsi::Date.civil(1391, 1, 17).cwday.should == 6
64
+ Parsi::Date.civil(1391, 8, 6).cwday.should == 1
65
+ end
66
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date#>>" do
4
+ it "adds the number of months to a Parsi::Date" do
5
+ d = Parsi::Date.civil(1391, 2, 27) >> 10
6
+ d.should == Parsi::Date.civil(1391, 12, 27)
7
+ end
8
+
9
+ it "sets the day to the last day of a month if the day doesn't exist" do
10
+ d = Parsi::Date.civil(1391, 6, 31) >> 1
11
+ d.should == Parsi::Date.civil(1391, 7, 30)
12
+ end
13
+
14
+ it "raise a TypeError when passed a Symbol" do
15
+ lambda { Parsi::Date.civil(1391, 2, 27) >> :hello }.should raise_error(TypeError)
16
+ end
17
+
18
+ it "raise a TypeError when passed a String" do
19
+ lambda { Parsi::Date.civil(1391, 2, 27) >> "hello" }.should raise_error(TypeError)
20
+ end
21
+
22
+ it "raise a TypeError when passed a Parsi::Date" do
23
+ lambda { Parsi::Date.civil(1391, 2, 27) >> Parsi::Date.new }.should raise_error(TypeError)
24
+ end
25
+
26
+ it "raise a TypeError when passed an Object" do
27
+ lambda { Parsi::Date.civil(1391, 2, 27) >> Object.new }.should raise_error(TypeError)
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date#+" do
4
+ it "adds the number of days to a Parsi::Date" do
5
+ d = Parsi::Date.civil(1391, 2, 27) + 10
6
+ d.should == Parsi::Date.civil(1391, 3, 6)
7
+ end
8
+
9
+ it "adds a negative number of days to a Parsi::Date" do
10
+ d = Parsi::Date.civil(1391, 2, 27) + (-10)
11
+ d.should == Parsi::Date.civil(1391, 2, 17)
12
+ end
13
+
14
+ it "raises a TypeError when passed a Symbol" do
15
+ lambda { Parsi::Date.civil(1391, 2, 27) + :hello }.should raise_error(TypeError)
16
+ end
17
+
18
+ it "raises a TypeError when passed a String" do
19
+ lambda { Parsi::Date.civil(1391, 2, 27) + "hello" }.should raise_error(TypeError)
20
+ end
21
+
22
+ it "raises a TypeError when passed a Parsi::Date" do
23
+ lambda { Parsi::Date.civil(1391, 2, 27) + Parsi::Date.new }.should raise_error(TypeError)
24
+ end
25
+
26
+ it "raises a TypeError when passed an Object" do
27
+ lambda { Parsi::Date.civil(1391, 2, 27) + Object.new }.should raise_error(TypeError)
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+ require 'date'
3
+
4
+ describe "Parsi::Date#<=>" do
5
+ it "returns 0 when two dates are equal" do
6
+ (Parsi::Date.civil(1391, 4, 6) <=> Parsi::Date.civil(1391, 4, 6)).should == 0
7
+ (Parsi::Date.civil(1391, 4, 6) <=> Date.civil(2012, 6, 26)).should == 0
8
+ end
9
+
10
+ it "returns -1 when self is less than another date" do
11
+ (Parsi::Date.civil(1391, 4, 5) <=> Parsi::Date.civil(1391, 4, 6)).should == -1
12
+ (Parsi::Date.civil(1391, 4, 5) <=> Date.civil(2012, 6, 26)).should == -1
13
+ end
14
+
15
+ it "returns 1 when self is greater than another date" do
16
+ (Parsi::Date.civil(1392, 4, 7) <=> Parsi::Date.civil(1391, 4, 6)).should == 1
17
+ (Parsi::Date.civil(1391, 4, 7) <=> Date.civil(2012, 6, 26)).should == 1
18
+ end
19
+
20
+ it "returns 0 when self is equal to a Numeric" do
21
+ (Parsi::Date.civil(1391, 4, 6) <=> 2456105).should == 0
22
+ end
23
+
24
+ it "returns -1 when self is less than a Numeric" do
25
+ (Parsi::Date.civil(1391, 4, 6) <=> 2456106).should == -1
26
+ end
27
+
28
+ it "returns 1 when self is greater than a Numeric" do
29
+ (Parsi::Date.civil(1391, 4, 6) <=> 2456104).should == 1
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../../spec_helper', __FILE__)
3
+
4
+ describe "Date constants" do
5
+ it "defines MONTHNAMES" do
6
+ Parsi::MONTHNAMES.should == [nil] + %w(فروردین اردیبهشت خرداد تیر مرداد شهریور مهر آبان آذر دی بهمن اسفند)
7
+ end
8
+
9
+ it "defines ABBR_MONTHNAMES" do
10
+ Parsi::ABBR_MONTHNAMES.should == [nil] + %w(Far Ord Kho Tir Mor Sha Meh Abn Azr Dey Bah Esf)
11
+ end
12
+
13
+ it "defines DAYNAMES" do
14
+ Parsi::DAYNAMES.should == %w(شنده یک‌شنده دوشنده سه‌شنده چهارشنده چنج‌شنده جمعه)
15
+ end
16
+
17
+ it "defines ABBR_DAYNAMES" do
18
+ Parsi::ABBR_DAYNAMES.should == %w(ش ۱ش ۲ش ۳ش ۴ش ۵ش ج)
19
+ end
20
+
21
+ it "freezes MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYSNAMES" do
22
+ [Parsi::MONTHNAMES, Parsi::DAYNAMES, Parsi::ABBR_MONTHNAMES, Parsi::ABBR_DAYNAMES].each do |ary|
23
+ ary.should be_frozen
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Parsi::Date do
4
+ context "civil" do
5
+ it "constructs a date with arguments" do
6
+ expect { Parsi::Date.civil 1391, 8, 6 }.to_not raise_error
7
+ expect { Parsi::Date.civil 1391, 12, 30 }.to_not raise_error # 1391 is a leap year
8
+ end
9
+
10
+ it "doesn't construct dates for invalid arguments" do
11
+ expect { Parsi::Date.civil 1391, 15, 1 }.to raise_error(ArgumentError, 'invalid date')
12
+ expect { Parsi::Date.civil 1391, 0, 1 }.to raise_error(ArgumentError, 'invalid date')
13
+ expect { Parsi::Date.civil 1391, 1, 32 }.to raise_error(ArgumentError, 'invalid date')
14
+ expect { Parsi::Date.civil 1391, 2, 0 }.to raise_error(ArgumentError, 'invalid date')
15
+ expect { Parsi::Date.civil 1391, 8, 31 }.to raise_error(ArgumentError, 'invalid date')
16
+ expect { Parsi::Date.civil 1390, 12, 30 }.to raise_error(ArgumentError, 'invalid date') # 1390 is not a leap year
17
+ expect { Parsi::Date.civil 1391, 8, 31 }.to raise_error(ArgumentError, 'invalid date')
18
+
19
+ # invalid type
20
+ expect { Parsi::Date.civil '1390/1/1' }.to raise_error(ArgumentError, 'invalid date')
21
+ expect { Parsi::Date.civil 1391, '1', 9 }.to raise_error(ArgumentError, 'invalid date')
22
+ end
23
+
24
+ it "constructs a Date for 0/1/1 by default" do
25
+ date = Parsi::Date.civil
26
+ date.year.should == 0
27
+ date.month.should == 1
28
+ date.day.should == 1
29
+ end
30
+ end
31
+
32
+ context "ordinal" do
33
+ it "constructs a Date object from an ordinal date" do
34
+ Parsi::Date.ordinal(1390).should == Parsi::Date.civil(1390, 1, 1)
35
+ Parsi::Date.ordinal(1390,7).should == Parsi::Date.civil(1390, 1, 7)
36
+ Parsi::Date.ordinal(1390,100).should == Parsi::Date.civil(1390, 4, 7)
37
+ end
38
+ end
39
+
40
+ context "parse" do
41
+ it "should parse date from strings" do
42
+ ['1391/8/6', '1391-8-6', '1391 8 6', '1391 8 6', '13910806'].each do |date_string|
43
+ date = Parsi::Date.parse date_string
44
+ [date.year, date.month, date.day].should == [1391, 8, 6]
45
+ end
46
+ end
47
+
48
+ it "completes century when second arg is true" do
49
+ Date.stub(:today) { Date.new 2012, 10, 26 }
50
+ date = Parsi::Date.parse '91/8/5', true
51
+ [date.year, date.month, date.day].should == [1391, 8, 5]
52
+ end
53
+
54
+ it "should raise ArgumentError on invalid date string" do
55
+ expect { date = Parsi::Date.parse '1390/12/30' }.to raise_error(ArgumentError)
56
+ expect { date = Parsi::Date.parse 'bad date string' }.to raise_error(ArgumentError)
57
+ expect { date = Parsi::Date.parse '12-30-1390' }.to raise_error(ArgumentError)
58
+ end
59
+ end
60
+
61
+ context "#today" do
62
+ it "initialize a date object with today's attributes" do
63
+ Date.stub(:today) { Date.new 2012, 10, 26 }
64
+ date = Parsi::Date.today
65
+ [date.year, date.month, date.day].should == [1391, 8, 5]
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date.jd" do
4
+ it "constructs a date form given Chronological Julian day number" do
5
+ Parsi::Date.jd(2456228).should == Parsi::Date.civil(1391, 8, 6)
6
+ Parsi::Date.jd(2456229).should == Parsi::Date.civil(1391, 8, 7)
7
+ end
8
+
9
+ it "returns a Date object representing Julian day 0 if no arguments passed"do
10
+ Parsi::Date.jd.should == Parsi::Date.civil(-5335, 9, 1)
11
+ end
12
+
13
+ it "constructs a Date object if passed a negative number" do
14
+ Parsi::Date.jd(-1).should == Parsi::Date.civil(-5335, 8, 30)
15
+ end
16
+ end
17
+
18
+ describe "Parsi::Date#jd" do
19
+ it "determines the Julian day for a Date object" do
20
+ Parsi::Date.civil(1391, 8, 7).jd.should == 2456229
21
+ end
22
+ end
23
+
24
+ describe "Parsi::Date#to_gregorian" do
25
+ it "converts date to Gregorian date" do
26
+ date = Parsi::Date.civil(1391, 8, 7).to_gregorian
27
+ date.should be_a(Date)
28
+ date.should == Date.civil(2012, 10, 28)
29
+ end
30
+ end
31
+
32
+ describe "Date#to_parsi" do
33
+ it "converts date to Parsi date" do
34
+ date = Date.civil(2012, 10, 28).to_parsi
35
+ date.should be_a(Parsi::Date)
36
+ date.should == Parsi::Date.civil(1391, 8, 7)
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date#leap?" do
4
+ it "returns true if a year is a leap year in the Parsi (Jalali) calendar" do
5
+ Parsi::Date.leap?(1387).should be_true
6
+ Parsi::Date.leap?(1391).should be_true
7
+ Parsi::Date.leap?(1395).should be_true
8
+ end
9
+
10
+ it "returns false if a year is not a leap year in the Parsi (Jalali) calendar" do
11
+ Parsi::Date.leap?(1390).should be_false
12
+ Parsi::Date.leap?(1392).should be_false
13
+ Parsi::Date.leap?(1400).should be_false
14
+ end
15
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Parsi::Date#step" do
4
+
5
+ it "steps forward in time" do
6
+ ds = Parsi::Date.civil(1391, 10, 11)
7
+ de = Parsi::Date.civil(1391, 9, 29)
8
+ count = 0
9
+ de.step(ds) do |d|
10
+ d.should <= ds
11
+ d.should >= de
12
+ count += 1
13
+ end
14
+ count.should == 13
15
+
16
+ count = 0
17
+ de.step(ds, 5) do |d|
18
+ d.should <= ds
19
+ d.should >= de
20
+ count += 1
21
+ end
22
+ count.should == 3
23
+
24
+ count = 0
25
+ ds.step(de) do |d|; count += 1; end
26
+ count.should == 0
27
+ end
28
+
29
+ it "steps backward in time" do
30
+ ds = Parsi::Date.civil(1390, 4, 14)
31
+ de = Parsi::Date.civil(1390, 3, 29)
32
+ count = 0
33
+ ds.step(de, -1) do |d|
34
+ d.should <= ds
35
+ d.should >= de
36
+ count += 1
37
+ end
38
+ count.should == 17
39
+
40
+ count = 0
41
+ ds.step(de, -5) do |d|
42
+ d.should <= ds
43
+ d.should >= de
44
+ count += 1
45
+ end
46
+ count.should == 4
47
+
48
+ count = 0
49
+ de.step(ds, -1) do |d|; count += 1; end
50
+ count.should == 0
51
+ end
52
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../../spec_helper', __FILE__)
3
+
4
+ describe "Parsi::Date#strftime" do
5
+
6
+ it "should be able to print the date" do
7
+ Parsi::Date.civil(1390, 4, 6).strftime.should == "1390/04/06"
8
+ Parsi::Date.civil(1390, 4, 6).strftime.should == Parsi::Date.civil(1390, 4, 6).to_s
9
+ end
10
+
11
+ it "should be able to print the full day name" do
12
+ Parsi::Date.civil(1390, 4, 6).strftime("%A").should == "دوشنده"
13
+ end
14
+
15
+ it "should be able to print the short day name" do
16
+ Parsi::Date.civil(1390, 4, 6).strftime("%a").should == "۲ش"
17
+ end
18
+
19
+ it "should be able to print the full month name" do
20
+ Parsi::Date.civil(1390, 4, 6).strftime("%B").should == "تیر"
21
+ end
22
+
23
+ it "should be able to print the short month name" do
24
+ Parsi::Date.civil(1390, 4, 6).strftime("%b").should == "Tir"
25
+ Parsi::Date.civil(1390, 4, 6).strftime("%h").should == "Tir"
26
+ Parsi::Date.civil(1390, 4, 6).strftime("%b").should == Parsi::Date.civil(1390, 4, 6).strftime("%h")
27
+ end
28
+
29
+ it "should be able to print the century" do
30
+ Parsi::Date.civil(1390, 4, 6).strftime("%C").should == "13"
31
+ end
32
+
33
+ it "should be able to print the month day with leading zeroes" do
34
+ Parsi::Date.civil(1390, 4, 6).strftime("%d").should == "06"
35
+ end
36
+
37
+ it "should be able to print the month day with leading spaces" do
38
+ Parsi::Date.civil(1390, 4, 6).strftime("%e").should == " 6"
39
+ end
40
+
41
+ it "should be able to print the month with leading zeroes" do
42
+ Parsi::Date.civil(1390, 4, 6).strftime("%m").should == "04"
43
+ end
44
+
45
+ it "should be able to add a newline" do
46
+ Parsi::Date.civil(1390, 4, 6).strftime("%n").should == "\n"
47
+ end
48
+
49
+ it "should be able to add a tab" do
50
+ Parsi::Date.civil(1390, 4, 6).strftime("%t").should == "\t"
51
+ end
52
+
53
+ it "should be able to show the commercial week day" do
54
+ Parsi::Date.civil(1390, 4, 10).strftime("%u").should == "7"
55
+ Parsi::Date.civil(1390, 4, 11).strftime("%u").should == "1"
56
+ end
57
+
58
+ it "should be able to show the week day" do
59
+ Parsi::Date.civil(1390, 4, 10).strftime("%w").should == "6"
60
+ Parsi::Date.civil(1390, 4, 11).strftime("%w").should == "0"
61
+ end
62
+
63
+ it "should be able to show the year in YYYY format" do
64
+ Parsi::Date.civil(1390, 4, 9).strftime("%Y").should == "1390"
65
+ end
66
+
67
+ it "should be able to show the year in YY format" do
68
+ Parsi::Date.civil(1390, 4, 9).strftime("%y").should == "90"
69
+ end
70
+
71
+ it "should be able to escape the % character" do
72
+ Parsi::Date.civil(1390, 4, 9).strftime("%%").should == "%"
73
+ end
74
+
75
+ ############################
76
+ # Specs that combine stuff #
77
+ ############################
78
+
79
+ it "should be able to print the date in full" do
80
+ Parsi::Date.civil(1390, 4, 6).strftime("%c").should == "۲ش 6 تیر 1390"
81
+ Parsi::Date.civil(1390, 4, 6).strftime("%c").should == Parsi::Date.civil(1390, 4, 6).strftime('%a %-d %B %Y')
82
+ end
83
+
84
+ it "should be able to print the date with slashes" do
85
+ Parsi::Date.civil(1390, 4, 6).strftime("%D").should == "90/04/06"
86
+ Parsi::Date.civil(1390, 4, 6).strftime("%D").should == Parsi::Date.civil(1390, 4, 6).strftime('%y/%m/%d')
87
+ end
88
+
89
+ it "should be able to print the date as YYYY-MM-DD" do
90
+ Parsi::Date.civil(1390, 4, 6).strftime("%F").should == "1390-04-06"
91
+ Parsi::Date.civil(1390, 4, 6).strftime("%F").should == Parsi::Date.civil(1390, 4, 6).strftime('%Y-%m-%d')
92
+ end
93
+
94
+ it "should be able to show the commercial week" do
95
+ Parsi::Date.civil(1390, 4, 9).strftime("%v").should == " 9-Tir-1390"
96
+ Parsi::Date.civil(1390, 4, 9).strftime("%v").should == Parsi::Date.civil(1390, 4, 9).strftime('%e-%b-%Y')
97
+ end
98
+
99
+ it "should be able to show YY/MM/DD" do
100
+ Parsi::Date.civil(1390, 4, 6).strftime("%x").should == "90/04/06"
101
+ Parsi::Date.civil(1390, 4, 6).strftime("%x").should == Parsi::Date.civil(1390, 4, 6).strftime('%y/%m/%d')
102
+ end
103
+
104
+ end
@@ -0,0 +1,13 @@
1
+ require 'parsi-date'
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+
8
+ # Run specs in random order to surface order dependencies. If you find an
9
+ # order dependency and want to debug it, you can fix the order by providing
10
+ # the seed, which is printed after each run.
11
+ # --seed 1234
12
+ config.order = 'random'
13
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parsi-date
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.pre
5
+ prerelease: 4
6
+ platform: ruby
7
+ authors:
8
+ - Hassan Zamani
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A Parsi date library for Ruby whitch provides much of Ruby's built-in
63
+ date class
64
+ email: hsn.zamani@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - Gemfile
72
+ - Gemfile.lock
73
+ - lib/parsi-date.rb
74
+ - lib/parsi-datetime.rb
75
+ - lib/version.rb
76
+ - parsi-date.gemspec
77
+ - spec/parsi-date/accessor_spec.rb
78
+ - spec/parsi-date/add_month_spec.rb
79
+ - spec/parsi-date/add_spec.rb
80
+ - spec/parsi-date/comp_spec.rb
81
+ - spec/parsi-date/constants_spec.rb
82
+ - spec/parsi-date/construction_spec.rb
83
+ - spec/parsi-date/conversion_spec.rb
84
+ - spec/parsi-date/leap_spec.rb
85
+ - spec/parsi-date/step_spec.rb
86
+ - spec/parsi-date/strftime_spec.rb
87
+ - spec/spec_helper.rb
88
+ homepage: http://github.com/hzamani/parsi-date
89
+ licenses: []
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>'
104
+ - !ruby/object:Gem::Version
105
+ version: 1.3.1
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.24
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Parsi (Jalali, Iranian, Persian) date library for Ruby
112
+ test_files:
113
+ - spec/parsi-date/accessor_spec.rb
114
+ - spec/parsi-date/add_month_spec.rb
115
+ - spec/parsi-date/add_spec.rb
116
+ - spec/parsi-date/comp_spec.rb
117
+ - spec/parsi-date/constants_spec.rb
118
+ - spec/parsi-date/construction_spec.rb
119
+ - spec/parsi-date/conversion_spec.rb
120
+ - spec/parsi-date/leap_spec.rb
121
+ - spec/parsi-date/step_spec.rb
122
+ - spec/parsi-date/strftime_spec.rb
123
+ - spec/spec_helper.rb