├── .gitignore ├── LICENSE ├── README.md ├── README_CN.md ├── calendar.go ├── data.go ├── go.mod ├── lunar.go ├── lunar_test.go └── solar.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 godcong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Calendar Date object interface 2 | ``` 3 | chronos.New() //Create current time 4 | chronos.New(time.Now()) //The parameter is of type time.Time 5 | chronos.New("2017/11/14 08:17") //Parameter is a specified format string 6 | ``` 7 | 8 | # Lunar 农历日期显示 9 | ``` 10 | chronos.New().Lunar() //Get the lunar calendar 11 | ``` 12 | # Solar 公历日期显示 13 | ``` 14 | chornos.New().Solar() //Get the solar calendar 15 | ``` 16 | 17 | 18 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # Calendar 日期对象接口 2 | ``` 3 | chronos.New() //创建当前时间 4 | chronos.New(time.Now()) //该参数的类型为time.Time 5 | chronos.New("2017/11/14 08:17") //参数是指定格式的字符串#年/月/日 时:分# 6 | ``` 7 | 8 | # Lunar 农历日期显示 9 | ``` 10 | chronos.New().Lunar() //获取月历 11 | ``` 12 | # Solar 公历日期显示 13 | ``` 14 | chornos.New().Solar() //获取日历 15 | ``` 16 | 17 | 18 | -------------------------------------------------------------------------------- /calendar.go: -------------------------------------------------------------------------------- 1 | package chronos 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // DateFormat ... 8 | const DateFormat = "2006/01/02 15:04" 9 | const LunarDateFormat = "2006/01/02" 10 | 11 | type calendar struct { 12 | time time.Time 13 | } 14 | 15 | // Calendar ... 16 | type Calendar interface { 17 | Lunar() *Lunar 18 | Solar() *Solar 19 | LunarDate() string 20 | } 21 | 22 | //New can input three type of time to create the calendar 23 | //"2006/01/02 03:04" format string 24 | // time.Time value 25 | // or nil to create a new time.Now() value 26 | func New(v ...interface{}) Calendar { 27 | var c Calendar 28 | if v == nil { 29 | return &calendar{time.Now()} 30 | } 31 | switch vv := v[0].(type) { 32 | case nil: 33 | c = &calendar{time.Now()} 34 | case string: 35 | c = formatDate(vv) 36 | case time.Time: 37 | c = &calendar{vv} 38 | } 39 | return c 40 | } 41 | 42 | func formatDate(s string) Calendar { 43 | t, err := time.Parse(DateFormat, s) 44 | if err != nil { 45 | t = time.Now() 46 | } 47 | return &calendar{ 48 | time: t, 49 | } 50 | } 51 | 52 | // Lunar ... 53 | func (c *calendar) Lunar() *Lunar { 54 | return CalculateLunar(c.time.Format(DateFormat)) 55 | } 56 | 57 | // Solar ... 58 | func (c *calendar) Solar() *Solar { 59 | return &Solar{time: c.time} 60 | } 61 | 62 | // LunarDate ... 63 | func (c *calendar) LunarDate() string { 64 | return c.Lunar().Date() 65 | } 66 | -------------------------------------------------------------------------------- /data.go: -------------------------------------------------------------------------------- 1 | package chronos 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | const ( 9 | cvalue20 = iota 10 | cvalue21 11 | cvalue22 12 | ) 13 | 14 | var ctable = []float64{ 15 | cvalue20: 4.6295, 16 | cvalue21: 3.87, 17 | cvalue22: 4.15, 18 | } 19 | var heavenlyStem = []string{ 20 | `甲`, `乙`, `丙`, `丁`, `戊`, `己`, `庚`, `辛`, `壬`, `癸`, 21 | } 22 | 23 | var earthyBranch = []string{ 24 | `子`, `丑`, `寅`, `卯`, `辰`, `巳`, `午`, `未`, `申`, `酉`, `戌`, `亥`, 25 | } 26 | 27 | var zodiacs = []string{ 28 | `鼠`, `牛`, `虎`, `兔`, `龙`, `蛇`, `马`, `羊`, `猴`, `鸡`, `狗`, `猪`, 29 | } 30 | 31 | var stemBranchTable = []string{ 32 | `甲子`, `乙丑`, `丙寅`, `丁卯`, `戊辰`, `己巳`, `庚午`, `辛未`, `壬申`, `癸酉`, `甲戌`, `乙亥`, //甲或己日 33 | `丙子`, `丁丑`, `戊寅`, `己卯`, `庚辰`, `辛巳`, `壬午`, `癸未`, `甲申`, `乙酉`, `丙戌`, `丁亥`, //乙或庚日 34 | `戊子`, `己丑`, `庚寅`, `辛卯`, `壬辰`, `癸巳`, `甲午`, `乙未`, `丙申`, `丁酉`, `戊戌`, `己亥`, //丙或辛日 35 | `庚子`, `辛丑`, `壬寅`, `癸卯`, `甲辰`, `乙巳`, `丙午`, `丁未`, `戊申`, `己酉`, `庚戌`, `辛亥`, //丁或壬日 36 | `壬子`, `癸丑`, `甲寅`, `乙卯`, `丙辰`, `丁巳`, `戊午`, `己未`, `庚申`, `辛酉`, `壬戌`, `癸亥`, //戊或癸日 37 | } 38 | 39 | var yearNumber = []int{ 40 | 0x9, 0xE, 0x13, 0x18, 0x1E, 0x23, 0x28, 0x2D, 0x33, 0x38, //1900-1909 41 | 0x1, 0x6, 0xC, 0x11, 0x16, 0x1B, 0x21, 0x26, 0x2B, 0x30, //1910-1919 42 | 0x36, 0x3B, 0x4, 0x9, 0xF, 0x14, 0x19, 0x1E, 0x24, 0x36, //1920-1929 43 | 0x2E, 0x33, 0x39, 0x2, 0x7, 0xC, 0x12, 0x17, 0x1C, 0x2E, //1930-1939 44 | 0x27, 0x2C, 0x31, 0x36, 0x0, 0x5, 0xA, 0xF, 0x15, 0x1A, //1940-1949 45 | 0x1F, 0x24, 0x2A, 0x2F, 0x34, 0x39, 0x3, 0x8, 0xD, 0x12, //1950-1959 46 | 0x18, 0x1D, 0x22, 0x27, 0x2D, 0x32, 0x37, 0x0, 0x6, 0xB, //1960-1969 47 | 0x10, 0x15, 0x1B, 0x20, 0x25, 0x2A, 0x30, 0x35, 0x3A, 0x3, //1970-1979 48 | 0x9, 0xE, 0x13, 0x18, 0x1E, 0x23, 0x28, 0x2D, 0x33, 0x38, //1980-1989 49 | 0x1, 0x6, 0xC, 0x11, 0x16, 0x1B, 0x21, 0x26, 0x2B, 0x30, //1990-1999 50 | 0x36, 0x3B, 0x4, 0x9, 0xF, 0x14, 0x19, 0x1E, 0x24, 0x29, //2000-2009 51 | 0x2E, 0x33, 0x39, 0x2, 0x7, 0xC, 0x12, 0x17, 0x1C, 0x21, //2010-2019 52 | 0x27, 0x2C, 0x31, 0x36, 0x0, 0x5, 0xA, 0xF, 0x15, 0x1A, //2020-2029 53 | 0x1F, 0x24, 0x2A, 0x2F, 0x34, 0x39, 0x3, 0x8, 0xD, 0x12, //2030-2039 54 | 0x18, 0x1D, 0x22, 0x27, 0x2D, 0x32, 0x37, 0x0, 0x6, 0xB, //2040-2049 55 | 0x10, 0x15, 0x1B, 0x20, 0x25, 0x2A, 0x30, 0x35, 0x3A, 0x3, //2050-2059 56 | 0x9, 0xE, 0x13, 0x18, 0x1E, 0x23, 0x28, 0x2D, 0x33, 0x38, //2060-2069 57 | 0x1, 0x6, 0xC, 0x11, 0x16, 0x1B, 0x21, 0x26, 0x2B, 0x30, //2070-2079 58 | 0x36, 0x3B, 0x4, 0x9, 0xF, 0x14, 0x19, 0x1E, 0x24, 0x29, //2080-2089 59 | 0x2E, 0x33, 0x39, 0x2, 0x7, 0xC, 0x12, 0x17, 0x1C, 0x21, //2090-2099 60 | } 61 | 62 | var monthNumber = []int{ 63 | 0x6, //next year 1 64 | 0x25, //next year 2 65 | 0x0, //3 66 | 0x1F, //4 67 | 0x1, //5 68 | 0x20, //6 69 | 0x2, //7 70 | 0x21, //8 71 | 0x4, //9 72 | 0x22, //10 73 | 0x5, //11 74 | 0x23, //12 75 | } 76 | 77 | var lunarInfoList = []int{ 78 | 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909 79 | 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919 80 | 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929 81 | 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 82 | 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949 83 | 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959 84 | 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969 85 | 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979 86 | 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989 87 | 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 88 | 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009 89 | 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019 90 | 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 91 | 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 92 | 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049 93 | 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059 94 | 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 95 | 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079 96 | 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089 97 | 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099 98 | 0x0d520, //2100 99 | } 100 | 101 | var termInfoList = []string{ 102 | `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf97c3598082c95f8c965cc920f`, `97bd0b06bdb0722c965ce1cfcc920f`, `b027097bd097c36b0b6fc9274c91aa`, 103 | `97b6b97bd19801ec9210c965cc920e`, `97bcf97c359801ec95f8c965cc920f`, `97bd0b06bdb0722c965ce1cfcc920f`, `b027097bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, 104 | `97bcf97c359801ec95f8c965cc920f`, `97bd0b06bdb0722c965ce1cfcc920f`, `b027097bd097c36b0b6fc9274c91aa`, `9778397bd19801ec9210c965cc920e`, `97b6b97bd19801ec95f8c965cc920f`, 105 | `97bd09801d98082c95f8e1cfcc920f`, `97bd097bd097c36b0b6fc9210c8dc2`, `9778397bd197c36c9210c9274c91aa`, `97b6b97bd19801ec95f8c965cc920e`, `97bd09801d98082c95f8e1cfcc920f`, 106 | `97bd097bd097c36b0b6fc9210c8dc2`, `9778397bd097c36c9210c9274c91aa`, `97b6b97bd19801ec95f8c965cc920e`, `97bcf97c3598082c95f8e1cfcc920f`, `97bd097bd097c36b0b6fc9210c8dc2`, 107 | `9778397bd097c36c9210c9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf97c3598082c95f8c965cc920f`, `97bd097bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, 108 | `97b6b97bd19801ec9210c965cc920e`, `97bcf97c3598082c95f8c965cc920f`, `97bd097bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, 109 | `97bcf97c359801ec95f8c965cc920f`, `97bd097bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf97c359801ec95f8c965cc920f`, 110 | `97bd097bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf97c359801ec95f8c965cc920f`, `97bd097bd07f595b0b6fc920fb0722`, 111 | `9778397bd097c36b0b6fc9210c8dc2`, `9778397bd19801ec9210c9274c920e`, `97b6b97bd19801ec95f8c965cc920f`, `97bd07f5307f595b0b0bc920fb0722`, `7f0e397bd097c36b0b6fc9210c8dc2`, 112 | `9778397bd097c36c9210c9274c920e`, `97b6b97bd19801ec95f8c965cc920f`, `97bd07f5307f595b0b0bc920fb0722`, `7f0e397bd097c36b0b6fc9210c8dc2`, `9778397bd097c36c9210c9274c91aa`, 113 | `97b6b97bd19801ec9210c965cc920e`, `97bd07f1487f595b0b0bc920fb0722`, `7f0e397bd097c36b0b6fc9210c8dc2`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, 114 | `97bcf7f1487f595b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf7f1487f595b0b0bb0b6fb0722`, 115 | `7f0e397bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf7f1487f531b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, 116 | `9778397bd097c36b0b6fc9274c91aa`, `97b6b97bd19801ec9210c965cc920e`, `97bcf7f1487f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, 117 | `97b6b97bd19801ec9210c9274c920e`, `97bcf7f0e47f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, `9778397bd097c36b0b6fc9210c91aa`, `97b6b97bd197c36c9210c9274c920e`, 118 | `97bcf7f0e47f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, `9778397bd097c36b0b6fc9210c8dc2`, `9778397bd097c36c9210c9274c920e`, `97b6b7f0e47f531b0723b0b6fb0722`, 119 | `7f0e37f5307f595b0b0bc920fb0722`, `7f0e397bd097c36b0b6fc9210c8dc2`, `9778397bd097c36b0b70c9274c91aa`, `97b6b7f0e47f531b0723b0b6fb0721`, `7f0e37f1487f595b0b0bb0b6fb0722`, 120 | `7f0e397bd097c35b0b6fc9210c8dc2`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f595b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, 121 | `9778397bd097c36b0b6fc9274c91aa`, `97b6b7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, 122 | `97b6b7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b7f0e47f531b0723b0b6fb0721`, 123 | `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, `9778397bd097c36b0b6fc9274c91aa`, `97b6b7f0e47f531b0723b0787b0721`, `7f0e27f0e47f531b0b0bb0b6fb0722`, 124 | `7f0e397bd07f595b0b0bc920fb0722`, `9778397bd097c36b0b6fc9210c91aa`, `97b6b7f0e47f149b0723b0787b0721`, `7f0e27f0e47f531b0723b0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, 125 | `9778397bd097c36b0b6fc9210c8dc2`, `977837f0e37f149b0723b0787b0721`, `7f07e7f0e47f531b0723b0b6fb0722`, `7f0e37f5307f595b0b0bc920fb0722`, `7f0e397bd097c35b0b6fc9210c8dc2`, 126 | `977837f0e37f14998082b0787b0721`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e37f1487f595b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc9210c8dc2`, `977837f0e37f14998082b0787b06bd`, 127 | `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, `977837f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, 128 | `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd097c35b0b6fc920fb0722`, `977837f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, 129 | `7f0e397bd07f595b0b0bc920fb0722`, `977837f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, 130 | `977837f0e37f14998082b0787b06bd`, `7f07e7f0e47f149b0723b0787b0721`, `7f0e27f0e47f531b0b0bb0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, `977837f0e37f14998082b0723b06bd`, 131 | `7f07e7f0e37f149b0723b0787b0721`, `7f0e27f0e47f531b0723b0b6fb0722`, `7f0e397bd07f595b0b0bc920fb0722`, `977837f0e37f14898082b0723b02d5`, `7ec967f0e37f14998082b0787b0721`, 132 | `7f07e7f0e47f531b0723b0b6fb0722`, `7f0e37f1487f595b0b0bb0b6fb0722`, `7f0e37f0e37f14898082b0723b02d5`, `7ec967f0e37f14998082b0787b0721`, `7f07e7f0e47f531b0723b0b6fb0722`, 133 | `7f0e37f1487f531b0b0bb0b6fb0722`, `7f0e37f0e37f14898082b0723b02d5`, `7ec967f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e37f1487f531b0b0bb0b6fb0722`, 134 | `7f0e37f0e37f14898082b072297c35`, `7ec967f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e37f0e37f14898082b072297c35`, 135 | `7ec967f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e37f0e366aa89801eb072297c35`, `7ec967f0e37f14998082b0787b06bd`, 136 | `7f07e7f0e47f149b0723b0787b0721`, `7f0e27f1487f531b0b0bb0b6fb0722`, `7f0e37f0e366aa89801eb072297c35`, `7ec967f0e37f14998082b0723b06bd`, `7f07e7f0e47f149b0723b0787b0721`, 137 | `7f0e27f0e47f531b0723b0b6fb0722`, `7f0e37f0e366aa89801eb072297c35`, `7ec967f0e37f14998082b0723b06bd`, `7f07e7f0e37f14998083b0787b0721`, `7f0e27f0e47f531b0723b0b6fb0722`, 138 | `7f0e37f0e366aa89801eb072297c35`, `7ec967f0e37f14898082b0723b02d5`, `7f07e7f0e37f14998082b0787b0721`, `7f07e7f0e47f531b0723b0b6fb0722`, `7f0e36665b66aa89801e9808297c35`, 139 | `665f67f0e37f14898082b0723b02d5`, `7ec967f0e37f14998082b0787b0721`, `7f07e7f0e47f531b0723b0b6fb0722`, `7f0e36665b66a449801e9808297c35`, `665f67f0e37f14898082b0723b02d5`, 140 | `7ec967f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e36665b66a449801e9808297c35`, `665f67f0e37f14898082b072297c35`, `7ec967f0e37f14998082b0787b06bd`, 141 | `7f07e7f0e47f531b0723b0b6fb0721`, `7f0e26665b66a449801e9808297c35`, `665f67f0e37f1489801eb072297c35`, `7ec967f0e37f14998082b0787b06bd`, `7f07e7f0e47f531b0723b0b6fb0721`, 142 | `7f0e27f1487f531b0b0bb0b6fb0722`, //2100 143 | } 144 | 145 | var number = []string{`一`, `二`, `三`, `四`, `五`, `六`, `七`, `八`, `九`, `十`, `十一`, `十二`} 146 | var ten = []string{`初`, `十`, `廿`, `卅`} 147 | 148 | //月历月份 149 | var chineseNumber = []string{`正`, `二`, `三`, `四`, `五`, `六`, `七`, `八`, `九`, `十`, `十一`, `腊`} 150 | 151 | //公历每个月份的天数 152 | var monthDay = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 153 | 154 | //12星座 155 | var constellation = []string{ 156 | `魔羯`, `水瓶`, `双鱼`, `白羊`, `金牛`, `双子`, `巨蟹`, `狮子`, `处女`, `天秤`, `天蝎`, `射手`, 157 | } 158 | 159 | func fixSuffix(y int) int { 160 | return y - 1900 161 | } 162 | 163 | //GetLunarInfo 取得月历信息 164 | func GetLunarInfo(y int) int { 165 | y = fixSuffix(y) 166 | if y < 0 || y > len(lunarInfoList) { 167 | return 0 168 | } 169 | return lunarInfoList[y] 170 | } 171 | 172 | // GetTermInfo ... 173 | func GetTermInfo(y, n int) int { 174 | y = fixSuffix(y) 175 | if y < 0 || y > len(termInfoList) { 176 | return -1 177 | } 178 | if n < 1 || n > 24 { 179 | return -1 180 | } 181 | i := (n - 1) / 4 * 5 182 | n = (n - 1) % 4 183 | idx, _ := strconv.ParseInt(termInfoList[y][i:i+5], 16, 64) 184 | a := strconv.FormatInt(idx, 10) 185 | day := []string{a[0:1], a[1:3], a[3:4], a[4:6]} 186 | i, _ = strconv.Atoi(day[n]) 187 | return i 188 | } 189 | 190 | func getChineseYear(year int) string { 191 | return StemBranchYear(year) + "年" 192 | } 193 | 194 | //getChineseMonth 取得月历月 195 | func getChineseMonth(m int) string { 196 | if m > 12 || m < 1 { 197 | return "?月" 198 | } 199 | return chineseNumber[m-1] + "月" //加上月字 200 | } 201 | 202 | //getChineseDay 取得月历日 203 | func getChineseDay(d int) string { 204 | if d < 0 || d > 31 { 205 | return "?日" 206 | } 207 | var s string 208 | switch d { 209 | case 10: 210 | s = `初十` 211 | case 20: 212 | s = `二十` 213 | case 30: 214 | s = `三十` 215 | default: 216 | n := (d - 1) % 10 217 | s = ten[d/10] + number[n] 218 | } 219 | return s + "日" 220 | 221 | } 222 | 223 | //GetStemBranch 取得干支 224 | func GetStemBranch(y int) string { 225 | return heavenlyStem[y%10] + earthyBranch[y%12] 226 | } 227 | 228 | //StemBranchHour 获取时柱 229 | //  子   丑   寅   卯   辰   己 230 | //   23-01:01-03:03-05 :05-07:07-09:09-11 231 | //   午   未   申   酉   戊   亥 232 | //   11-13:13-15:15-17:17-19:19-21:21-23 233 | //`甲子`, `乙丑`, `丙寅`, `丁卯`, `戊辰`, `己巳`, `庚午`, `辛未`, `壬申`, `癸酉`, `甲戌`, `乙亥`, //甲或己日 234 | //`丙子`, `丁丑`, `戊寅`, `己卯`, `庚辰`, `辛巳`, `壬午`, `癸未`, `甲申`, `乙酉`, `丙戌`, `丁亥`, //乙或庚日 235 | //`戊子`, `己丑`, `庚寅`, `辛卯`, `壬辰`, `癸巳`, `甲午`, `乙未`, `丙申`, `丁酉`, `戊戌`, `己亥`, //丙或辛日 236 | //`庚子`, `辛丑`, `壬寅`, `癸卯`, `甲辰`, `乙巳`, `丙午`, `丁未`, `戊申`, `己酉`, `庚戌`, `辛亥`, //丁或壬日 237 | //`壬子`, `癸丑`, `甲寅`, `乙卯`, `丙辰`, `丁巳`, `戊午`, `己未`, `庚申`, `辛酉`, `壬戌`, `癸亥`, //戊或癸日 238 | func StemBranchHour(y, m, d, h int) string { 239 | i := stemBranchIndex(y, m, d) % 5 * 12 240 | idx := (h + 1) / 2 % 12 241 | return stemBranchTable[fixDayNext(i, idx, h)] 242 | } 243 | 244 | //待优化 245 | func fixDayNext(row int, idx int, hour int) int { 246 | if hour >= 23 { 247 | idx += 12 248 | } 249 | if row+idx >= 60 { 250 | return row + idx - 60 251 | } 252 | return row + idx 253 | } 254 | 255 | func stemBranchIndex(y, m, d int) int { 256 | y = fixSuffix(y) 257 | if y < 0 || y > len(yearNumber) { 258 | return 0 259 | } 260 | if m < 3 { 261 | y-- 262 | } 263 | m = (m - 1) % 12 264 | return (yearNumber[y] + monthNumber[m] + d - 1) % 60 265 | } 266 | 267 | // StemBranchDay 获取日柱 268 | func StemBranchDay(y, m, d int) string { 269 | return stemBranchTable[stemBranchIndex(y, m, d)] 270 | } 271 | 272 | //StemBranchMonth 获取月柱 273 | func StemBranchMonth(y, m, d int) string { 274 | //月柱 1900年1月小寒以前为 丙子月(60进制12) 275 | fir := GetTermInfo(y, m*2-1) //返回当月「节」为几日开始 276 | 277 | //依据12节气修正干支月 278 | var sb = GetStemBranch(fixSuffix(y)*12 + m + 11) 279 | if d >= fir { 280 | sb = GetStemBranch(fixSuffix(y)*12 + m + 12) 281 | } 282 | return sb 283 | } 284 | 285 | //StemBranchYear 获取年柱 286 | func StemBranchYear(y int) string { 287 | num := y - 4 288 | return heavenlyStem[num%10] + earthyBranch[num%12] 289 | } 290 | 291 | func centuryCValue(y int) float64 { 292 | switch { 293 | case y > 1901 && y <= 2000: 294 | return ctable[cvalue20] 295 | case y >= 2001 && y <= 2100: 296 | return ctable[cvalue21] 297 | case y >= 2101 && y <= 2200: 298 | return ctable[cvalue22] 299 | } 300 | panic(fmt.Sprintf("not supported(%d)", y)) 301 | } 302 | 303 | func getLiChunDay(year int) int { 304 | c := centuryCValue(year) 305 | y := float64(year % 100) 306 | l := int((y - 1) / 4) 307 | return int((y*0.2422+c)/1 - float64(l)) 308 | 309 | } 310 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/godcong/chronos 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /lunar.go: -------------------------------------------------------------------------------- 1 | package chronos 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | // Lunar ... 10 | type Lunar struct { 11 | time.Time 12 | year int 13 | month int 14 | day int 15 | hour int 16 | leapMonth int 17 | leap bool 18 | fixLiChun int //立春当天如果未到时辰:-1 19 | } 20 | 21 | var loc *time.Location 22 | 23 | func init() { 24 | loc, _ = time.LoadLocation("Local") 25 | } 26 | 27 | func (lunar *Lunar) isLeap() bool { 28 | if lunar.leap && (lunar.month == lunar.leapMonth) { 29 | return true 30 | } 31 | return false 32 | } 33 | 34 | // Type ... 35 | func (lunar *Lunar) Type() string { 36 | return "lunar" 37 | } 38 | 39 | func (lunar *Lunar) FixLiChun(fix int) { 40 | lunar.fixLiChun = fix 41 | } 42 | 43 | // Calendar ... 44 | func (lunar *Lunar) Calendar() Calendar { 45 | t := time.Time{} 46 | t.AddDate(lunar.year, lunar.month, lunar.day) 47 | return New(t) 48 | } 49 | 50 | // EightCharacter ... 51 | func (lunar *Lunar) EightCharacter() []string { 52 | rlt := lunar.nianZhu(lunar.fixLiChun) + lunar.yueZhu() + lunar.riZhu() + lunar.shiZhu() 53 | return strings.Split(rlt, "") 54 | } 55 | 56 | //shiZhu 时柱 57 | func (lunar *Lunar) shiZhu() string { 58 | return StemBranchHour(lunar.Year(), int(lunar.Month()), lunar.Day(), lunar.Hour()) 59 | } 60 | 61 | //riZhu 日柱 62 | func (lunar *Lunar) riZhu() string { 63 | if lunar.Hour() >= 23 { 64 | return StemBranchDay(lunar.Year(), int(lunar.Month()), lunar.Day()+1) 65 | } 66 | return StemBranchDay(lunar.Year(), int(lunar.Month()), lunar.Day()) 67 | } 68 | 69 | //yueZhu 月柱 70 | func (lunar *Lunar) yueZhu() string { 71 | return StemBranchMonth(lunar.Year(), int(lunar.Month()), lunar.Day()) 72 | } 73 | 74 | //nianZhu 年柱 75 | func (lunar *Lunar) nianZhu(fix int) string { 76 | //log.Println("year", lunar.Year(), "nyear", lunar.year, "month", lunar.Month(), "day", lunar.Day(), "lichun", getLiChunDay(lunar.Year())) 77 | if lunar.Month() > 2 || (lunar.Month() == 2 && lunar.Day() >= getLiChunDay(lunar.Year())) { 78 | return StemBranchYear(lunar.Year() + fix) 79 | } 80 | return StemBranchYear(lunar.Year() - 1) 81 | } 82 | 83 | // GetZodiac ... 84 | func GetZodiac(lunar *Lunar) string { 85 | s := string([]rune(lunar.nianZhu(lunar.fixLiChun))[1]) 86 | for idx, v := range earthyBranch { 87 | if strings.Compare(v, s) == 0 { 88 | return zodiacs[idx] 89 | } 90 | } 91 | return "" 92 | } 93 | 94 | func yearDay(y int) int { 95 | i, sum := 348, 348 96 | for i = 0x8000; i > 0x8; i >>= 1 { 97 | if (GetLunarInfo(y) & i) != 0 { 98 | sum++ 99 | } 100 | } 101 | return sum + leapDay(y) 102 | } 103 | 104 | func leapDay(y int) int { 105 | if leapMonth(y) != 0 { 106 | if (GetLunarInfo(y) & 0x10000) != 0 { 107 | return 30 108 | } 109 | return 29 110 | } 111 | return 0 112 | } 113 | 114 | func leapMonth(y int) int { 115 | return GetLunarInfo(y) & 0xf 116 | } 117 | 118 | func monthDays(y int, m int) int { 119 | //月份参数从1至12,参数错误返回-1 120 | if m > 12 || m < 1 { 121 | return -1 122 | } 123 | if GetLunarInfo(y)&(0x10000>>uint32(m)) != 0 { 124 | return 30 125 | } 126 | return 29 127 | } 128 | 129 | func solarDays(y, m int) int { 130 | //若参数错误 返回-1 131 | if m > 12 || m < 1 { 132 | return -1 133 | } 134 | var idx = m - 1 135 | if idx == 1 { //2月份的闰平规律测算后确认返回28或29 136 | if (y%4 == 0) && (y%100 != 0) || (y%400 == 0) { 137 | return 29 138 | } 139 | return 28 140 | } 141 | return monthDay[idx] 142 | } 143 | 144 | //GetAstro 取得星座 145 | func GetAstro(m, d int) string { 146 | arr := []int{20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22} 147 | idx := d < arr[m-1] 148 | index := m * 2 149 | if idx { 150 | index = m*2 - 2 151 | } 152 | return constellation[index] + "座" 153 | } 154 | 155 | func lunarYear(offset int) (int, int) { 156 | day := 0 157 | i := 0 158 | //求当年农历年天数 159 | for i = yearMin; i <= yearMax; i++ { 160 | day = yearDay(i) 161 | if offset-day < 1 { 162 | break 163 | } 164 | offset -= day 165 | } 166 | return i, offset 167 | } 168 | 169 | func lunarStart() time.Time { 170 | loc, _ := time.LoadLocation("Local") 171 | start, err := time.ParseInLocation("2006/01/02", "1900/01/30", loc) 172 | if err != nil { 173 | fmt.Println(err.Error()) 174 | } 175 | return start 176 | } 177 | 178 | func lunarInput(date string) time.Time { 179 | 180 | input, err := time.ParseInLocation(DateFormat, date, loc) 181 | if err != nil { 182 | fmt.Println(err.Error()) 183 | return time.Time{} 184 | } 185 | //newInput, err := time.ParseInLocation(LunarDateFormat, input.Format(LunarDateFormat), loc) 186 | //if err != nil { 187 | // fmt.Println(err.Error()) 188 | // return time.Time{} 189 | //} 190 | return input 191 | } 192 | 193 | // CalculateLunar ... 194 | func CalculateLunar(date string) *Lunar { 195 | input := lunarInput(date) 196 | lunar := Lunar{ 197 | Time: input, 198 | leap: false, 199 | } 200 | 201 | i, day := 0, 0 202 | isLeapYear := false 203 | 204 | start := lunarStart() 205 | offset := betweenDay(input, start) 206 | year, offset := lunarYear(offset) 207 | lunar.leapMonth = leapMonth(year) //计算该年闰哪个月 208 | 209 | //设定当年是否有闰月 210 | if lunar.leapMonth > 0 { 211 | isLeapYear = true 212 | } 213 | 214 | for i = 1; i <= 12; i++ { 215 | if i == lunar.leapMonth+1 && isLeapYear { 216 | day = leapDay(year) 217 | isLeapYear = false 218 | lunar.leap = true 219 | i-- 220 | } else { 221 | day = monthDays(year, i) 222 | } 223 | offset -= day 224 | if offset <= 0 { 225 | break 226 | } 227 | } 228 | 229 | offset += day 230 | lunar.month = i 231 | lunar.day = offset 232 | lunar.year = year 233 | return &lunar 234 | 235 | } 236 | 237 | //betweenDay 计算两个时间差的天数 238 | func betweenDay(d time.Time, s time.Time) int { 239 | newInput, err := time.ParseInLocation(LunarDateFormat, d.Format(LunarDateFormat), loc) 240 | if err != nil { 241 | return 0 242 | } 243 | 244 | subValue := float64(newInput.Unix()-s.Unix())/86400.0 + 0.5 245 | return int(subValue) 246 | } 247 | 248 | //Solar2Lunar 输入日历输出月历 249 | func Solar2Lunar(time time.Time) string { 250 | lunar := CalculateLunar(time.Format(DateFormat)) 251 | result := StemBranchYear(lunar.year) + "年" 252 | if lunar.leap && (lunar.month == lunar.leapMonth) { 253 | result += "闰" 254 | } 255 | result += getChineseMonth(lunar.month) 256 | result += getChineseDay(lunar.day) 257 | return result 258 | } 259 | 260 | // Date ... 261 | func (lunar *Lunar) Date() string { 262 | result := getChineseYear(lunar.year) 263 | if lunar.isLeap() { 264 | result += "闰" 265 | } 266 | result += getChineseMonth(lunar.month) 267 | result += getChineseDay(lunar.day) 268 | return result 269 | } 270 | 271 | const yearMin = 1900 272 | const yearMax = 2100 273 | 274 | var solarTerms = []string{ 275 | `小寒`, `大寒`, `立春`, `雨水`, `惊蛰`, `春分`, `清明`, `谷雨`, `立夏`, `小满`, `芒种`, `夏至`, `小暑`, `大暑`, `立秋`, `处暑`, `白露`, `秋分`, `寒露`, `霜降`, `立冬`, `小雪`, `大雪`, `冬至`, 276 | } 277 | 278 | //一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月 :年份 279 | //var ChinesMonth = []string{ 280 | // `丙寅`, `丁卯`, `戊辰`, `己巳`, `庚午`, `辛未`, `壬申`, `癸酉`, `甲戌`, `乙亥`, `丙子`, `丁丑`, //甲、己 281 | // `戊寅`, `己卯`, `庚辰`, `辛巳`, `壬午`, `癸未`, `甲申`, `乙酉`, `丙戌`, `丁亥`, `戊子`, `己丑`, //乙、庚 282 | // `庚寅`, `辛卯`, `壬辰`, `癸巳`, `甲午`, `乙未`, `丙申`, `丁酉`, `戊戌`, `己亥`, `庚子`, `辛丑`, //丙、辛 283 | // `壬寅`, `癸卯`, `甲辰`, `乙巳`, `丙午`, `丁未`, `戊申`, `己酉`, `庚戌`, `辛亥`, `壬子`, `癸丑`, //丁、壬 284 | // `甲寅`, `乙卯`, `丙辰`, `丁巳`, `戊午`, `己未`, `庚申`, `辛酉`, `壬戌`, `癸亥`, `甲子`, `乙丑`, //戊、癸 285 | //} 286 | -------------------------------------------------------------------------------- /lunar_test.go: -------------------------------------------------------------------------------- 1 | package chronos_test 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strconv" 7 | "testing" 8 | "time" 9 | 10 | "github.com/godcong/chronos" 11 | ) 12 | 13 | // TestGetSolarTerm ... 14 | func TestGetSolarTerm(t *testing.T) { 15 | 16 | } 17 | 18 | // TestYearDays ... 19 | func TestYearDays(t *testing.T) { 20 | 21 | } 22 | 23 | // TestGetDayString ... 24 | func TestGetDayString(t *testing.T) { 25 | //log.Println(GetDayString(20)) 26 | //reader := transform.NewReader(strings.NewReader(, simplifiedchinese.GB18030.NewDecoder()) 27 | //all, _ := ioutil.ReadAll(reader) 28 | fmt.Println(strconv.Itoa(0x97783), strconv.Itoa(0x97bd0), strconv.Itoa(0x97c36), strconv.Itoa(0xb0b6f), strconv.Itoa(0xc9274), strconv.Itoa(0xc91aa)) 29 | } 30 | 31 | // TestGetTerm ... 32 | func TestGetTerm(t *testing.T) { 33 | for i := 1; i <= 24; i++ { 34 | i := chronos.GetTermInfo(2018, i) 35 | log.Println(i) 36 | } 37 | 38 | } 39 | 40 | // TestGetZodiac ... 41 | func TestGetZodiac(t *testing.T) { 42 | t.Log(chronos.GetZodiac(chronos.New("2020/01/24 18:40").Lunar()) == "猪") 43 | t.Log(chronos.GetZodiac(chronos.New("2020/01/25 18:40").Lunar()) == "鼠") 44 | t.Log(chronos.GetZodiac(chronos.New("2021/02/11 18:40").Lunar()) == "鼠") 45 | t.Log(chronos.GetZodiac(chronos.New("2021/02/12 18:40").Lunar()) == "牛") 46 | } 47 | 48 | // TestStemBranchYear ... 49 | func TestStemBranchYear(t *testing.T) { 50 | log.Println(chronos.StemBranchYear(2017)) 51 | 52 | } 53 | 54 | // TestStemBranchMonth ... 55 | func TestStemBranchMonth(t *testing.T) { 56 | log.Println(chronos.StemBranchMonth(2017, 11, 14)) 57 | } 58 | 59 | // TestStemBranchDay ... 60 | func TestStemBranchDay(t *testing.T) { 61 | log.Println(chronos.StemBranchDay(2017, 11, 14)) 62 | 63 | } 64 | 65 | // TestStemBranchHour ... 66 | func TestStemBranchHour(t *testing.T) { 67 | log.Print(12, chronos.StemBranchDay(2018, 1, 12), "日") 68 | for i := 0; i <= 23; i++ { 69 | 70 | log.Println(i, chronos.StemBranchHour(2019, 11, 2, i)) 71 | 72 | } 73 | log.Print(13, chronos.StemBranchHour(2018, 1, 13, 8), "日") 74 | log.Print(14, chronos.StemBranchDay(2017, 11, 14), "日") 75 | log.Println(8, chronos.StemBranchHour(2017, 11, 14, 8)) 76 | } 77 | 78 | // TestNewLunar ... 79 | func TestNewLunar(t *testing.T) { 80 | log.Print(chronos.New().Lunar().Date()) 81 | } 82 | 83 | // TestCalculateLunar ... 84 | func TestCalculateLunar(t *testing.T) { 85 | //log.Print("now: ", chronos.Solar2Lunar(time.Parse())) 86 | //检查日柱是否正确 87 | log.Print(chronos.New("2019/10/31 23:13").Lunar().EightCharacter()) 88 | log.Print(chronos.New("2019/11/01 0:13").Lunar().EightCharacter()) 89 | log.Print(chronos.New("2019/11/01 1:13").Lunar().EightCharacter()) 90 | 91 | //检查立春是否有效 92 | log.Print(chronos.New("2020/02/03 23:13").Lunar().EightCharacter()) 93 | log.Print(chronos.New("2020/02/04 1:13").Lunar().EightCharacter()) 94 | log.Print(chronos.New("2020/02/04 18:13").Lunar().EightCharacter()) 95 | 96 | log.Print(chronos.New("2020/01/24 0:40").LunarDate()) 97 | 98 | log.Print(chronos.New("2020/01/25 0:40").LunarDate()) 99 | log.Print(chronos.New(time.Now()).LunarDate()) 100 | 101 | log.Print(chronos.New("1989/01/07 18:40").Lunar().EightCharacter()) 102 | 103 | //output:戊辰年十一月三十日 104 | log.Print(chronos.New("1989/01/07 18:40").LunarDate()) 105 | log.Print(chronos.New("1989/01/07 0:40").LunarDate()) 106 | 107 | log.Print(chronos.New("2019/06/01 0:40").LunarDate()) 108 | 109 | } 110 | 111 | func TestLunar_EightCharacter(t *testing.T) { 112 | //output 己 亥 甲 戌 庚 子 丁 丑 113 | log.Println(chronos.New("2019/10/30 01:30").Lunar().EightCharacter()) 114 | //output 己 亥 甲 戌 庚 子 丙 子 115 | log.Println(chronos.New("2019/10/30 23:00").Lunar().EightCharacter()) 116 | log.Println(chronos.New("2019/10/31 00:30").Lunar().EightCharacter()) 117 | 118 | } 119 | -------------------------------------------------------------------------------- /solar.go: -------------------------------------------------------------------------------- 1 | package chronos 2 | 3 | import "time" 4 | 5 | // Solar ... 6 | type Solar struct { 7 | time time.Time 8 | } 9 | 10 | // NewSolar ... 11 | func NewSolar(calendar Calendar) *Solar { 12 | return calendar.Solar() 13 | } 14 | 15 | func (s *Solar) Time() time.Time { 16 | return s.time 17 | } 18 | --------------------------------------------------------------------------------