Skip to content

Instantly share code, notes, and snippets.

@qa1
Forked from meysampg/jalaali_utils.go
Created May 15, 2020 18:47
Show Gist options
  • Save qa1/da071ab3a212567a443e08dbbb069a7a to your computer and use it in GitHub Desktop.
Save qa1/da071ab3a212567a443e08dbbb069a7a to your computer and use it in GitHub Desktop.
Calculate some useful infornation on Jalali Calendar
// algorithms from php version of https://jdf.scr.ir/download/
package cal
import (
"log"
"strconv"
"strings"
"time"
"github.com/jalaali/go-jalaali"
)
var enToFa = strings.NewReplacer(
"۰", "0",
"۱", "1",
"۲", "2",
"۳", "3",
"۴", "4",
"۵", "5",
"۶", "6",
"۷", "7",
"۸", "8",
"۹", "9",
)
type IJalali interface {
From(t time.Time) IJalali
Format(format string) string
Year() int
Season() int
Month() int
Day() int
DayOfWeek() int
DayOfYear() int
WeekOfMonth() int
WeekOfYear() int
}
type Jalali struct {
_jalali jalaali.Jalaali
}
func New() IJalali {
return &Jalali{}
}
func (j *Jalali) From(t time.Time) IJalali {
j._jalali = jalaali.From(t)
return j
}
func (j *Jalali) Format(format string) string {
f, err := j._jalali.JFormat(format)
if err != nil {
log.Log.Errorf("error on parsing Jalali format, %s", err)
}
return enToFa.Replace(f)
}
func atoi(s string) int {
i, err := strconv.Atoi(s)
if err != nil {
log.Log.Errorf("error on converting %s to int, %s", s, err)
return -1
}
return i
}
func (j *Jalali) Year() int {
return atoi(j.Format("2006"))
}
func (j *Jalali) Month() int {
return atoi(j.Format("1"))
}
func (j *Jalali) Season() int {
switch month := j.Month(); {
case 1 <= month && month <= 3:
return 0
case 4 <= month && month <= 6:
return 1
case 7 <= month && month <= 9:
return 2
case 10 <= month && month <= 12:
return 3 // thanks to my ghashang Arman
default:
return -1
}
}
func (j *Jalali) Day() int {
return atoi(j.Format("2"))
}
func (j *Jalali) DayOfWeek() int {
return (int(j._jalali.Weekday()) + 1) % 7
}
func (j *Jalali) DayOfYear() int {
d := j.Day()
if d == -1 {
return -1
}
m := j.Month()
if m == -1 {
return -1
}
if m < 7 {
return (m-1)*31 + d
}
return (m-7)*30 + d + 186
}
func (j *Jalali) WeekOfMonth() int {
d := j.Day()
if d == -1 {
return -1
}
return d / 7
}
// I don't know what this f*ing s*t is doing, but it works
func (j *Jalali) WeekOfYear() int {
y := j.Year()
if y == -1 {
return -1
}
dow := j.DayOfWeek()
if dow == -1 {
return -1
}
doy := j.DayOfYear()
if doy == -1 {
return -1
}
avs := dow - (doy % 7)
if avs < 7 {
avs += 7
}
n := (doy + avs) / 7
if avs < 4 {
n += 1
} else if n < 1 {
var coy int
if int(float32(y%33)*0.05) == (((y % 33) % 4) - 2) {
coy = 5
} else {
coy = 4
}
if avs == 4 || avs == coy {
n = 53
} else {
n = 52
}
}
isLeap, err := jalaali.IsLeapYear(y)
if err != nil {
log.Log.Errorf("error on identifying leap year (%d), %s", y, err)
return -1
}
var kab int
if isLeap {
kab = 1
}
aks := avs + kab
if aks == 7 {
aks = 0
}
if kab+363-doy < aks && aks < 3 {
return 1
}
return n
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment