Skip to content

Instantly share code, notes, and snippets.

@YoshitsuguFujii
Created August 2, 2012 13:15
Show Gist options
  • Save YoshitsuguFujii/3237030 to your computer and use it in GitHub Desktop.
Save YoshitsuguFujii/3237030 to your computer and use it in GitHub Desktop.
calender
# coding: utf-8
require 'date'
#
# カレンダークラス
#
# 実装(予定)機能
# (1)コンソールへの出力 ->○
# (2)テーブル形式での出力 ->○
# (3)休日を考慮
# (4)土曜はじまりか日曜はじまりかselectableにする ->○
# (5)viewで前後のリンクを表示する?
# (6)divかspanで出力するようのクラスを生成する div=>行 span=>セル TODO class属性に曜日を持たせる
#
class Jpcalender
WEEK_DAY_INFO = {
:WEEK_DAY => %w(日 月 火 水 木 金 土),
:WEEK_DAY_NUMBER => [0,1,2,3,4,5,6],
:WEEK_DAY_EN => %w(sun,mon,tue,wed,thu,fri,sat)
}
# クラスメソッド定義(いずれモジュールにするよね)
class << self
##
# コンソールに試しに出力してみるやつ
#
def console(arg_date = Date.today)
console_text = ""
date = arg_date.to_date
start_date = date.beginning_of_month
end_date = date.end_of_month
console_text = WEEK_DAY_INFO[:WEEK_DAY].join("\s") + "\n"
is_firstdate =true
(start_date.to_date..end_date.to_date).each do |d|
if is_firstdate
WEEK_DAY_INFO[:WEEK_DAY].each do |weekday|
# 日付と曜日が一致したら、そこに日付を置く
if WEEK_DAY_INFO[:WEEK_DAY][d.wday] == weekday
console_text << sprintf("%02d",d.day).to_s + "|"
if weekday == WEEK_DAY_INFO[:WEEK_DAY].last
console_text << "\n"
end
is_firstdate = false
break
# なかったらスペース
else
console_text << "\s\s|"
end
end
# 初日が決まったらあとは日付を置いていく。土曜日で折り返す
else
console_text << sprintf("%02d",d.day).to_s + "|"
if (d.wday + 1) == WEEK_DAY_INFO[:WEEK_DAY].size
console_text << "\n"
end
end
end
console_text
end
##
# テーブル版
# options: padding 一桁の日付を何で埋めるか。デフォルトは0 => 01とか
# start_with_monday 月曜ではじめるかどうか。 デフォルトはfalse
#
def generate_table(arg_date = Date.today,options = {})
table = ""
arr_calender = console_a(arg_date,options)
weekdays = arr_calender.shift
table << tag_wrap(:tr) do
table_header = ""
weekdays.each do | weekday |
table_header << tag_wrap(:th){weekday}
end
table_header
end
arr_calender.each do |days|
table << tag_wrap(:tr) do
table_data = ""
days.each do |day|
table_data << tag_wrap(:td){day}
end
table_data
end
end
tag_wrap(:table){table}
end
##
# カレンダー出力
# options: padding 一桁の日付を何で埋めるか。デフォルトは0 => 01とか
# start_with_monday 月曜ではじめるかどうか。 デフォルトはfalse
#
def generate(arg_date = Date.today,options = {})
html = ""
arr_calender = console_a(arg_date,options)
weekdays = arr_calender.shift
html << tag_wrap(:div,{class: "header"}) do
html_header = ""
weekdays.each do | weekday |
html_header << tag_wrap(:span){weekday}
end
html_header
end
arr_calender.each.with_index(1) do |days, i|
html << tag_wrap(:div,{class: "row_#{i}"}) do
html_data = ""
days.each.with_index(1) do |day,j|
html_data << tag_wrap(:span, {class: "cell_#{i}_#{j}"}){day}
end
html_data
end
end
tag_wrap(:html){html}
end
private
##
# 指定したタグでかこむ
# ブロックが渡されてない時はただのタグを生成する
# Railsのtagまたはcontent_tagでよかったんじゃないか説浮上。なぜ作ったのかはその時きっと疲れていたから
#
def tag_wrap(tag,options={})
attr_id = " id='#{options[:id]}' " if options[:id]
attr_class = " class='#{options[:class]}' " if options[:class]
tag = tag.to_s if tag.is_a?(Symbol)
if block_given?
"<#{tag + (attr_id || "") + (attr_class || "")}>#{yield}</#{tag}>"
else
"<#{tag} />"
end
end
##
# 引数で指定した月のカレンダーを多重配列で取得
#
def console_a(arg_date,options ={})
# set options(or default setting)
padding = options[:padding] || "0"
start_with_monday = options[:start_with_monday] || false
if start_with_monday
# 似たような処理-> DRYにする
calender_weekday = WEEK_DAY_INFO[:WEEK_DAY].dup
sunday = calender_weekday.shift
calender_weekday.push(sunday)
week_day_number = WEEK_DAY_INFO[:WEEK_DAY_NUMBER].dup
sunday_number = week_day_number.shift
week_day_number.push(sunday_number)
week_day_en = WEEK_DAY_INFO[:WEEK_DAY_EN].dup
sunday_en = week_day_en.shift
week_day_en.push(sunday_en)
else
calender_weekday = WEEK_DAY_INFO[:WEEK_DAY].dup
week_day_number = WEEK_DAY_INFO[:WEEK_DAY_NUMBER].dup
week_day_en = WEEK_DAY_INFO[:WEEK_DAY_EN].dup
end
console_arr =[]
week_arr = []
date = arg_date.to_date
start_date = date.beginning_of_month
end_date = date.end_of_month
console_arr << calender_weekday
is_firstdate =true
(start_date.to_date..end_date.to_date).each do |d|
if is_firstdate
calender_weekday.each do |weekday|
# 日付と曜日が一致したら、そこに日付を置く
if calender_weekday[week_day_number.index(d.wday)] == weekday
week_arr << sprintf("%#{padding}2d",d.day)
if d.wday == week_day_number[calender_weekday.index(calender_weekday.last)]
console_arr << week_arr
week_arr = []
end
is_firstdate = false
break
# なかったら
else
week_arr << ""
end
end
# 初日が決まったらあとは日付を置いていく。土曜日で折り返す
else
week_arr << sprintf("%02d",d.day)
if d.wday == week_day_number[calender_weekday.index(calender_weekday.last)]
console_arr << week_arr
week_arr = []
end
end
end
console_arr << week_arr if week_arr.present?
console_arr
end
# end private
end # class << self
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment