Skip to content

Commit

Permalink
Session 11 examples
Browse files Browse the repository at this point in the history
  • Loading branch information
hamed committed Jul 23, 2022
1 parent fbdafe4 commit 4421745
Show file tree
Hide file tree
Showing 52 changed files with 3,199 additions and 0 deletions.
6 changes: 6 additions & 0 deletions 11-Modules/01-Module/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module github.com/naeemaei/test

go 1.18

require github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 // indirect
replace github.com/jalaali/go-jalaali => ./local/go-jalaali
2 changes: 2 additions & 0 deletions 11-Modules/01-Module/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE=
github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE=
21 changes: 21 additions & 0 deletions 11-Modules/01-Module/local/go-jalaali/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Amir Khazaie

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
23 changes: 23 additions & 0 deletions 11-Modules/01-Module/local/go-jalaali/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Jalaali

Golang implementation of [Jalaali JS](https://github.com/jalaali/jalaali-js) and [Jalaali Python](https://github.com/jalaali/jalaali-python) implementations of Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) convertion to Gregorian calendar system and vice-versa.

This implementation is based on an [algorithm by Kazimierz M. Borkowski](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm). Borkowski claims that this algorithm works correctly for 3000 years!

Documentation on API is available [here](https://pkg.go.dev/github.com/jalaali/go-jalaali) at Go official documentation site.

## Installation

Use `go get` on this repository:

```sh
$ go get -u github.com/jalaali/go-jalaali
```

## Usage

* Wrapper around Golang [time package](https://golang.org/pkg/time):
* Call `Jalaali.Now()` to get instance of current time. You can use all function from `time` package with this wrapper.
* Call `Jalaali.From(t)` and pass a `time` instance to it. The you can work with it the same way you work with `time` package.
* Jalaali Formatting:
* Call `JFormat` method of a Jalaali instance and pass it the same formatting options that is used for Golang `time` package. The output will be in Jalaali date and use persian digits and words.
140 changes: 140 additions & 0 deletions 11-Modules/01-Module/local/go-jalaali/convertion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package jalaali

import "time"

var (
breaks = [...]int{-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210,
1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178}
)

// ToJalaali converts Gregorian to Jalaali date. Error is not nil if Jalaali
// year passed to function is not valid.
func ToJalaali(gregorianYear int, gregorianMonth time.Month, gregorianDay int) (int, Month, int, error) {
jy, jm, jd, err := d2j(g2d(gregorianYear, int(gregorianMonth), gregorianDay))
return jy, Month(jm), jd, err
}

// ToGregorian converts Jalaali to Gregorian date. Error is not nil if Jalaali
// year passed to function is not valid.
func ToGregorian(jalaaliYear int, jalaaliMonth Month, jalaaliDay int) (int, time.Month, int, error) {
jdn, err := j2d(jalaaliYear, int(jalaaliMonth), jalaaliDay)
if err != nil {
return 0, 0, 0, err
}

gy, gm, gd := d2g(jdn)
return gy + 1400, time.Month(gm), gd, nil
}

func j2d(jy, jm, jd int) (jdn int, err error) {
_, gy, march, err := jalCal(jy)
if err != nil {
return 0, err
}
return g2d(gy, 3, march) + (jm-1)*31 - div(jm, 7)*(jm-7) + jd - 1, nil
}

func d2j(jdn int) (int, int, int, error) {
gy, _, _ := d2g(jdn) // Calculate Gregorian year (gy).
jy := gy - 621
leap, _, march, err := jalCal(jy)
jdn1f := g2d(gy, 3, march)

if err != nil {
return 0, 0, 0, err
}

// Find number of days that passed since 1 Farvardin.
k := jdn - jdn1f
if k >= 0 {
if k <= 185 {
// The first 6 months.
jm := 1 + div(k, 31)
jd := mod(k, 31) + 1
return jy, jm, jd, nil
}
// The remaining months.
k -= 186
} else {
// Previous Jalaali year.
jy--
k += 179
if leap == 1 {
k++
}
}
jm := 7 + div(k, 30)
jd := mod(k, 30) + 1
return jy, jm, jd, nil
}

func jalCal(jy int) (int, int, int, error) {
bl, gy, leapJ, jp := len(breaks), jy+621, -14, breaks[0]
jump := 0

if jy < jp || jy >= breaks[bl-1] {
return 0, 0, 0, &ErrorInvalidYear{jy}
}

// Find the limiting years for the Jalaali year jy.
for i := 1; i < bl; i++ {
jm := breaks[i]
jump = jm - jp
if jy < jm {
break
}
leapJ += div(jump, 33)*8 + div(mod(jump, 33), 4)
jp = jm
}
n := jy - jp

// Find the number of leap years from AD 621 to the beginning
// of the current Jalaali year in the Persian calendar.
leapJ += div(n, 33)*8 + div(mod(n, 33)+3, 4)
if mod(jump, 33) == 4 && jump-n == 4 {
leapJ++
}

// And the same in the Gregorian calendar (until the year gy).
leapG := div(gy, 4) - div((div(gy, 100)+1)*3, 4) - 150

// Determine the Gregorian date of Farvardin the 1st.
march := 20 + leapJ - leapG

// Find how many years have passed since the last leap year.
if jump-n < 6 {
n -= jump + div(jump+4, 33)*33
}
leap := mod(mod(n+1, 33)-1, 4)
if leap == -1 {
leap = 4
}

return leap, gy, march, nil
}

func g2d(gy, gm, gd int) int {
d := div((gy+div(gm-8, 6)+100100)*1461, 4) +
div(153*mod(gm+9, 12)+2, 5) +
gd - 34840408
d = d - div(div(gy+100100+div(gm-8, 6), 100)*3, 4) + 752
return d
}

func d2g(jdn int) (int, int, int) {
j := 4*jdn + 139361631
j = j + div(div(4*jdn+183187720, 146097)*3, 4)*4 - 3908
i := div(mod(j, 1461), 4)*5 + 308
gd := div(mod(i, 153), 5) + 1
gm := mod(div(i, 153), 12) + 1
gy := div(j, 1461) - 100100 + div(8-gm, 6)
return gy, gm, gd
}

func div(a, b int) int {
return a / b
}

func mod(a, b int) int {
return a % b
}
19 changes: 19 additions & 0 deletions 11-Modules/01-Module/local/go-jalaali/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package jalaali

import "fmt"

// ErrorNilReference is happening when a pointer is nil.
type ErrorNilReference struct{}

// ErrorInvalidYear is happening when year passed is is in proper range.
type ErrorInvalidYear struct {
year int
}

func (e *ErrorNilReference) Error() string {
return "jalaali: reference is nil"
}

func (e *ErrorInvalidYear) Error() string {
return fmt.Sprintf("jalaali: %v is invalid year", e.year)
}
Loading

0 comments on commit 4421745

Please sign in to comment.