class Persian::Date

Persian count class Basic counters for persian chars, texts, sentences and paragraphs

Public Instance Methods

d2g(jdn) click to toggle source
# File lib/persian/date.rb, line 120
def d2g(jdn)
  j = 4 * jdn + 139_361_631
  j = j + div(div(4 * jdn + 183_187_720, 146_097) * 3, 4) * 4 - 3_908
  i = div(mod(j, 1_461), 4) * 5 + 308
  gd = div(mod(i, 153), 5) + 1
  gm = mod(div(i, 153), 12) + 1
  gy = div(j, 1_461) - 100_100 + div(8 - gm, 6)

  { gy: gy,
    gm: gm,
    gd: gd }
end
d2j(jdn) click to toggle source
# File lib/persian/date.rb, line 79
def d2j(jdn)
  gy = d2g(jdn)[:gy]
  jy = gy - 621
  r = jal_cal(jy)
  jdn1f = g2d(gy, 3, r[:march])

  k = jdn - jdn1f
  if k >= 0
    (
    if k <= 185
      jm = 1 + div(k, 31)
      jd = mod(k, 31) + 1
      return {
        jy: jy,
        jm: jm,
        jd: jd
      }
    else
      k -= 186
    end
    )
  else
    jy -= 1
    k += 179
    k += 1 if r[:leap] == 1
  end
  jm = 7 + div(k, 30)
  jd = mod(k, 30) + 1

  {
    jy: jy,
    jm: jm,
    jd: jd
  }
end
div(a, b) click to toggle source
# File lib/persian/date.rb, line 133
def div(a, b)
  tilde(a / b.to_f)
end
g2d(gy, gm, gd) click to toggle source
# File lib/persian/date.rb, line 115
def g2d(gy, gm, gd)
  d = div((gy + div(gm - 8, 6) + 100_100) * 1_461, 4) + div(153 * mod(gm + 9, 12) + 2, 5) + gd - 34_840_408
  d - div(div(gy + 100_100 + div(gm - 8, 6), 100) * 3, 4) + 752
end
j2d(jy, jm, jd) click to toggle source
# File lib/persian/date.rb, line 74
def j2d(jy, jm, jd)
  r = jal_cal(jy)
  g2d(r[:gy], 3, r[:march]) + (jm - 1) * 31 - div(jm, 7) * (jm - 7) + jd - 1
end
jal_cal(jy) click to toggle source
# File lib/persian/date.rb, line 30
def jal_cal(jy)
  breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210,
            1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178]

  bl = breaks.size
  gy = jy + 621
  leap_j = -14
  jp = breaks[0]

  raise Error if jy < jp || jy >= breaks[bl - 1]

  jump = nil

  1.upto(bl - 1) do |i|
    jm = breaks[i]
    jump = jm - jp

    break if jy < jm

    leap_j = leap_j + div(jump, 33) * 8 + div(mod(jump, 33), 4)
    jp = jm
  end

  n = jy - jp

  leap_j = leap_j + div(n, 33) * 8 + div(mod(n, 33), 4)

  leap_j += 1 if mod(jump, 33) == 4 && jump - n == 4

  leap_g = div(gy, 4) - div((div(gy, 100) + 1) * 3, 4) - 150

  march = 20 + leap_j - leap_g

  n = n - jump + div(jump + 4, 33) * 33 if jump - n < 6

  leap = mod(mod(n + 1, 33) - 1, 4)

  leap = 4 if leap == -1

  { leap: leap,
    gy: gy,
    march: march }
end
jalali_month_length(jy, jm) click to toggle source
# File lib/persian/date.rb, line 23
def jalali_month_length(jy, jm)
  return 31 if jm <= 6
  return 30 if jm <= 11
  return 30 if leap_jalali_year?(jy)
  29
end
leap_jalali_year?(jy) click to toggle source
# File lib/persian/date.rb, line 19
def leap_jalali_year?(jy)
  jal_cal(jy)[:leap].zero?
end
mod(a, b) click to toggle source
# File lib/persian/date.rb, line 137
def mod(a, b)
  a - tilde(a / b.to_f) * b
end
tilde(num) click to toggle source
# File lib/persian/date.rb, line 141
def tilde(num)
  if num < 0
    num.ceil
  else
    num.floor
  end
end
to_gregorian(jy, jm, jd) click to toggle source
# File lib/persian/date.rb, line 11
def to_gregorian(jy, jm, jd)
  d2g(j2d(jy, jm, jd))
end
to_jalali(gy, gm, gd) click to toggle source
# File lib/persian/date.rb, line 7
def to_jalali(gy, gm, gd)
  d2j(g2d(gy, gm, gd))
end
valid_jalali_date?(jy, jm, jd) click to toggle source
# File lib/persian/date.rb, line 15
def valid_jalali_date?(jy, jm, jd)
  jy >= -61 && jy <= 3177 && jm >= 1 && jm <= 12 && jd >= 1 && jd <= jalali_month_length(jy, jm)
end