mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

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

[ プログラミング, 暦・カレンダー ] [ Ruby, RubyGems, カレンダー ]

こんばんは。

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

但し、微調整はしているもののこのアルゴリズムでは若干の誤差が発生します。 2008年〜2016年(当記事執筆時点)でしたら、海上保安庁海洋情報部提供のコンピュータによる天体の位置計算式で計算したほうが精度が高いです。
そちらについては、当ブログの前回の記事等をご参照ください。

さらには、 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. インストール

1
$ sudo gem install mk_calendar

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

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

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

1
2
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 ライブラリ化した次第です。

以上。

Comments