vncalendar 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ff8a13b52c6181608cffe86974f227a8f2675c7
4
+ data.tar.gz: e7cc72b4d6f3ab74d8b1590cfe1ed0a3e44fdd11
5
+ SHA512:
6
+ metadata.gz: db12b09e20671af5ae77d5948b16de2e7cfbf2994936aaa17d2e37a3c4bc5094d77a1ab76a7e8832d9a467b3dfbfe254853ef88edcce380f87c666cf91841499
7
+ data.tar.gz: a9a9bee2a8b92e8467fe58bf45740b6d20017ff88db36fee871c56beccfd5484aa77a47e5293d972839012e3387969f410be47af2169969460fb82c4d3dcc308
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .DS_Store
11
+ /log
12
+ *.gem
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.1
5
+ - 2.0
6
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vncalendar.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Man Vuong
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # Vncalendar
2
+
3
+ [![Build Status](https://travis-ci.org/kidlab/vncalendar-ruby.svg?branch=master)](https://travis-ci.org/kidlab/vncalendar-ruby) [![Gem Version](https://badge.fury.io/rb/vncalendar.svg)](https://badge.fury.io/rb/vncalendar)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'vncalendar'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install vncalendar
20
+
21
+ ## Usage
22
+
23
+ - Convert solar date or Gregorian date - our regular date, to lunar date:
24
+
25
+ ```
26
+ UTC_OFFSET = 7 # Asian/Ho_Chi_Minh
27
+ Vncalendar::Converter.solar_to_lunar(Date.new(2014, 9, 23), UTC_OFFSET)
28
+ ```
29
+
30
+ - Convert lunar date to solar date:
31
+
32
+ ```ruby
33
+ UTC_OFFSET = 7 # Asian/Ho_Chi_Minh
34
+ LEAP_MONTH_OF_THE_YEAR = 0 # no leap month in this year.
35
+ Vncalendar::Converter.lunar_to_solar(Date.new(2014, 8, 30), LEAP_MONTH_OF_THE_YEAR, UTC_OFFSET)
36
+ ```
37
+
38
+ ## Development
39
+
40
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
41
+
42
+ You can run one of these commands to run the test suite:
43
+
44
+ ```ruby
45
+ rake test
46
+
47
+ # Or:
48
+ ruby -Ilib:test test/*
49
+ ```
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kidlab/vncalendar.
54
+
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
59
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "vncalendar"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,209 @@
1
+ require 'date'
2
+ require_relative 'vncalendar/version'
3
+
4
+ module Vncalendar
5
+ class LunarDate < Struct.new(:year, :month, :day, :leap)
6
+ end
7
+
8
+ class Converter
9
+ class << self
10
+ private
11
+
12
+ # Return Julian date from Gregorian date (our regular date).
13
+ def jd_from_date(date)
14
+ a = (14 - date.month) / 12
15
+ y = date.year + 4800 - a
16
+ m = date.month + 12*a - 3
17
+ jd = date.day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 - 32045
18
+ if jd < 2299161
19
+ jd = date.day + (153*m+2)/5 + 365*y + y/4 - 32083
20
+ end
21
+
22
+ jd
23
+ end
24
+
25
+ # Return Gregorian date from Julian date.
26
+ def jd_to_date(jd)
27
+ if jd > 2299160
28
+ # After 5/10/1582, Gregorian calendar
29
+ a = jd + 32044
30
+ b = ((4*a + 3) / 146097).to_i
31
+ c = a - ((b*146097)/4).to_i
32
+ else
33
+ b = 0
34
+ c = jd + 32082
35
+ end
36
+
37
+ d = ((4*c + 3) / 1461).to_i
38
+ e = c - ((1461*d)/4).to_i
39
+ m = ((5*e + 2) / 153).to_i
40
+ day = e - ((153*m+2)/5).to_i + 1
41
+ month = m + 3 - 12*(m/10).to_i
42
+ year = b*100 + d - 4800 + (m/10).to_i
43
+
44
+ Date.new(year, month, day)
45
+ end
46
+
47
+ def new_moon(ak)
48
+ k = ak.to_f
49
+
50
+ t = k / 1236.85 # Time in Julian centuries from 1900 January 0.5
51
+ t2 = t * t
52
+ t3 = t2 * t
53
+ dr = Math::PI / 180
54
+ jd1 = 2415020.75933 + 29.53058868*k + 0.0001178*t2 - 0.000000155*t3
55
+ jd1 = jd1 + 0.00033*Math.sin((166.56+132.87*t-0.009173*t2)*dr) # Mean new moon
56
+ m = 359.2242 + 29.10535608*k - 0.0000333*t2 - 0.00000347*t3 # Sun's mean anomaly
57
+ mPr = 306.0253 + 385.81691806*k + 0.0107306*t2 + 0.00001236*t3 # Moon's mean anomaly
58
+ f = 21.2964 + 390.67050646*k - 0.0016528*t2 - 0.00000239*t3 # Moon's argument of latitude
59
+ c1 = (0.1734-0.000393*t)*Math.sin(m*dr) + 0.0021*Math.sin(2*dr*m)
60
+ c1 = c1 - 0.4068*Math.sin(mPr*dr) + 0.0161*Math.sin(dr*2*mPr)
61
+ c1 = c1 - 0.0004*Math.sin(dr*3*mPr)
62
+ c1 = c1 + 0.0104*Math.sin(dr*2*f) - 0.0051*Math.sin(dr*(m+mPr))
63
+ c1 = c1 - 0.0074*Math.sin(dr*(m-mPr)) + 0.0004*Math.sin(dr*(2*f+m))
64
+ c1 = c1 - 0.0004*Math.sin(dr*(2*f-m)) - 0.0006*Math.sin(dr*(2*f+mPr))
65
+ c1 = c1 + 0.0010*Math.sin(dr*(2*f-mPr)) + 0.0005*Math.sin(dr*(2*mPr+m))
66
+
67
+ if t < -11
68
+ deltat = 0.001 + 0.000839*t + 0.0002261*t2 - 0.00000845*t3 - 0.000000081*t*t3
69
+ else
70
+ deltat = -0.000278 + 0.000265*t + 0.000262*t2
71
+ end
72
+
73
+ jd1 + c1 - deltat
74
+ end
75
+
76
+ def new_moon_day(k, utc_offset)
77
+ (new_moon(k) + 0.5 + utc_offset.to_f/24).to_i
78
+ end
79
+
80
+ def sun_longitude(jdn)
81
+ t = (jdn - 2451545.0) / 36525.0 # Time in Julian centuries from 2000-01-01 12:00:00 GMT
82
+ t2 = t * t
83
+ dr = Math::PI / 180 # degree to radian
84
+ m = 357.52910 + 35999.05030*t - 0.0001559*t2 - 0.00000048*t*t2 # mean anomaly, degree
85
+ l0 = 280.46645 + 36000.76983*t + 0.0003032*t2 # mean longitude, degree
86
+ dl = (1.914600 - 0.004817*t - 0.000014*t2) * Math.sin(dr*m)
87
+ dl = dl + (0.019993-0.000101*t)*Math.sin(dr*2*m) + 0.000290*Math.sin(dr*3*m)
88
+ l = l0 + dl # true longitude, degree
89
+ l = l * dr
90
+ l = l - Math::PI*2*(l/(Math::PI*2)).to_i #Normalize to (0, 2*PI)
91
+ l
92
+ end
93
+
94
+ def calc_sun_longitude(jd, utc_offset)
95
+ (sun_longitude(jd.to_f - 0.5 - utc_offset.to_f/24)/Math::PI * 6).to_i
96
+ end
97
+
98
+ def lunar_month_11(year, utc_offset)
99
+ off = jd_from_date(Date.new(year, 12, 31)) - 2415021
100
+ k = (off.to_f / 29.530588853).to_i
101
+ nm = new_moon_day(k, utc_offset)
102
+ sun_long = calc_sun_longitude(nm, utc_offset) # sun longitude at local midnight
103
+
104
+ if sun_long >= 9
105
+ nm = new_moon_day(k-1, utc_offset)
106
+ end
107
+
108
+ nm
109
+ end
110
+
111
+ def leap_month_offset(a11, utc_offset)
112
+ k = ((a11.to_f-2415021.076998695)/29.530588853 + 0.5).to_i
113
+ last = 0
114
+ i = 1 # We start with the month following lunar month 11
115
+ arc = calc_sun_longitude(new_moon_day(k+i, utc_offset), utc_offset)
116
+
117
+ while arc != last && i < 14
118
+ last = arc
119
+ i += 1
120
+ arc = calc_sun_longitude(new_moon_day(k+i, utc_offset), utc_offset)
121
+ end
122
+
123
+ i - 1
124
+ end
125
+ end
126
+
127
+ def self.solar_to_lunar(date, utc_offset = 0)
128
+ day_number = jd_from_date(date)
129
+ k = ((day_number.to_f - 2415021.076998695) / 29.530588853).to_i
130
+ month_start = new_moon_day(k+1, utc_offset)
131
+
132
+ if month_start > day_number
133
+ month_start = new_moon_day(k, utc_offset)
134
+ end
135
+
136
+ b11 = a11 = lunar_month_11(date.year, utc_offset)
137
+
138
+ if a11 >= month_start
139
+ lunar_year = date.year
140
+ a11 = lunar_month_11(date.year - 1, utc_offset)
141
+ else
142
+ lunar_year = date.year + 1
143
+ b11 = lunar_month_11(date.year + 1, utc_offset)
144
+ end
145
+
146
+ lunar_day = day_number - month_start + 1
147
+ diff = ((month_start - a11) / 29).to_i
148
+ lunar_leap = false
149
+ lunar_month = diff + 11
150
+
151
+ if (b11 - a11) > 365
152
+ leap_month_diff = leap_month_offset(a11, utc_offset)
153
+
154
+ if diff >= leap_month_diff
155
+ lunar_month = diff + 10
156
+
157
+ if diff == leap_month_diff
158
+ lunar_leap = true
159
+ end
160
+ end
161
+ end
162
+
163
+ if lunar_month > 12
164
+ lunar_month = lunar_month - 12
165
+ end
166
+
167
+ if lunar_month >= 11 && diff < 4
168
+ lunar_year -= 1
169
+ end
170
+
171
+ LunarDate.new(lunar_year, lunar_month, lunar_day, lunar_leap)
172
+ end
173
+
174
+ def self.lunar_to_solar(date, lunar_leap = 0, utc_offset = 0)
175
+ if date.month < 11
176
+ a11 = lunar_month_11(date.year - 1, utc_offset)
177
+ b11 = lunar_month_11(date.year, utc_offset)
178
+ else
179
+ a11 = lunar_month_11(date.year, utc_offset)
180
+ b11 = lunar_month_11(date.year + 1, utc_offset)
181
+ end
182
+
183
+ k = (0.5 + (a11 - 2415021.076998695) / 29.530588853).to_i
184
+ off = date.month - 11
185
+
186
+ if off < 0
187
+ off += 12
188
+ end
189
+
190
+ if (b11 - a11) > 365
191
+ leap_off = leap_month_offset(a11, utc_offset)
192
+ leap_month = leap_off - 2
193
+
194
+ if leap_month < 0
195
+ leap_month += 12
196
+ end
197
+
198
+ if lunar_leap != 0 && date.month != lunar_leap
199
+ return Date.new(0, 0, 0)
200
+ elsif lunar_leap != 0 || off >= leap_off
201
+ off += 1
202
+ end
203
+ end
204
+
205
+ month_start = new_moon_day(k + off, utc_offset)
206
+ jd_to_date(month_start + date.day - 1)
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,3 @@
1
+ module Vncalendar
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vncalendar/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vncalendar"
8
+ spec.version = Vncalendar::VERSION
9
+ spec.authors = ["Man Vuong"]
10
+ spec.email = ["thanhman.gm@gmail.com"]
11
+
12
+ spec.summary = %q{Vietnamese date converter.}
13
+ spec.description = %q{Vietnamese date converter. A Ruby port of https://github.com/vanng822/vncalendar in Golang}
14
+ spec.homepage = "https://github.com/kidlab/vncalendar-ruby"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vncalendar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Man Vuong
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Vietnamese date converter. A Ruby port of https://github.com/vanng822/vncalendar
56
+ in Golang
57
+ email:
58
+ - thanhman.gm@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/vncalendar.rb
72
+ - lib/vncalendar/version.rb
73
+ - vncalendar.gemspec
74
+ homepage: https://github.com/kidlab/vncalendar-ruby
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.4.8
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Vietnamese date converter.
98
+ test_files: []