Last active
May 15, 2020 18:47
-
-
Save meysampg/84634f90d284faed146e70aa4ae40e9d to your computer and use it in GitHub Desktop.
Calculate some useful infornation on Jalali Calendar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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