jalalidate 0.2.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/LICENSE +20 -0
- data/README.rdoc +31 -0
- data/Rakefile +77 -0
- data/TODO +3 -0
- data/lib/jalalidate.rb +315 -0
- data/spec/jalalidate_spec.rb +127 -0
- data/spec/spec_helper.rb +9 -0
- metadata +85 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008-2010 Aziz A. Bargi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
= Jalali Date Library
|
2
|
+
|
3
|
+
== History
|
4
|
+
|
5
|
+
==== 0.2 - 25.FEB.2010
|
6
|
+
* renamed the gem from JalaliDate to jalalidate
|
7
|
+
* added spec and a full test suite
|
8
|
+
* updated gemspec file for rubygems.org
|
9
|
+
* updated some documentations
|
10
|
+
|
11
|
+
==== 0.02 - 08.AUG.2008
|
12
|
+
* added jalali to geregorian date convertor.
|
13
|
+
* added JalaliDate class and ported Date class method to JalaliDate
|
14
|
+
|
15
|
+
==== 0.01 - 07.AUG.2008
|
16
|
+
* planning the project
|
17
|
+
|
18
|
+
|
19
|
+
== Note on Patches/Pull Requests
|
20
|
+
|
21
|
+
* Fork the project.
|
22
|
+
* Make your feature addition or bug fix.
|
23
|
+
* Add tests for it. This is important so I don't break it in a
|
24
|
+
future version unintentionally.
|
25
|
+
* Commit, do not mess with rakefile, version, or history.
|
26
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
27
|
+
* Send me a pull request. Bonus points for topic branches.
|
28
|
+
|
29
|
+
== Copyright
|
30
|
+
|
31
|
+
Copyright (c) 2008-2010 Aziz A. Bargi. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
|
8
|
+
gem.name = "jalalidate"
|
9
|
+
gem.version = "0.2.0"
|
10
|
+
gem.authors = ["Aziz A. Bargi"]
|
11
|
+
gem.email = "aziz.bargi@gmail.com"
|
12
|
+
gem.rubyforge_project = 'JalaliDate'
|
13
|
+
gem.homepage = "http://github.com/aziz/jalalidate"
|
14
|
+
gem.summary = "A port of class Date in ruby that works based on Jalali Calendar (a.k.a Persian Calendar)"
|
15
|
+
gem.require_path = "lib"
|
16
|
+
gem.has_rdoc = true
|
17
|
+
gem.extra_rdoc_files = ["README.rdoc","LICENSE"]
|
18
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
19
|
+
gem.rdoc_options << "--charset" << "utf-8"
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
34
|
+
spec.libs << 'lib' << 'spec'
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :spec => :check_dependencies
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'reek/adapters/rake_task'
|
43
|
+
Reek::RakeTask.new do |t|
|
44
|
+
t.fail_on_error = true
|
45
|
+
t.verbose = false
|
46
|
+
t.source_files = 'lib/**/*.rb'
|
47
|
+
end
|
48
|
+
rescue LoadError
|
49
|
+
task :reek do
|
50
|
+
abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
begin
|
55
|
+
require 'roodi'
|
56
|
+
require 'roodi_task'
|
57
|
+
RoodiTask.new do |t|
|
58
|
+
t.verbose = false
|
59
|
+
end
|
60
|
+
rescue LoadError
|
61
|
+
task :roodi do
|
62
|
+
abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
task :default => :spec
|
67
|
+
|
68
|
+
require 'rake/rdoctask'
|
69
|
+
Rake::RDocTask.new do |rdoc|
|
70
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
71
|
+
|
72
|
+
rdoc.options << "--charset" << "utf-8"
|
73
|
+
rdoc.rdoc_dir = 'rdoc'
|
74
|
+
rdoc.title = "jalalidate #{version}"
|
75
|
+
rdoc.rdoc_files.include(['README.rdoc','LICENSE'])
|
76
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
77
|
+
end
|
data/TODO
ADDED
data/lib/jalalidate.rb
ADDED
@@ -0,0 +1,315 @@
|
|
1
|
+
# :title:Jalali Date #
|
2
|
+
require 'jcode'
|
3
|
+
require "date"
|
4
|
+
|
5
|
+
class JalaliDate
|
6
|
+
|
7
|
+
#:stopdoc:
|
8
|
+
$KCODE = 'u'
|
9
|
+
GDaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
10
|
+
JDaysInMonth = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]
|
11
|
+
PERSIAN_MONTH_NAMES = [nil, "فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"]
|
12
|
+
PERSIAN_WEEKDAY_NAMES = ["یکشنبه","دوشنبه","سهشنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"]
|
13
|
+
PERSIAN_ABBR_WEEKDAY_NAMES = ["۱ش","۲ش","۳ش","۴ش","۵ش","ج","ش"]
|
14
|
+
PERSIAN_MERIDIAN_INDICATOR = ["قبل از ظهر","بعد از ظهر"]
|
15
|
+
PERSIAN_ABBR_MERIDIAN_INDICATOR = ["ق.ظ","ب.ظ"]
|
16
|
+
#:startdoc:
|
17
|
+
|
18
|
+
include Comparable
|
19
|
+
|
20
|
+
attr_accessor :year,:month,:day
|
21
|
+
attr_reader :g_year, :g_month, :g_day
|
22
|
+
|
23
|
+
# Can be initialized in two ways:
|
24
|
+
# - First by feeding 3 arguments for Jalali Date, year,month and day.
|
25
|
+
# - The Second way to initializes is to pass a normal Ruby Date object, it'll be converted to jalali automatically.
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# jdate = JalaliDate.new(Date.today)
|
29
|
+
# other_jdate = JalaliDate.new(1388,9,17)
|
30
|
+
def initialize *args
|
31
|
+
if (args.size == 1) && (args.first.is_a? Date)
|
32
|
+
year,month,day = gregorian_to_jalali(args.first.year, args.first.month, args.first.day)
|
33
|
+
else
|
34
|
+
year,month,day = args
|
35
|
+
end
|
36
|
+
|
37
|
+
raise ArgumentError, "invalid arguments or invalid Jalali date" unless self.class.valid?(year,month,day)
|
38
|
+
@year = year
|
39
|
+
@month = month
|
40
|
+
@day = day
|
41
|
+
@g_year, @g_month, @g_day = jalali_to_gregorian(year,month,day)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Class Methods
|
45
|
+
class << self
|
46
|
+
|
47
|
+
# Return a JalaliDate object representing today's date in calendar
|
48
|
+
def today
|
49
|
+
JalaliDate.new(Date.today)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return a JalaliDate object representing yesterday's date in calendar
|
53
|
+
def yesterday
|
54
|
+
JalaliDate.new(Date.today - 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return a JalaliDate object representing tomorrow's date in calendar
|
58
|
+
def tomorrow
|
59
|
+
JalaliDate.new(Date.today + 1)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Accpets a four digit number as the jalaliyear and returns true if that particular year
|
63
|
+
# is a leap year in jalali calendar otherwise it returns false.
|
64
|
+
def leap?(y)
|
65
|
+
[6,22,17,13,9,5,1,30].include?(y%33) ? true : false
|
66
|
+
end
|
67
|
+
|
68
|
+
# Accpets three numbers for year (4 digit), month and day in jalali calendar and checks if it's a
|
69
|
+
# valid date according to jalali calendar or not.
|
70
|
+
def valid?(y,m,d)
|
71
|
+
(y.class == Fixnum && y > 0 &&
|
72
|
+
m.class == Fixnum && (1..12).include?(m) &&
|
73
|
+
d.class == Fixnum && (((1..JDaysInMonth[m-1]).include?(d)) || (d == 30 && m == 12 && leap?(y) ))
|
74
|
+
) ? true : false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Converts a JalaiDate object to Ruby Date object
|
79
|
+
def to_gregorian; Date.new(@g_year,@g_month,@g_day); end;
|
80
|
+
alias :to_g :to_gregorian
|
81
|
+
|
82
|
+
# Returns a string represtation of the JalaliDate object in format like this: y/m/d
|
83
|
+
def to_s
|
84
|
+
[@year,@month,@day].join("/")
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns a hash in a format like this: {:year => @year, :month => @month, :day => @day}
|
88
|
+
def to_hash
|
89
|
+
{:year => @year, :month => @month, :day => @day}
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns an array in a format like this: [y,m,d]
|
93
|
+
def to_a
|
94
|
+
[@year,@month,@day]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return internal object state as a programmer-readable string.
|
98
|
+
def inspect
|
99
|
+
"#<#{self.class}:#{self.object_id}, :year => #{@year}, :month => #{@month}, :day => #{@day} >"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Adds n days to the current JalaliDate object
|
103
|
+
def +(days)
|
104
|
+
self.class.new( to_g + days )
|
105
|
+
end
|
106
|
+
|
107
|
+
# Subtracts n days from the current JalaliDate object
|
108
|
+
def -(days)
|
109
|
+
self.class.new( to_g - days )
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return the next day for the current JalaliDate object
|
113
|
+
def next(n=1)
|
114
|
+
self + n
|
115
|
+
end
|
116
|
+
alias :succ :next
|
117
|
+
|
118
|
+
# Return the previous day for the current JalaliDate object
|
119
|
+
def previous(n=1)
|
120
|
+
self - n
|
121
|
+
end
|
122
|
+
|
123
|
+
# Compares two JalaliDate objects. acts like Date#<=>
|
124
|
+
def <=>(other)
|
125
|
+
to_g <=> other.to_g
|
126
|
+
end
|
127
|
+
|
128
|
+
# Move JalaliDate object forward by n months
|
129
|
+
def >>(months)
|
130
|
+
y, m = (@year * 12 + (@month - 1) + months).divmod(12)
|
131
|
+
m, = (m + 1) .divmod(1)
|
132
|
+
d = @day
|
133
|
+
d -= 1 until self.class.valid?(y, m, d)
|
134
|
+
self.class.new(y,m,d)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Move JalaliDate object backward by n months
|
138
|
+
def <<(months)
|
139
|
+
self >> -months
|
140
|
+
end
|
141
|
+
|
142
|
+
# Step the current date forward +step+ days at a time (or backward, if step is negative) until we reach
|
143
|
+
# limit (inclusive), yielding the resultant date at each step.
|
144
|
+
#
|
145
|
+
# Example:
|
146
|
+
# jdate = JalaliDate.new(Date.today)
|
147
|
+
# jdate.step(Date.today+10, 2) do |jd|
|
148
|
+
# puts jd.to_s
|
149
|
+
# end
|
150
|
+
def step(limit, step=1)
|
151
|
+
da = self
|
152
|
+
op = %w(- <= >=)[step <=> 0]
|
153
|
+
while da.__send__(op, limit)
|
154
|
+
yield da
|
155
|
+
da += step
|
156
|
+
end
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
# Step forward one day at a time until we reach max (inclusive), yielding each date as we go.
|
161
|
+
#
|
162
|
+
# Example:
|
163
|
+
# jdate = JalaliDate.new(Date.today)
|
164
|
+
# days_string = ""
|
165
|
+
# jdate.upto(jdate+5) do |jd|
|
166
|
+
# days_string += jd.day.to_s
|
167
|
+
# end
|
168
|
+
def upto(max, &block)
|
169
|
+
step(max, +1, &block)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Step backward one day at a time until we reach min (inclusive), yielding each date as we go.
|
173
|
+
# See #upto for the example.
|
174
|
+
def downto(min, &block)
|
175
|
+
step(min, -1, &block)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Is this a leap year?
|
179
|
+
def leap?
|
180
|
+
self.class.leap?(@year)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Get the week day of this date. Sunday is day-of-week 0; Saturday is day-of-week 6.
|
184
|
+
def wday
|
185
|
+
to_g.wday
|
186
|
+
end
|
187
|
+
|
188
|
+
# Get the day-of-the-year of this date.
|
189
|
+
# Farvardin 1 is day-of-the-year 1
|
190
|
+
def yday
|
191
|
+
m = (@month-2 < 0) ? 0 : @month-2
|
192
|
+
(@month==1) ? @day : @day + JDaysInMonth[0..m].inject(0) {|sum, n| sum + n }
|
193
|
+
end
|
194
|
+
|
195
|
+
# Formats time according to the directives in the given format string. Any text not listed as a directive will be
|
196
|
+
# passed through to the output string.
|
197
|
+
#
|
198
|
+
# Format meanings:
|
199
|
+
#
|
200
|
+
# [%a] The abbreviated weekday name (۳ش)
|
201
|
+
# [%A] The full weekday name (یکشنبه)
|
202
|
+
# [%b or %B] The month name (اردیبهشت)
|
203
|
+
# [%d] Day of the month (1..31)
|
204
|
+
# [%j] Day of the year (1..366)
|
205
|
+
# [%m] Month of the year (1..12)
|
206
|
+
# [%w] Day of the week (Sunday is 0, 0..6)
|
207
|
+
# [%x] Preferred representation for the date alone, no time in format YY/M/D
|
208
|
+
# [%y] Year without a century (00..99)
|
209
|
+
# [%Y] Year with century
|
210
|
+
# [%%] Literal %'' character
|
211
|
+
#
|
212
|
+
# Example:
|
213
|
+
# d = JalaliDate.today
|
214
|
+
# d.strftime("Printed on %Y/%m/%d") #=> "Printed on 87/5/26
|
215
|
+
def strftime(format_str = '%Y/%m/%d')
|
216
|
+
clean_fmt = format_str.gsub(/%{2}/, "SUBSTITUTION_MARKER").
|
217
|
+
gsub(/%a/, PERSIAN_ABBR_WEEKDAY_NAMES[wday]).
|
218
|
+
gsub(/%A/, PERSIAN_WEEKDAY_NAMES[wday]).
|
219
|
+
gsub(/%b/, PERSIAN_MONTH_NAMES[@month]).
|
220
|
+
gsub(/%B/, PERSIAN_MONTH_NAMES[@month]).
|
221
|
+
gsub(/%d/, @day.to_s).
|
222
|
+
gsub(/%m/, @month.to_s).
|
223
|
+
gsub(/%Y/, @year.to_s).
|
224
|
+
gsub(/%y/, @year.to_s.slice(2,2)).
|
225
|
+
gsub(/%j/, yday.to_s).
|
226
|
+
gsub(/%w/, wday.to_s).
|
227
|
+
gsub(/%x/, [@year.to_s.slice(2,2),@month,@day].join("/")).
|
228
|
+
gsub(/#{"SUBSTITUTION_MARKER"}/, '%')
|
229
|
+
end
|
230
|
+
alias :format :strftime
|
231
|
+
|
232
|
+
private #-------------------------------------------------------------------------
|
233
|
+
|
234
|
+
def gregorian_to_jalali(year, month, day)
|
235
|
+
gy = year - 1600
|
236
|
+
gm = month - 1
|
237
|
+
gd = day - 1
|
238
|
+
g_day_no = 365*gy + (gy+3)/4 - (gy+99)/100 + (gy+399)/400
|
239
|
+
gm.times { |i| g_day_no += GDaysInMonth[i] }
|
240
|
+
g_day_no += 1 if gm > 1 && ((gy%4 == 0 && gy%100 != 0) || (gy%400 == 0))
|
241
|
+
g_day_no += gd
|
242
|
+
|
243
|
+
j_day_no = g_day_no-79
|
244
|
+
j_np = j_day_no/12053
|
245
|
+
j_day_no %= 12053
|
246
|
+
jy = 979 + 33 * j_np + 4*(j_day_no/1461)
|
247
|
+
j_day_no %= 1461
|
248
|
+
|
249
|
+
if (j_day_no >= 366)
|
250
|
+
jy += (j_day_no - 1)/365
|
251
|
+
j_day_no = (j_day_no - 1) % 365
|
252
|
+
end
|
253
|
+
|
254
|
+
11.times do |i|
|
255
|
+
if j_day_no >= JDaysInMonth[i]
|
256
|
+
j_day_no -= JDaysInMonth[i]
|
257
|
+
$j = i + 1
|
258
|
+
else
|
259
|
+
$j = i
|
260
|
+
break
|
261
|
+
end
|
262
|
+
end
|
263
|
+
jm = $j + 1
|
264
|
+
jd = j_day_no + 1
|
265
|
+
|
266
|
+
[jy, jm, jd]
|
267
|
+
end
|
268
|
+
|
269
|
+
def jalali_to_gregorian(year,month,day)
|
270
|
+
jy = year - 979
|
271
|
+
jm = month - 1
|
272
|
+
jd = day - 1
|
273
|
+
j_day_no = 365*jy + (jy/33)*8 + (jy % 33 + 3)/4
|
274
|
+
jm.times { |i| j_day_no += JDaysInMonth[i] }
|
275
|
+
j_day_no += jd
|
276
|
+
|
277
|
+
g_day_no = j_day_no + 79
|
278
|
+
gy = 1600 + 400*(g_day_no/146097)
|
279
|
+
g_day_no %= 146097
|
280
|
+
|
281
|
+
leap = true
|
282
|
+
if g_day_no >= 36525
|
283
|
+
g_day_no -= 1
|
284
|
+
gy += 100 * (g_day_no/36524)
|
285
|
+
g_day_no %= 36524
|
286
|
+
(g_day_no >= 365) ? g_day_no += 1 : leap = false
|
287
|
+
end
|
288
|
+
|
289
|
+
gy += 4 * (g_day_no/1461)
|
290
|
+
g_day_no %= 1461
|
291
|
+
|
292
|
+
if g_day_no >= 366
|
293
|
+
leap = false
|
294
|
+
g_day_no -= 1
|
295
|
+
gy += g_day_no/365
|
296
|
+
g_day_no %= 365
|
297
|
+
end
|
298
|
+
|
299
|
+
11.times do |i|
|
300
|
+
leap_day = (i==1 && leap) ? 1 : 0
|
301
|
+
if g_day_no >= (GDaysInMonth[i] + leap_day )
|
302
|
+
g_day_no -= (GDaysInMonth[i] + leap_day )
|
303
|
+
$g = i + 1
|
304
|
+
else
|
305
|
+
$g = i
|
306
|
+
break
|
307
|
+
end
|
308
|
+
end
|
309
|
+
gm = $g + 1
|
310
|
+
gd = g_day_no + 1
|
311
|
+
|
312
|
+
[gy,gm,gd]
|
313
|
+
end
|
314
|
+
|
315
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe JalaliDate do
|
4
|
+
|
5
|
+
it "should initialize with valid year,month,date values" do
|
6
|
+
jdate = JalaliDate.new(1388,11,22)
|
7
|
+
jdate.should be_instance_of(JalaliDate)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should raise error for invalid year,month,date combination on initialize" do
|
11
|
+
lambda { JalaliDate.new(1388,14,22) }.should raise_error(ArgumentError) # invalid month
|
12
|
+
lambda { JalaliDate.new(1388,14,32) }.should raise_error(ArgumentError) # invalid day
|
13
|
+
lambda { JalaliDate.new(1388,14,"22") }.should raise_error(ArgumentError) # invalid type
|
14
|
+
lambda { JalaliDate.new(1388,14,22,11,0) }.should raise_error(ArgumentError) # invalid arguments
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should initialize with a ruby date object" do
|
18
|
+
jdate = JalaliDate.new(Date.today)
|
19
|
+
jdate.should be_instance_of(JalaliDate)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should populate attr_accessors for jalali year, month and date and attr_reader for gregorian year,month and date" do
|
23
|
+
jdate = JalaliDate.new(1388,11,22)
|
24
|
+
jdate.year.should eql(1388)
|
25
|
+
jdate.month.should eql(11)
|
26
|
+
jdate.day.should eql(22)
|
27
|
+
jdate.g_year.should eql(2010)
|
28
|
+
jdate.g_month.should eql(2)
|
29
|
+
jdate.g_day.should eql(11)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return today, yesterday, and tomorrow date according to jalali calendar" do
|
33
|
+
Date.stub!(:today).and_return(Date.new(2010,1,1))
|
34
|
+
JalaliDate.today.should == JalaliDate.new(1388,10,11)
|
35
|
+
JalaliDate.yesterday.should == JalaliDate.new(1388,10,10)
|
36
|
+
JalaliDate.tomorrow.should == JalaliDate.new(1388,10,12)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should distinguish invalid jalali dates" do
|
40
|
+
JalaliDate.valid?(1388,13,11).should be_false
|
41
|
+
JalaliDate.valid?(-1388,11,11).should be_false
|
42
|
+
JalaliDate.valid?(1388,1,45).should be_false
|
43
|
+
JalaliDate.valid?(1388,12,30).should be_false
|
44
|
+
JalaliDate.valid?(1387,12,30).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should distinguish leap years" do
|
48
|
+
JalaliDate.leap?(1387).should be_true
|
49
|
+
JalaliDate.leap?(1388).should be_false
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should convert to gregorian date correctly" do
|
53
|
+
jdate = JalaliDate.new(1388,10,11)
|
54
|
+
jdate.to_g.should == Date.new(2010,1,1)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should convert to string, array and hash correctly" do
|
58
|
+
jdate = JalaliDate.new(1388,10,11)
|
59
|
+
jdate.to_s.should == "1388/10/11"
|
60
|
+
jdate.to_a.should == [1388,10,11]
|
61
|
+
jdate.to_hash.should == {:year => 1388, :month => 10, :day => 11}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to add and substract days from the currect jalai date object" do
|
65
|
+
jdate = JalaliDate.new(1388,10,11)
|
66
|
+
five_days_later = jdate + 5
|
67
|
+
twenty_days_ago = jdate - 20
|
68
|
+
five_days_later.should == JalaliDate.new(1388,10,16)
|
69
|
+
twenty_days_ago.should == JalaliDate.new(1388,9,21)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should be able to compare two jalali dates" do
|
73
|
+
jdate = JalaliDate.new(1388,10,11)
|
74
|
+
next_month_jdate = JalaliDate.new(1388,11,11)
|
75
|
+
next_month_jdate.<=>(jdate).should == 1
|
76
|
+
jdate.<=>(next_month_jdate).should == -1
|
77
|
+
jdate.<=>(jdate).should == 0
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should now its next and previous dates" do
|
81
|
+
jdate = JalaliDate.new(1388,10,11)
|
82
|
+
jdate.next.should == JalaliDate.new(1388,10,12)
|
83
|
+
jdate.previous.should == JalaliDate.new(1388,10,10)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be able to move the month forward and backward" do
|
87
|
+
jdate = JalaliDate.new(1388,10,11)
|
88
|
+
five_month_later = jdate >> 5
|
89
|
+
five_month_ago = jdate << 5
|
90
|
+
five_month_later.should == JalaliDate.new(1389,3,11)
|
91
|
+
five_month_ago.should == JalaliDate.new(1388,5,11)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should be able to cycle through dates in different ways, namely, step, upto and downto" do
|
95
|
+
jdate = JalaliDate.new(1388,10,10)
|
96
|
+
|
97
|
+
days_string = ""
|
98
|
+
jdate.step( jdate + 10 , 2) do |jd|
|
99
|
+
days_string += jd.day.to_s
|
100
|
+
end
|
101
|
+
days_string.should == "101214161820"
|
102
|
+
|
103
|
+
days_string = ""
|
104
|
+
jdate.upto(jdate+5) do |jd|
|
105
|
+
days_string += jd.day.to_s
|
106
|
+
end
|
107
|
+
days_string.should == "101112131415"
|
108
|
+
|
109
|
+
days_string = ""
|
110
|
+
jdate.downto(jdate-5) do |jd|
|
111
|
+
days_string += jd.day.to_s
|
112
|
+
end
|
113
|
+
days_string.should == "1098765"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should return a correct year day based on Jalali Calendar" do
|
117
|
+
JalaliDate.new(1388,1,1).yday.should == 1
|
118
|
+
JalaliDate.new(1388,12,29).yday.should == 365
|
119
|
+
JalaliDate.new(1387,12,30).yday.should == 366
|
120
|
+
JalaliDate.new(1388,9,17).yday.should == 263
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should be able to print jalali date in different formats" do
|
124
|
+
JalaliDate.new(1388,1,7).format("%a %A %b %B %d %j %m %w %y %Y %% %x").should == "ج جمعه فروردین فروردین 7 7 1 5 88 1388 % 88/1/7"
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jalalidate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Aziz A. Bargi
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-03 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
31
|
+
version: 1.2.9
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description:
|
35
|
+
email: aziz.bargi@gmail.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- LICENSE
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- TODO
|
48
|
+
- lib/jalalidate.rb
|
49
|
+
- spec/jalalidate_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/aziz/jalalidate
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=UTF-8
|
58
|
+
- --charset
|
59
|
+
- utf-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: JalaliDate
|
79
|
+
rubygems_version: 1.3.6
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: A port of class Date in ruby that works based on Jalali Calendar (a.k.a Persian Calendar)
|
83
|
+
test_files:
|
84
|
+
- spec/jalalidate_spec.rb
|
85
|
+
- spec/spec_helper.rb
|