lunar_calendar 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +52 -0
- data/README.md +67 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/lunar_calendar.rb +24 -0
- data/lib/lunar_calendar/calculator/lunar.rb +76 -0
- data/lib/lunar_calendar/data/leap_months.rb +65 -0
- data/lib/lunar_calendar/data/new_years.rb +65 -0
- data/lib/lunar_calendar/date.rb +54 -0
- data/lib/lunar_calendar/lunar.rb +26 -0
- data/lib/lunar_calendar/lunar_year.rb +32 -0
- data/lib/lunar_calendar/solar.rb +33 -0
- data/lib/lunar_calendar/utils.rb +37 -0
- data/lib/lunar_calendar/version.rb +5 -0
- data/lunar_calendar.gemspec +30 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 98a2793caf8f76e1eda5668de1d1ae67b30ce24411e80f14402cbb90b1a11ef4
|
4
|
+
data.tar.gz: 921e3dfb0fb431293f8e8f47c42ed20d31ea5867401421ac8b07979de9dfe97d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 30bceb3fad47074ac31226db31d12b3bc6ec54a9ac24fc30e817d274372d28f25c602f45afa119b02fe63ac44434038e8b18165c9b77fac02c6b9eed21381ce1
|
7
|
+
data.tar.gz: f68df0d348d325f053103af9f875c16129f16f3633724d2754a4061ec942cdf2d92ea6fcab38d6c28070b54c879955a560326c65c4231299315e51bb41e44dcb
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at elct9620@frost.tw. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: https://contributor-covenant.org
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
lunar_calendar (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.0)
|
10
|
+
diff-lcs (1.3)
|
11
|
+
jaro_winkler (1.5.4)
|
12
|
+
parallel (1.19.1)
|
13
|
+
parser (2.7.1.0)
|
14
|
+
ast (~> 2.4.0)
|
15
|
+
rainbow (3.0.0)
|
16
|
+
rake (12.3.3)
|
17
|
+
rexml (3.2.4)
|
18
|
+
rspec (3.9.0)
|
19
|
+
rspec-core (~> 3.9.0)
|
20
|
+
rspec-expectations (~> 3.9.0)
|
21
|
+
rspec-mocks (~> 3.9.0)
|
22
|
+
rspec-core (3.9.1)
|
23
|
+
rspec-support (~> 3.9.1)
|
24
|
+
rspec-expectations (3.9.0)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.9.0)
|
27
|
+
rspec-mocks (3.9.1)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.9.0)
|
30
|
+
rspec-support (3.9.2)
|
31
|
+
rubocop (0.80.1)
|
32
|
+
jaro_winkler (~> 1.5.1)
|
33
|
+
parallel (~> 1.10)
|
34
|
+
parser (>= 2.7.0.1)
|
35
|
+
rainbow (>= 2.2.2, < 4.0)
|
36
|
+
rexml
|
37
|
+
ruby-progressbar (~> 1.7)
|
38
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
39
|
+
ruby-progressbar (1.10.1)
|
40
|
+
unicode-display_width (1.6.1)
|
41
|
+
|
42
|
+
PLATFORMS
|
43
|
+
ruby
|
44
|
+
|
45
|
+
DEPENDENCIES
|
46
|
+
lunar_calendar!
|
47
|
+
rake (~> 12.0)
|
48
|
+
rspec (~> 3.0)
|
49
|
+
rubocop (~> 0.80.1)
|
50
|
+
|
51
|
+
BUNDLED WITH
|
52
|
+
2.1.2
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# LunarCalendar
|
2
|
+
|
3
|
+
Convert Solar Date to Lunar Date
|
4
|
+
|
5
|
+
## Reference
|
6
|
+
|
7
|
+
* Table data from [isee15/Lunar-Solar-Calendar-Converter](https://github.com/isee15/Lunar-Solar-Calendar-Converter)
|
8
|
+
* Calculate discussion from [https://destiny.to/](https://destiny.to/ubbthreads/ubbthreads.php/ubb/showflat/Number/92769/site_id/1#import)
|
9
|
+
|
10
|
+
## Data Structure
|
11
|
+
|
12
|
+
### LunarCalendar::Data::NEW_YEARS
|
13
|
+
|
14
|
+
Each value stores the Chinese New Year date in solar calendar
|
15
|
+
|
16
|
+
| Name | Length
|
17
|
+
|------|--------
|
18
|
+
| Year | 12 bit
|
19
|
+
| Month | 4 bit
|
20
|
+
| Day | 5 bit
|
21
|
+
|
22
|
+
### LunarCalendar::Data::LEAP_MONTHS
|
23
|
+
|
24
|
+
Each value stores the month days and leap month
|
25
|
+
|
26
|
+
| Name | Length | Description
|
27
|
+
|------|--------|--------------
|
28
|
+
| Leap Month | 4 bit | `0` means this year no leap month
|
29
|
+
| Months | 12 bit | `1` is 30 days and `0` is 29 days
|
30
|
+
|
31
|
+
## Installation
|
32
|
+
|
33
|
+
Add this line to your application's Gemfile:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
gem 'lunar_calendar'
|
37
|
+
```
|
38
|
+
|
39
|
+
And then execute:
|
40
|
+
|
41
|
+
$ bundle install
|
42
|
+
|
43
|
+
Or install it yourself as:
|
44
|
+
|
45
|
+
$ gem install lunar_calendar
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
LunarCalendar.at_lunar(2020, 1, 1)
|
51
|
+
# => #<LunarCalendar::Lunar @year=2019 @month=12 @day=7>
|
52
|
+
```
|
53
|
+
|
54
|
+
## Development
|
55
|
+
|
56
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
57
|
+
|
58
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/elct9620/lunar_calendar. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/elct9620/lunar_calendar/blob/master/CODE_OF_CONDUCT.md).
|
63
|
+
|
64
|
+
|
65
|
+
## Code of Conduct
|
66
|
+
|
67
|
+
Everyone interacting in the LunarCalendar project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/elct9620/lunar_calendar/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'lunar_calendar'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/version'
|
4
|
+
require 'lunar_calendar/solar'
|
5
|
+
require 'lunar_calendar/lunar'
|
6
|
+
|
7
|
+
# The Lunar Calendar Calculator
|
8
|
+
module LunarCalendar
|
9
|
+
# @since 0.1.0
|
10
|
+
SUPPORT_YEARS = (1888..2100).freeze
|
11
|
+
|
12
|
+
# Convert Solar to Lunar
|
13
|
+
#
|
14
|
+
# @param year [Number] year
|
15
|
+
# @param month [Number] month
|
16
|
+
# @param day [Number] day
|
17
|
+
#
|
18
|
+
# @return [LunarCalendar::Solar] the lunar date
|
19
|
+
#
|
20
|
+
# @since 0.1.0
|
21
|
+
def self.at_lunar(year, month, day)
|
22
|
+
Solar.new(year, month, day).to_lunar
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/data/new_years'
|
4
|
+
require 'lunar_calendar/utils'
|
5
|
+
require 'lunar_calendar/lunar_year'
|
6
|
+
|
7
|
+
module LunarCalendar
|
8
|
+
module Calculator
|
9
|
+
# The Lunar Date Calculator
|
10
|
+
class Lunar
|
11
|
+
# @param date [LunarCalendar::Solar] the solar date
|
12
|
+
#
|
13
|
+
# @since 0.1.0
|
14
|
+
def initialize(solar)
|
15
|
+
@solar = solar
|
16
|
+
@lunar_year = LunarYear.new(position)
|
17
|
+
@year = position + LunarCalendar::SUPPORT_YEARS.begin
|
18
|
+
@month = 1
|
19
|
+
@day = 1
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [LunarCalendar::Lunar] the lunar date
|
23
|
+
#
|
24
|
+
# @since 0.1.0
|
25
|
+
def perform
|
26
|
+
move_days
|
27
|
+
|
28
|
+
@month -= 1 if leap?
|
29
|
+
|
30
|
+
LunarCalendar::Lunar.new(@year, @month, @day, leap_month?)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Number] position of table
|
34
|
+
#
|
35
|
+
# @since 0.1.0
|
36
|
+
def position
|
37
|
+
return @position unless @position.nil?
|
38
|
+
|
39
|
+
index = @solar.year - LunarCalendar::SUPPORT_YEARS.begin
|
40
|
+
# If new years in the previous year
|
41
|
+
index -= 1 if LunarCalendar::Data::NEW_YEARS[index] > @solar.binary
|
42
|
+
@position = index
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def leap_month?
|
48
|
+
return false if @month != @lunar_year.leap_month + 1
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def leap?
|
54
|
+
return false if @lunar_year.leap_month.zero?
|
55
|
+
return false if @lunar_year.leap_month >= @month
|
56
|
+
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
def move_days
|
61
|
+
@day = offset + 1
|
62
|
+
@lunar_year.month_days.each do |days_in_month|
|
63
|
+
break if days_in_month >= @day
|
64
|
+
|
65
|
+
@month += 1
|
66
|
+
@day -= days_in_month
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def offset
|
71
|
+
@offset ||=
|
72
|
+
@solar.to_i - LunarCalendar::Utils.new_year_at(position).to_i
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LunarCalendar
|
4
|
+
module Data
|
5
|
+
# @since 0.1.0
|
6
|
+
LEAP_MONTHS = [
|
7
|
+
0x1694, 0x16AA, 0x4AD5, 0xAB6,
|
8
|
+
0xC4B7, 0x4AE, 0xA56, 0xB52A,
|
9
|
+
0x1D2A, 0xD54, 0x75AA, 0x156A,
|
10
|
+
0x1096D, 0x95C, 0x14AE, 0xAA4D,
|
11
|
+
0x1A4C, 0x1B2A, 0x8D55, 0xAD4,
|
12
|
+
0x135A, 0x495D, 0x95C, 0xD49B,
|
13
|
+
0x149A, 0x1A4A, 0xBAA5, 0x16A8,
|
14
|
+
0x1AD4, 0x52DA, 0x12B6, 0XE937,
|
15
|
+
0x92E, 0x1496, 0xB64B, 0xD4A,
|
16
|
+
0xDA8, 0x95B5, 0x56C, 0x12AE,
|
17
|
+
0x492F, 0x92E, 0xCC96, 0x1A94,
|
18
|
+
0x1D4A, 0xADA9, 0xB5A, 0x56C,
|
19
|
+
0x726E, 0x125C, 0xF92D, 0x192A,
|
20
|
+
0x1A94, 0xDB4A, 0x16AA, 0xAD4,
|
21
|
+
0x955B, 0x4BA, 0x125A, 0x592B,
|
22
|
+
0x152A, 0xF695, 0xD94, 0x16AA,
|
23
|
+
0xAAB5, 0x9B4, 0x14B6, 0x6A57,
|
24
|
+
0xA56, 0x1152A, 0x1D2A, 0xD54,
|
25
|
+
0xD5AA, 0x156A, 0x96C, 0x94AE,
|
26
|
+
0x14AE, 0xA4C, 0x7D26, 0x1B2A,
|
27
|
+
0XEB55, 0xAD4, 0x12DA, 0xA95D,
|
28
|
+
0x95A, 0x149A, 0x9A4D, 0x1A4A,
|
29
|
+
0x11AA5, 0x16A8, 0x16D4, 0xD2DA,
|
30
|
+
0x12B6, 0x936, 0x9497, 0x1496,
|
31
|
+
0x1564B, 0xD4A, 0xDA8, 0xD5B4,
|
32
|
+
0x156C, 0x12AE, 0xA92F, 0x92E,
|
33
|
+
0xC96, 0x6D4A, 0x1D4A, 0x10D65,
|
34
|
+
0xB58, 0x156C, 0xB26D, 0x125C,
|
35
|
+
0x192C, 0x9A95, 0x1A94, 0x1B4A,
|
36
|
+
0x4B55, 0xAD4, 0xF55B, 0x4BA,
|
37
|
+
0x125A, 0xB92B, 0x152A, 0x1694,
|
38
|
+
0x96AA, 0x15AA, 0x12AB5, 0x974,
|
39
|
+
0x14B6, 0xCA57, 0xA56, 0x1526,
|
40
|
+
0x8E95, 0xD54, 0x15AA, 0x49B5,
|
41
|
+
0x96C, 0xD4AE, 0x149C, 0x1A4C,
|
42
|
+
0xBD26, 0x1AA6, 0xB54, 0x6D6A,
|
43
|
+
0x12DA, 0x1695D, 0x95A, 0x149A,
|
44
|
+
0xDA4B, 0x1A4A, 0x1AA4, 0xBB54,
|
45
|
+
0x16B4, 0xADA, 0x495B, 0x936,
|
46
|
+
0xF497, 0x1496, 0x154A, 0xB6A5,
|
47
|
+
0xDA4, 0x15B4, 0x6AB6, 0x126E,
|
48
|
+
0x1092F, 0x92E, 0xC96, 0xCD4A,
|
49
|
+
0x1D4A, 0xD64, 0x956C, 0x155C,
|
50
|
+
0x125C, 0x792E, 0x192C, 0xFA95,
|
51
|
+
0x1A94, 0x1B4A, 0xAB55, 0xAD4,
|
52
|
+
0x14DA, 0x8A5D, 0xA5A, 0x1152B,
|
53
|
+
0x152A, 0x1694, 0xD6AA, 0x15AA,
|
54
|
+
0xAB4, 0x94BA, 0x14B6, 0xA56,
|
55
|
+
0x7527, 0xD26, 0XEE53, 0xD54,
|
56
|
+
0x15AA, 0xA9B5, 0x96C, 0x14AE,
|
57
|
+
0x8A4E, 0x1A4C, 0x11D26, 0x1AA4,
|
58
|
+
0x1B54, 0xCD6A, 0xADA, 0x95C,
|
59
|
+
0x949D, 0x149A, 0x1A2A, 0x5B25,
|
60
|
+
0x1AA4, 0xFB52, 0x16B4, 0xABA,
|
61
|
+
0xA95B, 0x936, 0x1496, 0x9A4B,
|
62
|
+
0x154A, 0x136A5, 0xDA4, 0x15AC
|
63
|
+
].freeze
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LunarCalendar
|
4
|
+
module Data
|
5
|
+
# @since 0.1.0
|
6
|
+
NEW_YEARS = [
|
7
|
+
0xec04c, 0xec23f, 0xec435, 0xec649,
|
8
|
+
0xec83e, 0xeca51, 0xecc46, 0xece3a,
|
9
|
+
0xed04d, 0xed242, 0xed436, 0xed64a,
|
10
|
+
0xed83f, 0xeda53, 0xedc48, 0xede3d,
|
11
|
+
0xee050, 0xee244, 0xee439, 0xee64d,
|
12
|
+
0xee842, 0xeea36, 0xeec4a, 0xeee3e,
|
13
|
+
0xef052, 0xef246, 0xef43a, 0xef64e,
|
14
|
+
0xef843, 0xefa37, 0xefc4b, 0xefe41,
|
15
|
+
0xf0054, 0xf0248, 0xf043c, 0xf0650,
|
16
|
+
0xf0845, 0xf0a38, 0xf0c4d, 0xf0e42,
|
17
|
+
0xf1037, 0xf124a, 0xf143e, 0xf1651,
|
18
|
+
0xf1846, 0xf1a3a, 0xf1c4e, 0xf1e44,
|
19
|
+
0xf2038, 0xf224b, 0xf243f, 0xf2653,
|
20
|
+
0xf2848, 0xf2a3b, 0xf2c4f, 0xf2e45,
|
21
|
+
0xf3039, 0xf324d, 0xf3442, 0xf3636,
|
22
|
+
0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46,
|
23
|
+
0xf403b, 0xf424e, 0xf4443, 0xf4638,
|
24
|
+
0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48,
|
25
|
+
0xf503c, 0xf524f, 0xf5445, 0xf5639,
|
26
|
+
0xf584d, 0xf5a42, 0xf5c35, 0xf5e49,
|
27
|
+
0xf603e, 0xf6251, 0xf6446, 0xf663b,
|
28
|
+
0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b,
|
29
|
+
0xf703f, 0xf7252, 0xf7447, 0xf763c,
|
30
|
+
0xf7850, 0xf7a45, 0xf7c39, 0xf7e4d,
|
31
|
+
0xf8042, 0xf8254, 0xf8449, 0xf863d,
|
32
|
+
0xf8851, 0xf8a46, 0xf8c3b, 0xf8e4f,
|
33
|
+
0xf9044, 0xf9237, 0xf944a, 0xf963f,
|
34
|
+
0xf9853, 0xf9a47, 0xf9c3c, 0xf9e50,
|
35
|
+
0xfa045, 0xfa238, 0xfa44c, 0xfa641,
|
36
|
+
0xfa836, 0xfaa49, 0xfac3d, 0xfae52,
|
37
|
+
0xfb047, 0xfb23a, 0xfb44e, 0xfb643,
|
38
|
+
0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53,
|
39
|
+
0xfc048, 0xfc23c, 0xfc450, 0xfc645,
|
40
|
+
0xfc839, 0xfca4c, 0xfcc41, 0xfce36,
|
41
|
+
0xfd04a, 0xfd23d, 0xfd451, 0xfd646,
|
42
|
+
0xfd83a, 0xfda4d, 0xfdc43, 0xfde37,
|
43
|
+
0xfe04b, 0xfe23f, 0xfe453, 0xfe648,
|
44
|
+
0xfe83c, 0xfea4f, 0xfec44, 0xfee38,
|
45
|
+
0xff04c, 0xff241, 0xff436, 0xff64a,
|
46
|
+
0xff83e, 0xffa51, 0xffc46, 0xffe3a,
|
47
|
+
0x10004e, 0x100242, 0x100437, 0x10064b,
|
48
|
+
0x100841, 0x100a53, 0x100c48, 0x100e3c,
|
49
|
+
0x10104f, 0x101244, 0x101438, 0x10164c,
|
50
|
+
0x101842, 0x101a35, 0x101c49, 0x101e3d,
|
51
|
+
0x102051, 0x102245, 0x10243a, 0x10264e,
|
52
|
+
0x102843, 0x102a37, 0x102c4b, 0x102e3f,
|
53
|
+
0x103053, 0x103247, 0x10343b, 0x10364f,
|
54
|
+
0x103845, 0x103a38, 0x103c4c, 0x103e42,
|
55
|
+
0x104036, 0x104249, 0x10443d, 0x104651,
|
56
|
+
0x104846, 0x104a3a, 0x104c4e, 0x104e43,
|
57
|
+
0x105038, 0x10524a, 0x10543e, 0x105652,
|
58
|
+
0x105847, 0x105a3b, 0x105c4f, 0x105e45,
|
59
|
+
0x106039, 0x10624c, 0x106441, 0x106635,
|
60
|
+
0x106849, 0x106a3d, 0x106c51, 0x106e47,
|
61
|
+
0x10703c, 0x10724f, 0x107444, 0x107638,
|
62
|
+
0x10784c, 0x107a3f, 0x107c53, 0x107e48
|
63
|
+
].freeze
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LunarCalendar
|
4
|
+
# The abstract date of calendar
|
5
|
+
class Date
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# @since 0.1.0
|
9
|
+
attr_reader :year, :month, :day
|
10
|
+
|
11
|
+
# @param year [Number] year
|
12
|
+
# @param month [Number] month
|
13
|
+
# @param day [Number] day
|
14
|
+
#
|
15
|
+
# @since 0.1.0
|
16
|
+
def initialize(year, month, day)
|
17
|
+
@year = year
|
18
|
+
@month = month
|
19
|
+
@day = day
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Number] the number of days
|
23
|
+
#
|
24
|
+
# @since 0.1.0
|
25
|
+
def to_i
|
26
|
+
-1
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Number] the packed solar date
|
30
|
+
#
|
31
|
+
# @since 0.1.0
|
32
|
+
def binary
|
33
|
+
@binary ||= (@year << 9) | (@month << 5) | @day
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Boolean] date is same or not
|
37
|
+
#
|
38
|
+
# @since 0.1.0
|
39
|
+
def ==(other)
|
40
|
+
return false unless other.is_a?(self.class)
|
41
|
+
|
42
|
+
@year == other.year &&
|
43
|
+
@month == other.month &&
|
44
|
+
@day == other.day
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Number] the compare result
|
48
|
+
#
|
49
|
+
# @since 0.1.0
|
50
|
+
def <=>(other)
|
51
|
+
binary <=> other.binary
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/date'
|
4
|
+
|
5
|
+
module LunarCalendar
|
6
|
+
# The Lunar Calendar Date
|
7
|
+
class Lunar < Date
|
8
|
+
# @param year [Number] year
|
9
|
+
# @param month [Number] month
|
10
|
+
# @param day [Number] day
|
11
|
+
# @param leap [Boolean] is leap month
|
12
|
+
#
|
13
|
+
# @since 0.1.0
|
14
|
+
def initialize(year, month, day, leap = false)
|
15
|
+
super(year, month, day)
|
16
|
+
@leap = leap
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Boolean] is leap month
|
20
|
+
#
|
21
|
+
# @since 0.1.0
|
22
|
+
def leap?
|
23
|
+
@leap == true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/data/leap_months'
|
4
|
+
require 'lunar_calendar/utils'
|
5
|
+
|
6
|
+
module LunarCalendar
|
7
|
+
# The leap and months of specify year
|
8
|
+
#
|
9
|
+
# @param offset [Number] the offset of table
|
10
|
+
class LunarYear
|
11
|
+
def initialize(offset)
|
12
|
+
@offset = offset
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Number] the packed leap data
|
16
|
+
def binary
|
17
|
+
@binary ||= LunarCalendar::Data::LEAP_MONTHS[@offset]
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array<Number>] month days
|
21
|
+
def month_days
|
22
|
+
(0..12).map do |month|
|
23
|
+
LunarCalendar::Utils.decode(binary, 1, 12 - month) == 1 ? 30 : 29
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Number] the leap month
|
28
|
+
def leap_month
|
29
|
+
@leap_month ||= LunarCalendar::Utils.decode(binary, 4, 13)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/date'
|
4
|
+
require 'lunar_calendar/calculator/lunar'
|
5
|
+
|
6
|
+
module LunarCalendar
|
7
|
+
# The Solar Calendar Date
|
8
|
+
class Solar < Date
|
9
|
+
# @return [LunarCalendar::Lunar] the lunar date
|
10
|
+
#
|
11
|
+
# @since 0.1.0
|
12
|
+
def to_lunar
|
13
|
+
LunarCalendar::Calculator::Lunar.new(self).perform
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Number] solar days
|
17
|
+
#
|
18
|
+
# @since 0.1.0
|
19
|
+
# rubocop:disable Metrics/AbcSize
|
20
|
+
def to_i
|
21
|
+
m = (@month + 9) % 12
|
22
|
+
y = @year - (m / 10)
|
23
|
+
|
24
|
+
(365 * y) + # One year have 365 days
|
25
|
+
(y / 4) - # Add leap days
|
26
|
+
(y / 100) +
|
27
|
+
(y / 400) +
|
28
|
+
((m * 306 + 5) / 10) + # Unknown
|
29
|
+
(@day - 1)
|
30
|
+
end
|
31
|
+
# rubocop:enable Metrics/AbcSize
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lunar_calendar/data/new_years'
|
4
|
+
|
5
|
+
module LunarCalendar
|
6
|
+
# The calculate utils
|
7
|
+
module Utils
|
8
|
+
# Extract packed informactio
|
9
|
+
#
|
10
|
+
# @param data [Number] packed data
|
11
|
+
# @param length [Number] total bit to read
|
12
|
+
# @param shift [Number] the shift position
|
13
|
+
#
|
14
|
+
# @return [Number] value
|
15
|
+
#
|
16
|
+
# @since 0.1.0
|
17
|
+
def self.decode(data, length, shift)
|
18
|
+
(data & (((1 << length) - 1) << shift)) >> shift
|
19
|
+
end
|
20
|
+
|
21
|
+
# Extract lunar new year in solar date
|
22
|
+
#
|
23
|
+
# @param offset [Number] the offset of table
|
24
|
+
#
|
25
|
+
# @return [LunarCalendar::Solar] the solar date
|
26
|
+
#
|
27
|
+
# @since 0.1.0
|
28
|
+
def self.new_year_at(offset)
|
29
|
+
solar = LunarCalendar::Data::NEW_YEARS[offset]
|
30
|
+
year = decode(solar, 12, 9)
|
31
|
+
month = decode(solar, 4, 5)
|
32
|
+
day = decode(solar, 5, 0)
|
33
|
+
|
34
|
+
Solar.new(year, month, day)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/lunar_calendar/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'lunar_calendar'
|
7
|
+
spec.version = LunarCalendar::VERSION
|
8
|
+
spec.authors = ['蒼時弦也']
|
9
|
+
spec.email = ['contact@frost.tw']
|
10
|
+
|
11
|
+
spec.summary = 'The calculator to calculate lunar calendar'
|
12
|
+
spec.description = 'The calculator to calculate lunar calendar'
|
13
|
+
spec.homepage = 'https://github.com/elct9620/lunar_calendar'
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/elct9620/lunar_calendar'
|
18
|
+
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
|
+
`git ls-files -z`
|
21
|
+
.split("\x0")
|
22
|
+
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
27
|
+
|
28
|
+
spec.add_development_dependency 'rspec'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 0.80.1'
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lunar_calendar
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 蒼時弦也
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.80.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.80.1
|
41
|
+
description: The calculator to calculate lunar calendar
|
42
|
+
email:
|
43
|
+
- contact@frost.tw
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- ".rubocop.yml"
|
51
|
+
- ".travis.yml"
|
52
|
+
- CODE_OF_CONDUCT.md
|
53
|
+
- Gemfile
|
54
|
+
- Gemfile.lock
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/console
|
58
|
+
- bin/setup
|
59
|
+
- lib/lunar_calendar.rb
|
60
|
+
- lib/lunar_calendar/calculator/lunar.rb
|
61
|
+
- lib/lunar_calendar/data/leap_months.rb
|
62
|
+
- lib/lunar_calendar/data/new_years.rb
|
63
|
+
- lib/lunar_calendar/date.rb
|
64
|
+
- lib/lunar_calendar/lunar.rb
|
65
|
+
- lib/lunar_calendar/lunar_year.rb
|
66
|
+
- lib/lunar_calendar/solar.rb
|
67
|
+
- lib/lunar_calendar/utils.rb
|
68
|
+
- lib/lunar_calendar/version.rb
|
69
|
+
- lunar_calendar.gemspec
|
70
|
+
homepage: https://github.com/elct9620/lunar_calendar
|
71
|
+
licenses: []
|
72
|
+
metadata:
|
73
|
+
homepage_uri: https://github.com/elct9620/lunar_calendar
|
74
|
+
source_code_uri: https://github.com/elct9620/lunar_calendar
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 2.3.0
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubygems_version: 3.0.3
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: The calculator to calculate lunar calendar
|
94
|
+
test_files: []
|