Ruby - カレンダー計算 gem の作成!

Updated:


当方、 旧暦計算サンプルプログラム を参考にカレンダーを計算する Ruby スクリプトを作成しておりました(実際には多くの部分を微調整した)が、あらゆる面で流用したくなったために、今回 RubyGems ライブラリにし公開することとしました。

但し、微調整はしているもののこのアルゴリズムでは若干の誤差が発生します。また、計算する日によっては月齢が不正になることもあります。
2008年以降でしたら、海上保安庁海洋情報部提供のコンピュータによる天体の位置計算式で計算したほうが精度が高いです。

さらには、 NASA の機関 JPL(Jet Propulsion Laboratory) の提供する DE430 などのデータを使用して計算するほうがより高精度です。

以下では、旧暦計算サンプルプログラムを元に作成した gem の簡単な利用方法をご紹介します。

0. 前提条件

  • Ruby 2.3.1-p112 での作業を想定。
  • 自作した gem ライブラリの名称は “mk_calendar” で、計算対象年月日は 0000-01-01 〜 9999-01-01。
    (但し、祝日は当記事執筆時点の「国民の祝日に関する法律」によるもの)
  • 当ライブラリの計算可能項目
    • ユリウス日(UTC), ユリウス日(JST)
    • 曜日
    • 祝日
    • 二十四節気
    • 雑節
    • 干支(日)
    • 節句
    • 視黄経(太陽)
    • 視黄経(月)
    • 月齢(正午)
    • 旧暦
      • 閏月フラグ

1. インストール

$ sudo gem install mk_calendar

2. Ruby スクリプトの作成例

File: calendar.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#! /usr/local/bin/ruby
# coding: utf-8
require 'date'
require 'mk_calendar'

class Calendar
  USAGE   = "[USAGE] .calendar.rb [YYYYMMDD]"
  MSG_ERR = "[ERROR] Invalid date!"

  def initialize
    @date = ARGV.shift
    @date ||= Time.now.strftime("%Y%m%d")
    unless @date =~ /\d{8}/
      puts USAGE
      exit 0
    end
    unless Date.valid_date?(@date[0,4].to_i, @date[4,2].to_i, @date[6,2].to_i)
      puts MSG_ERR
      exit 0
    end
  end

  def calc
    @obj = MkCalendar.new(@date)
    str =  sprintf("%04d-%02d-%02d", @obj.year, @obj.month, @obj.day)
    str << " #{@obj.yobi}曜日"
    str << " #{@obj.holiday}" unless @obj.holiday == ""
    str << " #{@obj.jd}UTC(#{@obj.jd_jst}JST) #{@obj.kanshi} "
    str << sprintf("%04d-%02d-%02d", @obj.oc[0], @obj.oc[2], @obj.oc[3])
    str << "(閏)" if @obj.oc[1] == 1
    str << " #{@obj.oc[4]}"
    str << " #{@obj.sekki_24}" unless @obj.sekki_24 == ""
    str << " #{@obj.zassetsu}" unless @obj.zassetsu == ""
    str << " #{@obj.sekku}" unless @obj.sekku == ""
    str << " #{@obj.lambda_sun} #{@obj.lambda_moon} #{@obj.moonage}"
    puts str
  rescue => e
    $stderr.puts "[#{e.class}] #{e.message}"
    e.backtrace.each { |tr| $stderr.puts "\t#{tr}"}
    exit 1
  end
end

Calendar.new.calc if __FILE__ == $0

3. サンプルスクリプトの実行

$ ./ex_calendar.rb 20160320
2016-03-20 日曜日 春分の日 2457467.125UTC(2457467.5JST) 辛丑 2016-02-12 先勝
 春分 彼岸(春) 359.44136890287837 136.31180004624142 11.045331036671996

(実際には1行で出力)

4. gem ライブラリ


以前作成した Ruby スクリプトを何かと応用したかったので gem ライブラリ化した次第です。

以上。





 

Sponsored Link

 

Comments