mirror of
https://gitee.com/dromara/carbon.git
synced 2024-12-01 19:58:07 +08:00
优化 农历
This commit is contained in:
parent
302960077f
commit
b50061c94f
@ -25,39 +25,44 @@
|
||||
```go
|
||||
// 获取农历生肖
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Animal() // 鼠
|
||||
|
||||
// 获取农历节日
|
||||
carbon.Parse("2021-02-12 13:14:15").Lunar().Festival() // 春节
|
||||
|
||||
// 获取农历年月日时分秒
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().DateTime() // 2020, 6, 16, 13, 14, 15
|
||||
// 获取农历年月日
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Date() // 2020, 6, 16
|
||||
// 获取农历时分秒
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Time() // 13, 14, 15
|
||||
|
||||
// 获取农历年年份
|
||||
// 获取农历年份
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Year() // 2020
|
||||
// 获取农历月月份
|
||||
// 获取农历月份
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Month() // 6
|
||||
// 获取农历闰月月份
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().LeapMonth() // 4
|
||||
// 获取农历日日期
|
||||
// 获取农历日期
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Day() // 16
|
||||
// 获取农历 YYYY-MM-DD HH::ii::ss 格式字符串
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// 获取农历时辰
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Hour() // 13
|
||||
// 获取农历分钟
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Minute() // 14
|
||||
// 获取农历秒数
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Second() // 15
|
||||
|
||||
// 获取农历日期时间字符串
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().String() // 2020-06-16 13:14:15
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// 获取农历年字符串
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToYearString() // 二零二零
|
||||
// 获取农历月字符串
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToMonthString() // 六月
|
||||
// 获取农历闰月字符串
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToMonthString() // 闰四月
|
||||
// 获取农历周字符串
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToWeekString() // 周四
|
||||
// 获取农历天字符串
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDayString() // 十六
|
||||
// 获取农历日期字符串
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDateString() // 二零二零年六月十六
|
||||
|
||||
// 是否是零值时间
|
||||
carbon.Parse("0000-00-00 00:00:00").Lunar().IsZero() // true
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsZero() // false
|
||||
|
||||
// 是否是农历闰年
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsLeapYear() // true
|
||||
// 是否是农历闰月
|
||||
|
@ -25,17 +25,9 @@
|
||||
```go
|
||||
// 旧暦の干支を手に入れる
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Animal() // 鼠
|
||||
|
||||
// 旧暦の祝日を取得する
|
||||
carbon.Parse("2021-02-12 13:14:15").Lunar().Festival() // 春节
|
||||
|
||||
// 旧暦年月日取得時分秒
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().DateTime() // 2020, 6, 16, 13, 14, 15
|
||||
// 旧暦年月日の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Date() // 2020, 6, 16
|
||||
// 旧暦取得時の分秒数
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Time() // 13, 14, 15
|
||||
|
||||
// 旧正月の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Year() // 2020
|
||||
// 旧暦月の取得
|
||||
@ -44,20 +36,33 @@ carbon.Parse("2020-08-05 13:14:15").Lunar().Month() // 6
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().LeapMonth() // 4
|
||||
// 旧暦日の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Day() // 16
|
||||
// 旧暦 YYYY-MM-DD HH::ii::ss フォーマット文字列を取得します
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// 旧暦時刻の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Hour() // 13
|
||||
// 旧暦分の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Minute() // 14
|
||||
// 旧暦の取得秒数
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Second() // 15
|
||||
|
||||
// 旧暦日時文字列の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().String() // 2020-06-16 13:14:15
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// 旧正月文字列の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToYearString() // 二零二零
|
||||
// 旧暦月文字列の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToMonthString() // 六月
|
||||
// 旧暦うるう月文字列の取得
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToMonthString() // 闰四月
|
||||
// 旧暦週文字列の取得
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToWeekString() // 周四
|
||||
// 旧暦日文字列の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDayString() // 十六
|
||||
// 旧暦日付文字列の取得
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDateString() // 二零二零年六月十六
|
||||
|
||||
// ゼロ値の時間ですか
|
||||
carbon.Parse("0000-00-00 00:00:00").Lunar().IsZero() // true
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsZero() // false
|
||||
|
||||
// 旧暦うるう年かどうか
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsLeapYear() // true
|
||||
// 旧暦うるう月かどうか
|
||||
|
@ -28,17 +28,9 @@ by [awesome-go](https://github.com/avelino/awesome-go#date-and-time "awesome-go"
|
||||
```go
|
||||
// Get Lunar year of animal
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Animal() // 鼠
|
||||
|
||||
// Get lunar festival
|
||||
carbon.Parse("2021-02-12 13:14:15").Lunar().Festival() // 春节
|
||||
|
||||
// Get lunar year, month, day, hour, minute and second
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().DateTime() // 2020, 6, 16, 13, 14, 15
|
||||
// Get lunar year, month and day
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Date() // 2020, 6, 16
|
||||
// Get lunar hour, minute and second
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Time() // 13, 14, 15
|
||||
|
||||
// Get lunar year
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Year() // 2020
|
||||
// Get lunar month
|
||||
@ -47,20 +39,33 @@ carbon.Parse("2020-08-05 13:14:15").Lunar().Month() // 6
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().LeapMonth() // 4
|
||||
// Get lunar day
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Day() // 16
|
||||
// Get lunar date as YYYY-MM-DD HH::ii::ss format string
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// Get lunar hour
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Hour() // 13
|
||||
// Get lunar minute
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Minute() // 14
|
||||
// Get lunar second
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().Second() // 15
|
||||
|
||||
// Get lunar date and time string
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().String() // 2020-06-16 13:14:15
|
||||
fmt.Printf("%s", carbon.Parse("2020-08-05 13:14:15").Lunar()) // 2020-06-16 13:14:15
|
||||
// Get lunar year as string
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToYearString() // 二零二零
|
||||
// Get lunar month as string
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToMonthString() // 六月
|
||||
// Get lunar leap month as string
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToMonthString() // 闰四月
|
||||
// Get lunar week as string
|
||||
carbon.Parse("2020-04-23 13:14:15").Lunar().ToWeekString() // 周四
|
||||
// Get lunar day as string
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDayString() // 十六
|
||||
// Get lunar date as string
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().ToDateString() // 二零二零年六月十六
|
||||
|
||||
// Whether is a lunar zero time
|
||||
carbon.Parse("0000-00-00 00:00:00").Lunar().IsZero() // true
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsZero() // false
|
||||
|
||||
// Whether is a lunar leap year
|
||||
carbon.Parse("2020-08-05 13:14:15").Lunar().IsLeapYear() // true
|
||||
// Whether is a lunar leap month
|
||||
|
@ -1,3 +1,4 @@
|
||||
// Package lunar is part of the Carbon package.
|
||||
package lunar
|
||||
|
||||
import (
|
||||
@ -13,6 +14,7 @@ var (
|
||||
|
||||
numbers = []string{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"}
|
||||
months = []string{"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊"}
|
||||
weeks = []string{"周日", "周一", "周二", "周三", "周四", "周五", "周六"}
|
||||
animals = []string{"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"}
|
||||
|
||||
festivals = map[string]string{
|
||||
@ -56,7 +58,7 @@ var (
|
||||
}
|
||||
|
||||
invalidYearError = func() error {
|
||||
return fmt.Errorf("invalid year, currently only 200 years from 1900 to 2100 are supported")
|
||||
return fmt.Errorf("invalid year, outside of range [1900,2100]")
|
||||
}
|
||||
)
|
||||
|
||||
@ -75,14 +77,17 @@ type Lunar struct {
|
||||
}
|
||||
|
||||
// FromGregorian creates a Gregorian instance from time.Time.
|
||||
// 从标准 time.Time 创建 Gregorian 结构体
|
||||
// 从标准 time.Time 创建 Gregorian 实例
|
||||
func FromGregorian(t time.Time) (g Gregorian) {
|
||||
if t.IsZero() {
|
||||
return
|
||||
}
|
||||
g.Time = t
|
||||
return
|
||||
}
|
||||
|
||||
// FromLunar creates a Lunar instance from lunar datetime.
|
||||
// 从 农历日期 创建 Lunar 结构体
|
||||
// 从 农历日期 创建 Lunar 实例
|
||||
func FromLunar(year, month, day, hour, minute, second int, isLeapMonth bool) (l Lunar) {
|
||||
l.year, l.month, l.day = year, month, day
|
||||
l.hour, l.minute, l.second = hour, minute, second
|
||||
@ -90,9 +95,12 @@ func FromLunar(year, month, day, hour, minute, second int, isLeapMonth bool) (l
|
||||
return
|
||||
}
|
||||
|
||||
// ToLunar converts Gregorian calendar to Lunar calendar.
|
||||
// 将 公历 转化为 农历
|
||||
// ToLunar converts Gregorian instance to Lunar instance.
|
||||
// 将 Gregorian 实例转化为 Lunar 实例
|
||||
func (g Gregorian) ToLunar() (l Lunar) {
|
||||
if g.IsZero() {
|
||||
return
|
||||
}
|
||||
daysInYear, daysInMonth, leapMonth := 365, 30, 0
|
||||
if g.Year() < minYear || g.Year() > maxYear {
|
||||
l.Error = invalidYearError()
|
||||
@ -141,9 +149,12 @@ func (g Gregorian) ToLunar() (l Lunar) {
|
||||
return
|
||||
}
|
||||
|
||||
// ToGregorian converts Lunar calendar to Gregorian calendar.
|
||||
// 将 农历 转化为 公历
|
||||
// ToGregorian converts Lunar instance to Gregorian instance.
|
||||
// 将 Lunar 实例转化为 Gregorian 实例
|
||||
func (l Lunar) ToGregorian() (g Gregorian) {
|
||||
if l.IsZero() {
|
||||
return
|
||||
}
|
||||
if l.year < minYear || l.year > maxYear {
|
||||
g.Error = invalidYearError()
|
||||
return
|
||||
@ -162,68 +173,10 @@ func (l Lunar) ToGregorian() (g Gregorian) {
|
||||
return
|
||||
}
|
||||
|
||||
func (g Gregorian) diffInDays(t time.Time) int {
|
||||
return int(g.Time.Sub(t).Hours() / 24)
|
||||
}
|
||||
|
||||
func (l Lunar) getOffsetInYear() int {
|
||||
flag := false
|
||||
clone, month, offset := l, 0, 0
|
||||
for month = 1; month < l.month; month++ {
|
||||
leapMonth := l.LeapMonth()
|
||||
if !flag {
|
||||
// 处理闰月
|
||||
if leapMonth <= month && leapMonth > 0 {
|
||||
offset += l.getDaysInLeapMonth()
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
clone.month = month
|
||||
offset += clone.getDaysInMonth()
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
func (l Lunar) getOffsetInMonth() int {
|
||||
clone, year, offset := l, 0, 0
|
||||
for year = minYear; year < l.year; year++ {
|
||||
clone.year = year
|
||||
offset += clone.getDaysInYear()
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInYear() int {
|
||||
var days = 348
|
||||
for i := 0x8000; i > 0x8; i >>= 1 {
|
||||
if (years[l.year-minYear] & i) != 0 {
|
||||
days++
|
||||
}
|
||||
}
|
||||
return days + l.getDaysInLeapMonth()
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInMonth() int {
|
||||
if (years[l.year-minYear] & (0x10000 >> uint(l.month))) != 0 {
|
||||
return 30
|
||||
}
|
||||
return 29
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInLeapMonth() int {
|
||||
if l.LeapMonth() == 0 {
|
||||
return 0
|
||||
}
|
||||
if years[l.year-minYear]&0x10000 != 0 {
|
||||
return 30
|
||||
}
|
||||
return 29
|
||||
}
|
||||
|
||||
// Animal gets lunar animal name like "猴".
|
||||
// 获取生肖
|
||||
// 获取农历生肖
|
||||
func (l Lunar) Animal() string {
|
||||
if l.Error != nil {
|
||||
if l.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return animals[l.year%calendar.MonthsPerYear]
|
||||
@ -232,14 +185,14 @@ func (l Lunar) Animal() string {
|
||||
// Festival gets lunar festival name like "春节".
|
||||
// 获取农历节日
|
||||
func (l Lunar) Festival() string {
|
||||
if l.Error != nil {
|
||||
if l.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return festivals[fmt.Sprintf("%d-%d", l.month, l.day)]
|
||||
}
|
||||
|
||||
// Year gets lunar year like 2020.
|
||||
// 获取农历年
|
||||
// 获取农历年份
|
||||
func (l Lunar) Year() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
@ -248,7 +201,7 @@ func (l Lunar) Year() int {
|
||||
}
|
||||
|
||||
// Month gets lunar month like 8.
|
||||
// 获取农历月
|
||||
// 获取农历月份
|
||||
func (l Lunar) Month() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
@ -256,17 +209,8 @@ func (l Lunar) Month() int {
|
||||
return l.month
|
||||
}
|
||||
|
||||
// LeapMonth gets lunar leap month like 2.
|
||||
// 获取农历闰月月份
|
||||
func (l Lunar) LeapMonth() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return years[l.year-minYear] & 0xf
|
||||
}
|
||||
|
||||
// Day gets lunar day like 5.
|
||||
// 获取农历日
|
||||
// 获取农历日,如 5
|
||||
func (l Lunar) Day() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
@ -274,13 +218,61 @@ func (l Lunar) Day() int {
|
||||
return l.day
|
||||
}
|
||||
|
||||
// ToYearString outputs a string in lunar year format like "二零二零".
|
||||
// 获取农历年字符串
|
||||
func (l Lunar) ToYearString() string {
|
||||
// Hour gets current hour like 13.
|
||||
// 获取农历时辰
|
||||
func (l Lunar) Hour() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return l.hour
|
||||
}
|
||||
|
||||
// Minute gets current minute like 14.
|
||||
// 获取农历分钟数
|
||||
func (l Lunar) Minute() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return l.minute
|
||||
}
|
||||
|
||||
// Second gets current second like 15.
|
||||
// 获取农历秒数
|
||||
func (l Lunar) Second() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return l.second
|
||||
}
|
||||
|
||||
// LeapMonth gets lunar leap month like 2.
|
||||
// 获取农历闰月月份,如 2
|
||||
func (l Lunar) LeapMonth() int {
|
||||
if l.Error != nil {
|
||||
return 0
|
||||
}
|
||||
if l.year-minYear < 0 {
|
||||
return 0
|
||||
}
|
||||
return years[l.year-minYear] & 0xf
|
||||
}
|
||||
|
||||
// String implements Stringer interface and outputs a string in YYYY-MM-DD HH::ii::ss format like "2019-12-07 00:00:00".
|
||||
// 实现 Stringer 接口, 输出 YYYY-MM-DD HH::ii::ss 格式字符串,如 "2019-12-07 00:00:00"
|
||||
func (l Lunar) String() string {
|
||||
if l.IsZero() {
|
||||
return ""
|
||||
}
|
||||
year := fmt.Sprintf("%d", l.year)
|
||||
return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", l.year, l.month, l.day, l.hour, l.minute, l.second)
|
||||
}
|
||||
|
||||
// ToYearString outputs a string in lunar year format like "二零二零".
|
||||
// 获取农历年份字符串,如 "二零二零"
|
||||
func (l Lunar) ToYearString() (year string) {
|
||||
if l.IsZero() {
|
||||
return
|
||||
}
|
||||
year = fmt.Sprintf("%d", l.year)
|
||||
for index, number := range numbers {
|
||||
year = strings.Replace(year, fmt.Sprintf("%d", index), number, -1)
|
||||
}
|
||||
@ -288,10 +280,10 @@ func (l Lunar) ToYearString() string {
|
||||
}
|
||||
|
||||
// ToMonthString outputs a string in lunar month format like "正月".
|
||||
// 获取农历月字符串
|
||||
// 获取农历月份字符串,如 "正月"
|
||||
func (l Lunar) ToMonthString() (month string) {
|
||||
if l.Error != nil {
|
||||
return ""
|
||||
if l.IsZero() {
|
||||
return
|
||||
}
|
||||
month = months[l.month-1] + "月"
|
||||
if l.IsLeapMonth() {
|
||||
@ -300,10 +292,19 @@ func (l Lunar) ToMonthString() (month string) {
|
||||
return
|
||||
}
|
||||
|
||||
// ToWeekString outputs a string in week layout like "周一".
|
||||
// 输出完整农历星期字符串,如 "周一"
|
||||
func (l Lunar) ToWeekString() (month string) {
|
||||
if l.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return weeks[l.ToGregorian().Week()]
|
||||
}
|
||||
|
||||
// ToDayString outputs a string in lunar day format like "廿一".
|
||||
// 获取农历日字符串
|
||||
// 获取农历日字符串,如 "廿一"
|
||||
func (l Lunar) ToDayString() (day string) {
|
||||
if l.Error != nil {
|
||||
if l.IsZero() {
|
||||
return
|
||||
}
|
||||
num := numbers[l.day%10]
|
||||
@ -325,25 +326,28 @@ func (l Lunar) ToDayString() (day string) {
|
||||
}
|
||||
|
||||
// ToDateString outputs a string in lunar date format like "二零二零年腊月初五".
|
||||
// 获取农历日期字符串
|
||||
// 获取农历日期字符串,如 "二零二零年腊月初五"
|
||||
func (l Lunar) ToDateString() string {
|
||||
if l.Error != nil {
|
||||
if l.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return l.ToYearString() + "年" + l.ToMonthString() + l.ToDayString()
|
||||
}
|
||||
|
||||
// String outputs a string in YYYY-MM-DD HH::ii::ss format, implement Stringer interface.
|
||||
// 输出 YYYY-MM-DD HH::ii::ss 格式字符串,实现 Stringer 接口
|
||||
func (l Lunar) String() string {
|
||||
// IsZero reports whether is zero time.
|
||||
// 是否是农历零值时间
|
||||
func (l Lunar) IsZero() bool {
|
||||
if l.Error != nil {
|
||||
return ""
|
||||
return true
|
||||
}
|
||||
return fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d", l.year, l.month, l.day, l.hour, l.minute, l.second)
|
||||
if l.year == 0 || l.month == 0 || l.day == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLeapYear reports whether is leap year.
|
||||
// 是否是闰年
|
||||
// 是否是农历闰年
|
||||
func (l Lunar) IsLeapYear() bool {
|
||||
if l.Error != nil {
|
||||
return false
|
||||
@ -352,7 +356,7 @@ func (l Lunar) IsLeapYear() bool {
|
||||
}
|
||||
|
||||
// IsLeapMonth reports whether is leap month.
|
||||
// 是否是闰月
|
||||
// 是否是农历闰月
|
||||
func (l Lunar) IsLeapMonth() bool {
|
||||
if l.Error != nil {
|
||||
return false
|
||||
@ -503,3 +507,61 @@ func (l Lunar) IsPigYear() bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g Gregorian) diffInDays(t time.Time) int {
|
||||
return int(g.Time.Sub(t).Hours() / 24)
|
||||
}
|
||||
|
||||
func (l Lunar) getOffsetInYear() int {
|
||||
flag := false
|
||||
clone, month, offset := l, 0, 0
|
||||
for month = 1; month < l.month; month++ {
|
||||
leapMonth := l.LeapMonth()
|
||||
if !flag {
|
||||
// 处理闰月
|
||||
if leapMonth <= month && leapMonth > 0 {
|
||||
offset += l.getDaysInLeapMonth()
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
clone.month = month
|
||||
offset += clone.getDaysInMonth()
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
func (l Lunar) getOffsetInMonth() int {
|
||||
clone, year, offset := l, 0, 0
|
||||
for year = minYear; year < l.year; year++ {
|
||||
clone.year = year
|
||||
offset += clone.getDaysInYear()
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInYear() int {
|
||||
var days = 348
|
||||
for i := 0x8000; i > 0x8; i >>= 1 {
|
||||
if (years[l.year-minYear] & i) != 0 {
|
||||
days++
|
||||
}
|
||||
}
|
||||
return days + l.getDaysInLeapMonth()
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInMonth() int {
|
||||
if (years[l.year-minYear] & (0x10000 >> uint(l.month))) != 0 {
|
||||
return 30
|
||||
}
|
||||
return 29
|
||||
}
|
||||
|
||||
func (l Lunar) getDaysInLeapMonth() int {
|
||||
if l.LeapMonth() == 0 {
|
||||
return 0
|
||||
}
|
||||
if years[l.year-minYear]&0x10000 != 0 {
|
||||
return 30
|
||||
}
|
||||
return 29
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSolarToLunar(t *testing.T) {
|
||||
func TestGregorianToLunar(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
@ -44,6 +44,14 @@ func TestLunarToGregorian(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{Lunar{}},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(0, 0, 0, 0, 0, 0, false)},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 11, 0, 0, 0, false)},
|
||||
want: "2024-01-21 00:00:00",
|
||||
@ -80,6 +88,10 @@ func TestLunar_Animal(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -168,6 +180,10 @@ func TestLunar_Festival(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -232,6 +248,10 @@ func TestLunar_Year(t *testing.T) {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
@ -260,6 +280,10 @@ func TestLunar_Month(t *testing.T) {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
@ -320,34 +344,6 @@ func TestLunar_Month(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_LeapMonth(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2020, 4, 23, 0, 0, 0, 0, time.Local))},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2021, 7, 1, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.g).ToLunar().LeapMonth(), "args{%v}", tt.args.g)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_Day(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
@ -356,6 +352,10 @@ func TestLunar_Day(t *testing.T) {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
@ -384,6 +384,122 @@ func TestLunar_Day(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_Hour(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2020, 8, 19, 13, 14, 15, 0, time.Local))},
|
||||
want: 13,
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.g).ToLunar().Hour(), "args{%v}", tt.args.g)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_Minute(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2020, 8, 19, 13, 14, 15, 0, time.Local))},
|
||||
want: 14,
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.g).ToLunar().Minute(), "args{%v}", tt.args.g)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_Second(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2020, 8, 19, 13, 14, 15, 0, time.Local))},
|
||||
want: 15,
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.g).ToLunar().Second(), "args{%v}", tt.args.g)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_LeapMonth(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2020, 4, 23, 0, 0, 0, 0, time.Local))},
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(2021, 7, 1, 0, 0, 0, 0, time.Local))},
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.g).ToLunar().LeapMonth(), "args{%v}", tt.args.g)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_ToYearString(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
@ -392,6 +508,10 @@ func TestLunar_ToYearString(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -420,6 +540,10 @@ func TestLunar_ToMonthString(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -488,6 +612,54 @@ func TestLunar_ToMonthString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_ToWeekString(t *testing.T) {
|
||||
type args struct {
|
||||
l Lunar
|
||||
}
|
||||
tests := []struct {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{Lunar{}},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(0, 0, 0, 0, 0, 0, false)},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 20, 0, 0, 0, false)},
|
||||
want: "周二",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 21, 0, 0, 0, false)},
|
||||
want: "周三",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 22, 0, 0, 0, false)},
|
||||
want: "周四",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 23, 0, 0, 0, false)},
|
||||
want: "周五",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 24, 0, 0, 0, false)},
|
||||
want: "周六",
|
||||
},
|
||||
{
|
||||
args: args{FromLunar(2023, 12, 25, 0, 0, 0, false)},
|
||||
want: "周日",
|
||||
},
|
||||
}
|
||||
for index, tt := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, (tt.args.l).ToWeekString(), "args{%v}", tt.args.l)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLunar_ToDayString(t *testing.T) {
|
||||
type args struct {
|
||||
g Gregorian
|
||||
@ -496,6 +668,10 @@ func TestLunar_ToDayString(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -576,6 +752,10 @@ func TestLunar_String(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -628,6 +808,10 @@ func TestLunar_ToDateString(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: "",
|
||||
@ -696,6 +880,14 @@ func TestLunar_IsLeapYear(t *testing.T) {
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
args: args{FromGregorian(time.Time{})},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
args: args{FromGregorian(time.Date(0, 0, 0, 0, 0, 0, 0, time.Local))},
|
||||
want: false,
|
||||
|
Loading…
Reference in New Issue
Block a user