Class: JalaliDate

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/jalali_date.rb,
lib/jalali_date/cli.rb,
lib/jalali_date/version.rb

Defined Under Namespace

Classes: Cli

Constant Summary collapse

GDaysInMonth =

:stopdoc:

[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
JDaysInMonth =
[31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]
PERSIAN_MONTH_NAMES =
[nil, "فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"]
PERSIAN_MONTH_NAMES_PINGLISH =
[nil, "Farvardin", "Ordibehesht", "Khordad", "Tir", "Mordad", "Shahrivar", "Mehr", "Aban", "Azar", "Dey", "Bahman", "Esfand"]
PERSIAN_WEEKDAY_NAMES =
["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه"]
PERSIAN_ABBR_WEEKDAY_NAMES =
["۱ش ","۲ش","۳ش","۴ش","۵ش","ج ","ش"]
PERSIAN_MERIDIAN_INDICATOR =
["قبل از ظهر","بعد از ظهر"]
PERSIAN_ABBR_MERIDIAN_INDICATOR =
["ق.ظ","ب.ظ"]
VERSION =
"0.3.7"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ JalaliDate

Can be initialized in two ways:

  • First by feeding 3 arguments for Jalali Date, year,month and day.
  • The Second way to initializes is to pass a normal Ruby Date object, it'll be converted to jalali automatically.

Example:

jdate = JalaliDate.new(Date.today)
other_jdate = JalaliDate.new(1388,9,17)

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jalali_date.rb', line 35

def initialize *args
  if (args.size == 1) && (args.first.is_a?(Date))
    year,month,day = gregorian_to_jalali(args.first.year, args.first.month, args.first.day)
  elsif (args.size == 1) && (args.first.is_a?(Time) || args.first.is_a?(DateTime))
    year,month,day = gregorian_to_jalali(args.first.year, args.first.month, args.first.day)
    @hour = args.first.hour || 0
    @min  = args.first.min  || 0
    @sec  = args.first.sec  || 0
    @zone = args.first.zone || "UTC"
    @utc_offset = args.first.utc_offset  || 0
  else
    year,month,day,hour,min,sec,zone,utc_offset = args
  end

  raise ArgumentError, "invalid arguments or invalid Jalali date" unless self.class.valid?(year,month,day)
  @year  = year
  @month = month
  @day   = day
  @hour ||=  hour || 0
  @min  ||=  min  || 0
  @sec  ||=  sec  || 0
  @zone ||=  zone || "UTC"
  @utc_offset ||= utc_offset || 0
  @g_year, @g_month, @g_day = jalali_to_gregorian(year,month,day)
end

Instance Attribute Details

#dayObject

Returns the value of attribute day.



25
26
27
# File 'lib/jalali_date.rb', line 25

def day
  @day
end

#g_dayObject (readonly)

Returns the value of attribute g_day.



26
27
28
# File 'lib/jalali_date.rb', line 26

def g_day
  @g_day
end

#g_monthObject (readonly)

Returns the value of attribute g_month.



26
27
28
# File 'lib/jalali_date.rb', line 26

def g_month
  @g_month
end

#g_yearObject (readonly)

Returns the value of attribute g_year.



26
27
28
# File 'lib/jalali_date.rb', line 26

def g_year
  @g_year
end

#hourObject

Returns the value of attribute hour.



25
26
27
# File 'lib/jalali_date.rb', line 25

def hour
  @hour
end

#minObject

Returns the value of attribute min.



25
26
27
# File 'lib/jalali_date.rb', line 25

def min
  @min
end

#monthObject

Returns the value of attribute month.



25
26
27
# File 'lib/jalali_date.rb', line 25

def month
  @month
end

#secObject

Returns the value of attribute sec.



25
26
27
# File 'lib/jalali_date.rb', line 25

def sec
  @sec
end

#yearObject

Returns the value of attribute year.



25
26
27
# File 'lib/jalali_date.rb', line 25

def year
  @year
end

Class Method Details

.leap?(y) ⇒ Boolean

Accpets a four digit number as the jalaliyear and returns true if that particular year is a leap year in jalali calendar otherwise it returns false.

Returns:

  • (Boolean)


86
87
88
# File 'lib/jalali_date.rb', line 86

def leap?(y)
  [6,22,17,13,9,5,1,30].include?(y%33) ? true : false
end

.parse(s) ⇒ Object

Return JalaliDate from a provided string



79
80
81
82
# File 'lib/jalali_date.rb', line 79

def parse(s)
  date = JalaliDateParser.parse(s)
  date[:jalali]
end

.todayObject

Return a JalaliDate object representing today's date in calendar



64
65
66
# File 'lib/jalali_date.rb', line 64

def today
  JalaliDate.new(Date.today)
end

.tomorrowObject

Return a JalaliDate object representing tomorrow's date in calendar



74
75
76
# File 'lib/jalali_date.rb', line 74

def tomorrow
  JalaliDate.new(Date.today + 1)
end

.valid?(y, m, d) ⇒ Boolean

Accpets three numbers for year (4 digit), month and day in jalali calendar and checks if it's a valid date according to jalali calendar or not.

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
# File 'lib/jalali_date.rb', line 92

def valid?(y,m,d)
  ( y.class == Integer && y > 0 &&
    m.class == Integer && (1..12).include?(m) &&
    d.class == Integer &&
    (
      ((1..JDaysInMonth[m-1]).include?(d)) || (d == 30 && m == 12 && leap?(y))
    )
  ) ? true : false
end

.yesterdayObject

Return a JalaliDate object representing yesterday's date in calendar



69
70
71
# File 'lib/jalali_date.rb', line 69

def yesterday
  JalaliDate.new(Date.today - 1)
end

Instance Method Details

#+(days) ⇒ Object

Adds n days to the current JalaliDate object



132
133
134
# File 'lib/jalali_date.rb', line 132

def +(days)
  self.class.new( to_g + days )
end

#-(days) ⇒ Object

Subtracts n days from the current JalaliDate object



137
138
139
# File 'lib/jalali_date.rb', line 137

def -(days)
  self.class.new( to_g - days )
end

#<<(months) ⇒ Object

Move JalaliDate object backward by n months



167
168
169
# File 'lib/jalali_date.rb', line 167

def <<(months)
  self >> -months
end

#<=>(other) ⇒ Object

Compares two JalaliDate objects. acts like Date#<=>



153
154
155
# File 'lib/jalali_date.rb', line 153

def <=>(other)
  to_g <=> other.to_g
end

#>>(months) ⇒ Object

Move JalaliDate object forward by n months



158
159
160
161
162
163
164
# File 'lib/jalali_date.rb', line 158

def >>(months)
  y, m = (@year * 12 + (@month - 1) + months).divmod(12)
  m,   = (m + 1)                    .divmod(1)
  d = @day
  d -= 1 until self.class.valid?(y, m, d)
  self.class.new(y,m,d)
end

#downto(min, &block) ⇒ Object

Step backward one day at a time until we reach min (inclusive), yielding each date as we go. See #upto for the example.



203
204
205
# File 'lib/jalali_date.rb', line 203

def downto(min, &block)
  step(min, -1, &block)
end

#inspectObject

Return internal object state as a programmer-readable string.



127
128
129
# File 'lib/jalali_date.rb', line 127

def inspect
  "#<#{self.class}:#{self.object_id}, :year => #{@year}, :month => #{@month}, :day => #{@day} >"
end

#jwdayObject

Get the jalali week day of this date. Saturday is day-of-week 0; Friday is day-of-week 6.



218
219
220
# File 'lib/jalali_date.rb', line 218

def jwday
  (to_g.wday + 1) % 7
end

#leap?Boolean

Is this a leap year?

Returns:

  • (Boolean)


208
209
210
# File 'lib/jalali_date.rb', line 208

def leap?
  self.class.leap?(@year)
end

#next(n = 1) ⇒ Object Also known as: succ

Return the next day for the current JalaliDate object



142
143
144
# File 'lib/jalali_date.rb', line 142

def next(n=1)
  self + n
end

#previous(n = 1) ⇒ Object

Return the previous day for the current JalaliDate object



148
149
150
# File 'lib/jalali_date.rb', line 148

def previous(n=1)
  self - n
end

#step(limit, step = 1) ⇒ Object

Step the current date forward step days at a time (or backward, if step is negative) until we reach limit (inclusive), yielding the resultant date at each step.

Example:

jdate = JalaliDate.new(Date.today)
jdate.step(Date.today+10, 2) do |jd|
puts jd.to_s
end


179
180
181
182
183
184
185
186
187
# File 'lib/jalali_date.rb', line 179

def step(limit, step=1)
  da = self
  op = %w(- <= >=)[step <=> 0]
  while da.__send__(op, limit)
    yield da
    da += step
  end
  self
end

#strftime(format_str = '%Y/%m/%d') ⇒ Object Also known as: format

Formats time according to the directives in the given format string. Any text not listed as a directive will be passed through to the output string.

Format meanings:

[%a] The abbreviated weekday name (۳ش) [%A] The full weekday name (یکشنبه) [%b] The month name (اردیبهشت) [%B] The month name in pinglish (Ordibehesht) [%d] Day of the month (01..31) [%e] Day of the month (1..31) [%j] Day of the year (1..366) [%m] Month of the year (1..12) [%n] Month of the year (01..12) [%w] Day of the week (Sunday is 0, 0..6) [%x] Preferred representation for the date alone, no time in format YY/M/D [%y] Year without a century (00..99) [%Y] Year with century [%H] Hour of the day, 24-hour clock (00..23) [%I] Hour of the day, 12-hour clock (01..12) [%M] Minute of the hour (00..59) [%p] Meridian indicator ("بعد از ظهر" or "قبل از ظهر") [%P] Meridian indicator ("ب.ظ" or "ق.ظ") [%S] Second of the minute (00..60) [%X] Preferred representation for the time alone, no date [%Z] Time zone name [%%] Literal %'' character

Example:

d = JalaliDate.today
d.strftime("Printed on %Y/%m/%d")   #=> "Printed on 87/5/26


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/jalali_date.rb', line 260

def strftime(format_str = '%Y/%m/%d')
  clean_fmt = format_str.gsub(/%{2}/, "SUBSTITUTION_MARKER").
    gsub(/%a/, PERSIAN_ABBR_WEEKDAY_NAMES[wday]).
    gsub(/%A/, PERSIAN_WEEKDAY_NAMES[wday]).
    gsub(/%b/, PERSIAN_MONTH_NAMES[@month]).
    gsub(/%B/, PERSIAN_MONTH_NAMES_PINGLISH[@month]).
    gsub(/%d/, ("%02d" % @day).to_s).
    gsub(/%e/, @day.to_s).
    gsub(/%m/, @month.to_s).
   gsub(/%n/, ("%02d" % @month).to_s).
    gsub(/%Y/, @year.to_s).
    gsub(/%y/, @year.to_s.slice(2,2)).
    gsub(/%j/, yday.to_s).
    gsub(/%H/, ("%02d" % @hour).to_s).
    gsub(/%I/, ("%02d" % ((@hour>=12) ? @hour-12 : @hour)).to_s).
    gsub(/%M/, ("%02d" % @min).to_s).
    gsub(/%S/, ("%02d" % @sec).to_s).
    gsub(/%p/, (@hour>=12 ? "بعد از ظهر" : "قبل از ظهر")).
    gsub(/%P/, (@hour>=12 ? "ب.ظ" : "ق.ظ")).
    gsub(/%w/, wday.to_s).
    gsub(/%Z/, @zone).
    gsub(/%X/, [("%02d" % @hour),("%02d" % @min),("%02d" % @sec)].join(":")).
    gsub(/%x/, [@year.to_s.slice(2,2),@month,@day].join("/")).
    gsub(/#{"SUBSTITUTION_MARKER"}/, '%')
end

#to_aObject

Returns an array in a format like this: [y,m,d]



122
123
124
# File 'lib/jalali_date.rb', line 122

def to_a
  [@year,@month,@day]
end

#to_gregorianObject Also known as: to_g

Converts a JalaiDate object to Ruby Date object



106
107
108
# File 'lib/jalali_date.rb', line 106

def to_gregorian
  Date.new(@g_year,@g_month,@g_day)
end

#to_hashObject

Returns a hash in a format like this: => @year, :month => @month, :day => @day



117
118
119
# File 'lib/jalali_date.rb', line 117

def to_hash
  {:year => @year, :month => @month, :day => @day}
end

#to_sObject

Returns a string represtation of the JalaliDate object in format like this: y/m/d



112
113
114
# File 'lib/jalali_date.rb', line 112

def to_s
  [@year,@month,@day].join("/")
end

#upto(max, &block) ⇒ Object

Step forward one day at a time until we reach max (inclusive), yielding each date as we go.

Example:

jdate = JalaliDate.new(Date.today)
days_string = ""
jdate.upto(jdate+5) do |jd|
days_string += jd.day.to_s
end


197
198
199
# File 'lib/jalali_date.rb', line 197

def upto(max, &block)
  step(max, +1, &block)
end

#wdayObject

Get the week day of this date. Sunday is day-of-week 0; Saturday is day-of-week 6.



213
214
215
# File 'lib/jalali_date.rb', line 213

def wday
  to_g.wday
end

#ydayObject

Get the day-of-the-year of this date. Farvardin 1 is day-of-the-year 1



224
225
226
227
# File 'lib/jalali_date.rb', line 224

def yday
  m = (@month-2 < 0) ? 0 : @month-2
  (@month==1) ? @day : @day + JDaysInMonth[0..m].inject(0) {|sum, n| sum + n }
end