年間カレンダー
Posted feedbacks - Nested
Flatten Hidden裏技?系
1 2 3 4 5 6 | module Main (main) where
import System.Cmd
import System.Environment
import System.Exit
main :: IO ExitCode
main = system . ("cal "++) . head =<< getArgs
|
これが一番簡単だと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //http://ja.doukaku.org/119/ 投稿用
using System;
using System.Windows.Forms;
namespace どう書く_org年間カレンダー {
class Program {
[STAThread]
static void Main(string[] args) {
Application.Run(new Form1());
}
}
class Form1:Form {
MonthCalendar calendar = new MonthCalendar();
public Form1() {
int year = int.Parse(Environment.GetCommandLineArgs()[1]);
AutoSize = true;
calendar.Parent = this;
calendar.SetCalendarDimensions(4, 3);
calendar.SelectionStart = new DateTime(year, 1, 1);
}
}
}
|
見た目修正。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //http://ja.doukaku.org/119/ 投稿用
using System;
using System.Drawing;
using System.Windows.Forms;
namespace どう書く_org年間カレンダー {
class Program {
[STAThread]
static void Main(string[] args) {
Application.Run(new Form1());
}
}
class Form1:Form {
public Form1() {
int year = int.Parse(Environment.GetCommandLineArgs()[1]);
Text = year + " Calender";
MonthCalendar calendar = new MonthCalendar();
calendar.Parent = this;
calendar.Dock = DockStyle.Fill;
calendar.SelectionStart = new DateTime(year, 1, 1);
calendar.SelectionEnd = new DateTime(year, 1, 1);
Size = new Size(calendar.SingleMonthSize.Width * 4, calendar.SingleMonthSize.Height * 3);
}
}
}
|
標準出力へ。
========= 2008/ 1 =========
SUN MON TUE WED THR FRI SAT
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
========= 2008/ 2 =========
SUN MON TUE WED THR FRI SAT
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
......
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System;
static class Program {
static void Main(string[] args) {
int year = int.Parse(args[0]);
for(int month = 1; month <= 12; month++) {
int lastday = DateTime.DaysInMonth(year, month);
int week = (int) DateTime.Parse(string.Format("{0}/{1}/1", args[0], month)).DayOfWeek;
Console.WriteLine("========= {0,4}/{1,2} =========", year, month);
Console.WriteLine("SUN MON TUE WED THR FRI SAT");
for(int i = 0; i < week; i++) {
Console.Write(" ");
}
for(int day = 1; day <= lastday; day++) {
Console.Write("{0,3} ", day);
week++;
if (week == 7) {
Console.WriteLine(); week = 0;
}
}
Console.WriteLine();
Console.WriteLine();
}
}
}
|
何となく修正
1 2 3 4 5 6 7 8 9 | --- calendar.cs.old Sun Dec 30 10:22:50 2007
+++ calendar.cs Sun Dec 30 18:23:04 2007
@@ -6,10 +6,8 @@
- Console.WriteLine("SUN MON TUE WED THR FRI SAT");
- for(int i = 0; i < week; i++) {
- Console.Write(" ");
- }
+ Console.WriteLine("SUN MON TUE WED THU FRI SAT");
+ Console.Write (" ".Substring(0, week * 4));
|
標準出力へ。
1 2 3 4 | import sys
import calendar
calendar.prcal(int(sys.argv[1]))
|
ちょっと長いか?
< January_2007 >
Sun Mon Tue Wed Thu Fri Sat
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
・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | require 'date'
y = ARGV[0].to_i
for m in 1 .. 12
date = Date.new(y, m, 1)
puts "< #{ Date::MONTHNAMES[date.month]}_#{y} >"
Date::ABBR_DAYNAMES.each { |name|
print name + " "
}
puts
date.wday.times {
print " "
}
date.upto((date >> 1) - 1) { |d|
print " " if d.day < 10
print " " + d.day.to_s + " "
if d.wday == 6
puts
end
}
puts
puts
end
|
Python/Tkinterで組んでみました。組んだはいいが、結構重い・・・(レイアウトを工夫すればもっと速くできるかもしれませんが)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # coding: shift_jis
import Tkinter as Tk
import calendar
import sys
def grid_configure(frame, col_count, row_count):
for col in xrange(col_count):
frame.grid_columnconfigure(col, weight=1)
for row in xrange(row_count):
frame.grid_rowconfigure(row, weight=1)
class MonthPanel(Tk.Frame):
def __init__(self, master, year, month):
Tk.Frame.__init__(self, master)
label = Tk.Label(self, text=u"%d月" % month)
label.pack(side=Tk.TOP, fill=Tk.X)
frame = Tk.Frame(self)
frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)
grid_configure(frame, 7, 7)
def create_label(row, col):
label = Tk.Label(frame, bg="white")
label.grid(row=row, column=col, sticky="news", padx=1, pady=1)
return label
labels = [[create_label(row, col) for col in xrange(7)] for row in xrange(7)]
def text(col, row, s, color="white"):
labels[row][col].configure(text=s, bg=color)
for col, s in enumerate(u"日月火水木金土"):
if col == 0:
color = "#F7CACA"
elif col == 6:
color = "#CEFFFF"
else:
color = "#E7FFE7"
text(col, 0, s, color)
for row, a in enumerate(calendar.Calendar(6).monthdayscalendar(year, month)):
for col, day in enumerate(a):
if day:
text(col, row + 1, day)
def main():
if len(sys.argv) != 2:
sys.stderr.write("usage: year\n")
return
year = int(sys.argv[1])
root = Tk.Tk()
root.title(u"%d年 年間カレンダー" % year)
grid_configure(root, 4, 3)
for i in xrange(12):
frame = MonthPanel(root, year, i + 1)
frame.grid(row=i/4, column=i%4, sticky="news", padx=2, pady=2)
root.mainloop()
if __name__ == '__main__':
main()
|
Tk.LabelFrameを使ってみた。
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 | --- 1.py Mon Dec 31 18:42:39 2007
+++ 2.py Mon Dec 31 18:44:14 2007
@@ -10,20 +10,14 @@
for row in xrange(row_count):
frame.grid_rowconfigure(row, weight=1)
-class MonthPanel(Tk.Frame):
+class MonthPanel(Tk.LabelFrame):
def __init__(self, master, year, month):
- Tk.Frame.__init__(self, master)
+ Tk.LabelFrame.__init__(self, master, text=u"%dŒŽ" % month)
- label = Tk.Label(self, text=u"%dŒŽ" % month)
- label.pack(side=Tk.TOP, fill=Tk.X)
-
- frame = Tk.Frame(self)
- frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)
-
- grid_configure(frame, 7, 7)
+ grid_configure(self, 7, 7)
def create_label(row, col):
- label = Tk.Label(frame, bg="white")
+ label = Tk.Label(self, bg="white")
label.grid(row=row, column=col, sticky="news", padx=1, pady=1)
return label
|
とりあえず表示例1で書いてみました
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 | ●yCalendar(year)
monthとは整数
dayとは整数
"{year} calendar (#=Saturday, @=Sunday)"を表示
12回
month=回数
"{year}/{month}"を継続表示
(daysOfMonth(year,month))回
day=回数
もし("{year}/{month}/{day}"の曜日="土")ならば
" #{day}"を継続表示
違えば、もし("{year}/{month}/{day}"の曜日="日")ならば
" @{day}"を継続表示
違えば
" {day}"を継続表示
改行を継続表示
●daysOfMonth(year,month)
nextYearとは整数
nextMonthとは整数
もし(month=12)ならば、nextMonth=1。nextYear=year+1
違えば、nextMonth=month+1。nextYear=year
"{year}/{month}/1"と"{nextYear}/{nextMonth}/1"の日数差
yCalendar(2008)
|
2008 / 1 2008 / 2 2008 / 3
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 5 1 2 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 29 23 24 25 26 27 28 29
30 31
(中略)
2008 / 10 2008 / 11 2008 / 12
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
と、こんな感じで表示します☆
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 | #include<stdio.h>
int f(int y, int m, int d){
if(m < 3)
y--, m += 12;
return y * 365 + y / 4 - y / 100 + y / 400 + (m + 1) * 306 / 10 + d - 428;
}
int main(void){
int y , m , d , i , j;
printf("n = ");
scanf("%d", &y);
for(i = 0; i < 12; i += 3){
for(m = i + 1 ; m < i + 4; m++)
printf("%16d /%3d ", y, m);
printf("\n");
for(j = 0; j < 3; j++)
printf(" Su Mo Tu We Th Fr Sa ");
printf("\n");
for(j = 0; j < 42; j += 7, printf("\n"))
for(m = i + 1; m < i + 4; m++, printf(" "))
for(d = j - f(y, m, 1) % 7 + 1; d < j - f(y, m, 1) % 7 + 8; d++)
if(d < 1 || d > f(y, m + 1, 1) - f(y, m, 1))
printf(" ");
else
printf("%3d", d);
printf("\n");
}
return 0;
}
|
出力例3をテーブルに変えて。
テーブル用に空白を で埋めています。
テーブル用に空白を で埋めています。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <?php
$year = 2008;
$weekdays = array( "S", "M", "T", "W", "T", "F", "S" );
for ( $month = 1; $month <= 12; $month++ ) {
$month_ts = mktime( 0, 0, 0, $month, 1, $year );
$days = date( 't', $month_ts );
$weekday = date( 'w', $month_ts );
$week = 0;
for ( $day = 1; $day <= $days; $day++ ) {
if ( $day == 1 && $weekday > 0 ) {
for ( $i = 0; $i < $weekday; $i++ ) {
$calendar[$month][$week][$i] = " ";
}
}
$calendar[$month][$week][] = $day;
$weekday++;
if ( $day == $days && $weekday < 7 ) {
for ( $j = $weekday; $j < 7; $j++ ) {
$calendar[$month][$week][$j] = " ";
}
}
if ( $weekday == 7 ) {
$week++;
$weekday = 0;
}
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title><?php echo($year); ?> calendar</title>
<style type="text/css">
* {font-family: monospace;}
td {text-align: right;}
.sunday {color:red;font-weight:bold;}
.saturday {color:blue;font-weight:bold;}
</style>
</head>
<body>
<h1><?php echo($year); ?> calendar</h1>
<dl>
<?php foreach ( $calendar as $month => $weeks ) { ?>
<dt><?php echo($year); ?>/<?php echo($month); ?></dt>
<dd>
<table>
<tr>
<?php
foreach ( $weekdays as $key => $val ) {
$class = "weekday";
$class = ( $key === 0 )? "sunday": $class;
$class = ( $key == 6 )? "saturday": $class;
?>
<th class="<?php echo($class); ?>"><?php echo($val); ?></th>
<?php } ?>
</tr>
<?php foreach ( $weeks as $week ) { ?>
<tr>
<?php
foreach ( $week as $weekday => $day ) {
$class = "weekday";
$class = ( $weekday === 0 )? "sunday": $class;
$class = ( $weekday == 6 )? "saturday": $class;
?>
<td class="<?php echo($class); ?>"><?php echo($day); ?></td>
<?php } ?>
</tr>
<?php } ?>
</table>
</dd>
<?php } ?>
</dl>
</body>
</html>
|
参考文献: ツェラーの公式 - Wikipedia
Java/Swingで組んでみました。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | import java.awt.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
class MeApp {
public static void main(String[] args) {
final int year;
if (args.length == 0) {
year = Calendar.getInstance().get(Calendar.YEAR);
} else {
year = Integer.valueOf(args[0]);
}
SwingUtilities.invokeLater(new Runnable(){
public void run() {
final MeFrame frame = new MeFrame(year);
frame.setDefaultCloseOperation(MeFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
class MeFrame extends JFrame {
public MeFrame(int year) {
super(String.format("%d年 年間カレンダー", year));
getContentPane().setLayout(new GridLayout(3, 4, 5, 5));
for (int i = 0; i < 12; ++i) {
getContentPane().add(new MeMonthPanel(year, i + 1));
}
}
}
class MeMonthPanel extends JPanel {
public MeMonthPanel(int year, int month) {
setLayout(new BorderLayout());
add(new JLabel(String.format("%d月", month), JLabel.CENTER), BorderLayout.NORTH);
add(new MeMonthCanvas(year, month), BorderLayout.CENTER);
}
}
class MeMonthCanvas extends JComponent {
private final String[][] _cells = new String[7][7];
private final Color[][] _colors = new Color[7][7];
public MeMonthCanvas(int year, int month) {
final String[] weekdays = new DateFormatSymbols().getShortWeekdays();
for (int col = 0; col < 7; ++col) {
_cells[0][col] = weekdays[col + 1];
_colors[0][col] = new Color(231, 255, 231);
}
_colors[0][0] = new Color(247, 202, 202); // Sunday
_colors[0][6] = new Color(206, 255, 255); // Saturday
final Calendar cal = Calendar.getInstance();
for (int row = 1; row < 7; ++row) {
for (int col = 0; col < 7; ++col) {
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1); // starts from 0
cal.set(Calendar.DAY_OF_WEEK, col + 1); // starts from 1
cal.set(Calendar.WEEK_OF_MONTH, row); // starts from 1
if (cal.get(Calendar.DAY_OF_WEEK) == col + 1 && cal.get(Calendar.WEEK_OF_MONTH) == row) {
_cells[row][col] = String.valueOf(cal.get(Calendar.DATE));
} else {
_cells[row][col] = "";
}
_colors[row][col] = Color.WHITE;
}
}
}
public Dimension getPreferredSize() {
return new Dimension(25 * 7, 25 * 7);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
final FontMetrics fm = g.getFontMetrics();
final int w = getWidth() / 7;
final int h = getHeight() / 7;
for (int row = 0; row < 7; ++row) {
for (int col = 0; col < 7; ++col) {
g.setColor(_colors[row][col]);
g.fill3DRect(w * col, h * row, w, h, true);
final String s = _cells[row][col];
g.setColor(Color.BLACK);
g.drawString(
s,
w * col + (w - fm.stringWidth(s)) / 2,
h * row + (h - fm.getHeight()) / 2 + fm.getAscent()
);
}
}
}
}
|
ついでにJTable版。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import java.awt.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
class MeApp {
public static void main(String[] args) {
final int year;
if (args.length == 0) {
year = Calendar.getInstance().get(Calendar.YEAR);
} else {
year = Integer.valueOf(args[0]);
}
SwingUtilities.invokeLater(new Runnable(){
public void run() {
final MeFrame frame = new MeFrame(year);
frame.setDefaultCloseOperation(MeFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
class MeFrame extends JFrame {
public MeFrame(int year) {
super(String.valueOf(year));
getContentPane().setLayout(new GridLayout(3, 4, 5, 5));
for (int i = 0; i < 12; ++i) {
getContentPane().add(new MeMonthPanel(year, i + 1));
}
}
}
class MeMonthPanel extends JPanel {
public MeMonthPanel(int year, int month) {
setLayout(new BorderLayout());
add(new JLabel(new DateFormatSymbols().getMonths()[month - 1], JLabel.CENTER), BorderLayout.NORTH);
add(new JScrollPane(new JTable(new MeMonthTableModel(year, month))), BorderLayout.CENTER);
}
public Dimension getPreferredSize() {
return new Dimension(220, 180); // ???
}
}
class MeMonthTableModel extends AbstractTableModel {
private final int _year, _month;
private final String[] _weekdays = new DateFormatSymbols().getShortWeekdays();
private final Calendar _cal = Calendar.getInstance();
public MeMonthTableModel(int year, int month) {
_year = year; _month = month;
}
public int getColumnCount() {
return 7;
}
public String getColumnName(int col) {
return _weekdays[col + 1];
}
public int getRowCount() {
return 6;
}
public Object getValueAt(int row, int col) {
_cal.set(Calendar.YEAR, _year);
_cal.set(Calendar.MONTH, _month - 1); // starts from 0
_cal.set(Calendar.DAY_OF_WEEK, col + 1); // starts from 1
_cal.set(Calendar.WEEK_OF_MONTH, row + 1); // starts from 1
if (_cal.get(Calendar.DAY_OF_WEEK) == col + 1 && _cal.get(Calendar.WEEK_OF_MONTH) == row + 1) {
return String.valueOf(_cal.get(Calendar.DATE));
} else {
return "";
}
}
}
|
他言語化。(ウィンドウタイトルはそのままだけど、まあいいか)
1 2 3 4 5 6 7 8 9 10 11 | --- MeApp.java.old Mon Dec 31 18:21:09 2007
+++ MeApp.java Mon Dec 31 18:21:22 2007
@@ -35,7 +35,7 @@
class MeMonthPanel extends JPanel {
public MeMonthPanel(int year, int month) {
setLayout(new BorderLayout());
- add(new JLabel(String.format("%dŒŽ", month), JLabel.CENTER), BorderLayout.NORTH);
+ add(new JLabel(new DateFormatSymbols().getMonths()[month - 1], JLabel.CENTER), BorderLayout.NORTH);
add(new MeMonthCanvas(year, month), BorderLayout.CENTER);
}
}
|
せっかくJAVAのクラスを使っているので多言語対応で。
JAPAN
=================================
2007/1
日 月 火 水 木 金 土
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
US
=================================
2007/1
Sun Mon Tue Wed Thu Fri Sat
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
CHINA
=================================
2007/1
星期日 星期一 星期二 星期三 星期四 星期五 星期六
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
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 | import java.text.{DateFormatSymbols, SimpleDateFormat}
import java.util.{Date, Locale}
object YearCalendar {
import java.util.Calendar._
def mkString(n:int, s:String) = List.make(n, s).mkString
def print(year:int):unit = print(year, Locale.getDefault)
def print(year:int, locale:Locale):unit = {
val ws = (new DateFormatSymbols(locale)).getShortWeekdays mkString " "
val format = (new SimpleDateFormat("dd", locale)).format _:Date => String
val wwidth = ws.split(" ")(1).getBytes.size
val cal = getInstance(locale)
(0 to 11).foreach { month =>
println(year+"/"+(month+1)+"\n"+ws)
var n = {cal.set(year,month,1); cal}.get(DAY_OF_WEEK)
Console.print(mkString((n-1)*(wwidth+2), " "))
do {
Console.print(mkString(wwidth, " ")+format(cal.getTime).replaceFirst("^0", " "))
if(n == 7){ println(""); n = 0 }
}while({n = n +1;cal.add(DATE, 1);cal.get(MONTH) == month})
println("\n")
}
}
}
YearCalendar print 2007
YearCalendar.print(2007, Locale.US)
YearCalendar.print(2007, Locale.CHINA)
|
#5080を参考に、Javaの標準出力版を書いてみました。
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 45 46 47 48 49 50 51 | import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Locale;
public class Sample119 {
private final int year_;
private final Locale locale_;
private DateFormatSymbols formatSymbols_;
public Sample119(int year, Locale locale) {
year_ = year;
locale_ = locale;
formatSymbols_ = new DateFormatSymbols(locale_);
}
public void printCalendar() {
System.out.println(locale_.getDisplayCountry());
for (int month = 0; month < 12; month++) {
printCalendar(month);
}
System.out.println();
}
private void printCalendar(int month) {
System.out.format("< %s/%d >%n", formatSymbols_.getShortMonths()[month], year_);
String[] weekdays = formatSymbols_.getShortWeekdays();
for (int index = 1; index < weekdays.length; index++) {
System.out.format("%s ", weekdays[index]);
}
System.out.println();
Calendar cal = Calendar.getInstance(locale_);
cal.set(year_, month, 1);
int dayLen = weekdays[1].getBytes().length;
for (int index = 0, length = (cal.get(Calendar.DAY_OF_WEEK) - 1) * (dayLen + 1); index < length; index++) {
System.out.print(" ");
}
String format = String.format("%%%dd ", dayLen);
for (; cal.get(Calendar.MONTH) == month; cal.add(Calendar.DATE, 1)) {
System.out.format(format, cal.get(Calendar.DATE));
if (Calendar.SATURDAY == cal.get(Calendar.DAY_OF_WEEK)) {
System.out.println();
}
}
System.out.println();
}
public static void main(String[] args) {
new Sample119(2008, Locale.JAPAN).printCalendar();
new Sample119(2008, Locale.US).printCalendar();
}
}
|
#5080ではなくて、#5060でした。
Date-Calcという同名のPerlのライブラリをCommon Lispで再現したものを 使用してみました。 ライブラリ機能のおまけで英仏独等々に対応させてみましたが、 日本語は対応していないという…。 (y-calendar 2008 7) ;7はイタリア(数字で指定だと色んな意味で紛らわしいかも) ;==> ; Gennaio 2008 ;Lun Mar Mer Gio Ven Sab Dom ; 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 ; ~~~
see: Date-Calc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | (defpackage :doukaku-119 (:use :cl :date-calc))
(in-package :doukaku-119)
(defun y-calendar (y &optional (lang 1))
(do ((m 1 (1+ m)) (col 4))
((> m 12))
(format t "~&~%~V:@<~A ~D~>~%~{~A~^ ~}~%"
(* col 7) (get-month-name m lang) y
(get-week-day-name-list lang (1- col)))
(do ((d 1 (1+ d))) (nil)
(let ((dow (day-of-week y m d))
(day (day-of-year y m d)))
(when (= 1 d)
(format t "~V,0T" (* col (1- dow))))
(if (zerop day)
(return)
(format t "~VD~:[ ~;~%~]" (1- col) d (= 7 dow)))))))
(defun get-month-name (m &optional (lang 1))
(aref (gethash lang date-calc::month-to-text) m))
(defun get-week-day-name-list (&optional (lang 1) (shoten 3))
(map 'list (if shoten (lambda (name) (subseq name 0 shoten)) #'identity)
(subseq (gethash lang date-calc::day-of-week-to-text) 1)))
|
Squeak Smalltalk で。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | | nn |
nn := 2008.
World findATranscript: nil.
Transcript cr; show: nn.
nn asYear monthsDo: [:month |
Transcript cr; show: (month name first: 3).
month datesDo: [:date |
| template |
template := date weekday caseOf: {
[#Saturday] -> ['({1})'].
[#Sunday] -> ['[{1}]']} otherwise: ['{1}'].
Transcript space; show: (template format: {date dayOfMonth})]]
"=>
2008
Jan 1 2 3 4 (5) [6] 7 8 9 1 ... "
|
404 Blog Not Found:javascript - カレンダーを作るに実際に動くデモがありますので併せてご覧下さい。なるべく再利用しやすいよう書きました。
Dan the JavaScripter
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | function leap(year){
return year % 4 ? 0 : year % 100 ? 1 : year % 400 ? 0 : 1;
}
function make_cal_array(year){
var months = [31, 28 + leap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var result = [];
for (var m = 0; m < 12; m++){
result[m] = [];
var dofw1 = (new Date(year, m, 1, 0, 0, 0)).getDay();
for (var d = 1; d <= months[m]; d++){
result[m][d + dofw1 - 1] = d;
}
}
return result;
}
var daynames = ['sun','mon','tue','wed','thr','fri','sat'];
function make_cal_yearly(year){
var cal = make_cal_array(year);
var tbody = document.createElement('tbody');
for (var m = 0; m < 12; m++){
var tr = document.createElement('tr');
var th = document.createElement('th');
th.innerHTML = m + 1;
tr.appendChild(th);
for (var d = 0, l = cal[m].length; d < l; d++){
var td = document.createElement('td');
if (cal[m][d]){
td.innerHTML = cal[m][d];
td.className = daynames[d % 7];
}
tr.appendChild(td);
}
tbody.appendChild(tr);
}
var table = document.createElement('table');
table.className = 'ycal';
var caption = document.createElement('caption');
caption.innerHTML = year;
table.appendChild(caption);
table.appendChild(tbody);
return table;
}
function make_cal_monthly(year, m){
var cal = make_cal_array(year);
var table = document.createElement('table');
// header
var tr = document.createElement('tr');
for (var d = 0; d < 7; d++){
var th = document.createElement('th');
th.innerHTML = th.className = daynames[d];
tr.appendChild(th);
}
var thead = document.createElement('thead');
thead.appendChild(tr);
table.appendChild(thead);
// body;
var tbody = document.createElement('tbody');
for (var d = 0, l = cal[m].length; d < l; d++){
if (d % 7 == 0) tr = document.createElement('tr');
var td = document.createElement('td');
if (cal[m][d]){
td.innerHTML = cal[m][d];
td.className = daynames[d % 7];
}
tr.appendChild(td);
if (d % 7 == 6) tbody.appendChild(tr);
}
tbody.appendChild(tr);
table.className = 'mcal';
var caption = document.createElement('caption');
caption.innerHTML = year + '.' + (m+1);
table.appendChild(caption);
table.appendChild(tbody);
return table;
}
function make_calendars(year, p){
p.innerHTML = '';
p.appendChild(make_cal_yearly(year));
for (var m = 0; m < 12; m++){
var mcal = make_cal_monthly(year, m);
p.appendChild(mcal);
if (m % 3 == 2){
var br = document.createElement('br');
br.clear = 'all';
p.appendChild(br);
}
};
}
|
ひたすらコンパクトさ目指して、32進表記とか。 cal 2008 uv12345 6789abc defghij klmnopq rstuv12 3456789 abcdefg hijklmn opqrst1 2345678 9abcdef ghijklm nopqrst uv12345 6789abc defghij klmnopq rstu123 456789a bcdefgh ijklmno pqrstuv 1234567 89abcde fghijkl mnopqrs tu12345 6789abc defghij klmnopq rstuv12 3456789 abcdefg hijklmn opqrstu v123456 789abcd efghijk lmnopqr stu1234 56789ab cdefghi jklmnop qrstuv1 2345678 9abcdef ghijklm nopqrst u123456 789abcd efghijk lmnopqr stuv123 456789a bcdefgh ijklmno
1 2 3 | load 'dates'
n32=:{&' 123456789abcdefghijklmnopqrstuv'
cal=:3 :'14 32$,,.&'' ''_7[\n32"0[,2}."1 todate((todayno-weekday)y,1 1)+i.400'
|
全部で365日をこえてしまってまっているようですが…
前にも後ろにもはみ出しています。「年間」カレンダーとはよべないかも しれません。4クールカレンダーかな。 もうすこしカレンダーらしくなるように考えてみます。
calコマンドっぽく表示します。
> erlc year_cal.erl
> erl -noshell -s year_cal main -s init stop
1月_2008
日 月 火 水 木 金 土
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
(中略)
12月_2008
日 月 火 水 木 金 土
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
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 | -module(year_cal).
-export([main/0]).
main() -> year_cal(2008).
year_cal(Year) -> lists:foreach(fun manth/1, [{Year, X} || X <- lists:seq(1, 12)]).
manth({Year, Manth}) ->
io:format("~B月_~B~n", [Manth, Year]),
io:format("日 月 火 水 木 金 土~n", []),
First = calendar:day_of_the_week(Year, Manth, 1),
if
7 == First -> true;
true -> io:format(lists:duplicate(((First rem 7) * 3) - 1, " "), [])
end,
manth(Year, Manth, 1).
manth(Year, Manth, Day) ->
case calendar:valid_date(Year, Manth, Day) of
false -> io:nl(); % 一ヶ月の終わり
true ->
Dotw = calendar:day_of_the_week(Year, Manth, Day),
if
7 == Dotw -> io:format("~2B", [Day]); % 日曜日
6 == Dotw -> io:format("~3B~n", [Day]); % 土曜日
true -> io:format("~3B", [Day]) % その他平日
end,
manth(Year, Manth, Day + 1)
end.
|
初めて投稿させていただきます。
出力形式はUnixの calコマンドを参考にしました。
バッチファイルですので、ファイル名を cal.batなどにして保存し、ダブルクリックして
ください。Windows 2000以降であれば動作すると思います。一瞬で終了しないようにする
には、69行目のendlocalの下に以下の行を追加してください。
e.g. pause >NUL
引数を指定しない場合はシステムの日時をもとに算出します。ただし、日本以外の地域の
日時表記を使用している環境では正常に動作しません。
e.g. C:\>cal 1 2008
出力形式はUnixの calコマンドを参考にしました。
バッチファイルですので、ファイル名を cal.batなどにして保存し、ダブルクリックして
ください。Windows 2000以降であれば動作すると思います。一瞬で終了しないようにする
には、69行目のendlocalの下に以下の行を追加してください。
e.g. pause >NUL
引数を指定しない場合はシステムの日時をもとに算出します。ただし、日本以外の地域の
日時表記を使用している環境では正常に動作しません。
e.g. C:\>cal 1 2008
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | @echo off
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: グローバル変数
setlocal
set Y4=%2
set MM=%1
set DOW=
set EOM=
set COUNT=
set ERROR=
set IS_LEAP_YEAR=0
set MARGIN=
set MONTH=
set SPACE=
set ARRAY_MONTH=
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: メイン関数
if "%3" NEQ "" echo usage: cal [month] [year] & goto :EOF
if "%2" EQU "" (
if "%1" NEQ "" echo usage: cal [month] [year] & goto :EOF
call :GetDate Y4 MM
)
:: 8進数として解釈されないようにする。
set /a Y4=%Y4%+0
set /a MM=%MM%+0
call :IsNumber %Y4% _ERROR
if %_ERROR% NEQ 0 echo usage: cal [month] [year] & goto :EOF
call :IsNumber %MM% _ERROR
if %_ERROR% NEQ 0 echo usage: cal [month] [year] & goto :EOF
if %Y4% LSS 1 echo cal: illegal year value: use 1-9999 & goto :EOF
if %Y4% GTR 9999 echo cal: illegal year value: use 1-9999 & goto :EOF
if %MM% LSS 1 echo cal: illegal month value: use 1-12 & goto :EOF
if %MM% GTR 12 echo cal: illegal month value: use 1-12 & goto :EOF
call :GetMonthName ARRAY_MONTH
call :GetMargin %MM% MARGIN
call :GetSpace %MARGIN% SPACE
call :GetArrayValue ARRAY_MONTH_%MM% MONTH
call :PrintHeader %Y4% %MONTH% "%SPACE%"
call :GetDayOfWeek %Y4% %MM% DOW
:: 2 : セルの幅, 1 : セルの余白
set /a MARGIN=%DOW%*(2+1)
call :GetSpace %MARGIN% SPACE
call :GetEndOfMonth %MM% EOM
call :IsLeapYear %Y4% %MM% IS_LEAP_YEAR
if %IS_LEAP_YEAR% NEQ 0 set /a EOM+=1
call :PrintCalendar %EOM% %DOW% "%SPACE%"
endlocal
goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ユーザー定義関数
:SetArrayValue
set %1_%COUNT%=%2
goto :EOF
:GetArrayValue
for /f "delims== tokens=1,2" %%a in ('set^|findstr /b "%1="') do set %2=%%b
goto :EOF
:Increment
set /a COUNT+=1
goto :EOF
:GetDate
set _DATE=
for /f "tokens=1" %%d in ('date /t') do set _DATE=%%d
set %1=%_DATE:~0,4%
set %2=%_DATE:~5,2%
goto :EOF
:IsNumber
set %2=0
echo %1|findstr /r "[^0-9]" >NUL 2>NUL
if %ERRORLEVEL% EQU 0 set %2=1
goto :EOF
:PrintHeader
set _SPACE=%3
set _SPACE=%_SPACE:"=%
echo %_SPACE% %2 %1
echo Su Mo Tu We Th Fr Sa
goto :EOF
:GetMonthName
set _PATH=_.txt
echo January > %_PATH%
echo February >>%_PATH%
echo March >>%_PATH%
echo April >>%_PATH%
echo May >>%_PATH%
echo June >>%_PATH%
echo July >>%_PATH%
echo Augst >>%_PATH%
echo September>>%_PATH%
echo October >>%_PATH%
echo November >>%_PATH%
echo December >>%_PATH%
set COUNT=1
for /f "delims=" %%m in (%_PATH%) do (
call :SetArrayValue %1 %%m
call :Increment
)
del /q %_PATH% >NUL 2>NUL
goto :EOF
:GetMargin
set _PATH=_.bat
echo set _MARGIN= 334455542333>%_PATH%
echo set %2=%%_MARGIN:~%1,1%%>>%_PATH%
call %_PATH%
del %_PATH% >NUL 2>NUL
goto :EOF
:GetDayOfWeek
set _Y4_PREV=%1
set _MM_PREV=%2
set _DOW=0
if %2 LEQ 2 (
set /a _Y4_PREV=%1-1
set /a _MM_PREV=%2+12
)
set /a _DOW=_Y4_PREV+_Y4_PREV/4-_Y4_PREV/100+_Y4_PREV/400+(13*_MM_PREV+8)/5+1
set /a %3=_DOW%%7
goto :EOF
:GetSpace
set _PATH=_.bat
echo set _SPACE= >%_PATH%
echo set %2=%%_SPACE:~0,%1%%>>%_PATH%
call %_PATH%
del %_PATH% >NUL 2>NUL
goto :EOF
:GetEndOfMonth
set _PATH=_.bat
echo set _DIFF=0030101001010>%_PATH%
echo set /a %2=31-%%_DIFF:~%1,1%%>>%_PATH%
call %_PATH%
del %_PATH% >NUL 2>NUL
goto :EOF
:PrintCalendar
set _DOW=0
set _SPACE=%3
set _LINE=%_SPACE:"=%
set _DD=1
:LOOP_BEGIN
if %_DD% GTR %1 goto LOOP_END
set /a _DOW=(%_DD%+%2)%%7
if %_DD% LSS 10 set _DD= %_DD%
set _LINE=%_LINE%%_DD%
if %_DOW% EQU 0 (
echo %_LINE%
set _LINE=
)
set /a _DD+=1
goto LOOP_BEGIN
:LOOP_END
if "%_LINE%" NEQ "" echo %_LINE%
goto :EOF
:IsLeapYear
set _VALUE=0
if %2 NEQ 2 goto :EOF
set /a _VALUE=%1%%4
if %_VALUE% NEQ 0 goto :EOF
set /a _VALUE=%1%%100
if %_VALUE% NEQ 0 set %3=1 && goto :EOF
set /a _VALUE=%1%%400
if %_VALUE% EQU 0 set %3=1 && goto :EOF
goto :EOF
|
一点訂正です。
47, 48, 50, 51行目で_ERRORという名前の変数を使用していますが、正しくは ERRORでし
た。(先頭のアンダースコアが不要。)
該当部分の処理を関数(擬似関数)内からメイン関数に移した際、変数名を変更するのを忘
れていました。とはいえ、setlocalとendlocalでスコープを細かく分けることはしていな
いので、投稿したものでも動作上問題はありません。
47, 48, 50, 51行目で_ERRORという名前の変数を使用していますが、正しくは ERRORでし
た。(先頭のアンダースコアが不要。)
該当部分の処理を関数(擬似関数)内からメイン関数に移した際、変数名を変更するのを忘
れていました。とはいえ、setlocalとendlocalでスコープを細かく分けることはしていな
いので、投稿したものでも動作上問題はありません。
現状を維持しながら cal -y のような表示形式にするのは難しかったので、以下のワンラ
イナーでもって「年間カレンダー」に対する回答とさせてください。
e.g.
C:\>echo off && (for /l %i in (1,1,12) do (echo. & cal %i 2008)) && echo on
January 2008
Su Mo Tu We Th Fr Sa
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
(中略)
December 2008
Su Mo Tu We Th Fr Sa
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
カレンダーをどう見せるかで一番迷いましたが、こんな見せ方もあってもいいかなあ、と。
ANSIカラーに対応した端末(まあ今時はたいていのがそうだけど)で実行してご確認ください。
Dan the Perl Monger
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 45 46 47 48 49 50 51 52 | #!/usr/local/bin/perl
use strict;
use warnings;
use POSIX qw/mktime/;
sub leap {
$_[0] % 4 ? 0 : $_[0] % 100 ? 1 : $_[0] % 400 ? 0 : 1;
}
my @dayname = qw/sun mon tue wed thu fri sat/;
sub make_cal_array {
my $year = shift;
my @months =
( 31, 28 + leap($year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
my $result;
for my $m ( 0 .. 11 ) {
my $dofw1 = ( localtime( mktime( 0, 0, 0, 1, $m, $year - 1900 ) ) )[6];
for my $d ( 1 .. $months[$m] ) {
$result->[$m][ $d + $dofw1 - 1 ] = $d;
}
}
return $result;
}
sub color {
[
sub { "\e[7m\e[31m$_[0]\e[0m" }, # reverse red
sub { "\e[30m$_[0]\e[0m" }, # black
sub { "\e[35m$_[0]\e[0m" }, # purple
sub { "\e[32m$_[0]\e[0m" }, # green
sub { "\e[33m$_[0]\e[0m" }, # yellow
sub { "\e[36m$_[0]\e[0m" }, # skyblue
sub { "\e[7m\e[34m$_[0]\e[0m" }, # reverse blue
]->[ $_[1] % 7 ]->( $_[0] );
}
sub print_cal {
my $year = shift;
my $cal = make_cal_array($year);
print "$year\n";
for my $m ( 0 .. 11 ) {
printf "%2d: ", $m + 1;
my $c = 0;
for my $d ( @{ $cal->[$m] } ) {
print color( $d ? $d < 10 ? ' ' . $d : $d : ' ', $c++ );
}
print "\n";
}
}
print_cal(shift || (localtime)[5]+1900);
|
InstallShield Scriptで書いてみました。
InstallShield Scriptは Windowsアプリケーション用のインストーラーを作成するための
言語です。
インストーラーを実行すると、年を入力するダイアログが表示されます。西暦を入力して
[次へ]ボタンを押すと、ダイアログに以下の形式でカレンダーが表示されます。
e.g.
2008/ 1
日 月 火 水 木 金 土
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
(中略)
2008/12
日 月 火 水 木 金 土
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
# InstallShield Profesional 7.01でビルドし、動作することを確認。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include "ifx.h"
prototype CreateCalendar(BYREF LIST, NUMBER, NUMBER);
prototype GetDayOfWeek(NUMBER, NUMBER, NUMBER);
prototype GetEndOfMonth(NUMBER, NUMBER);
prototype IsLeapYear(NUMBER);
LIST l;
NUMBER m, y;
STRING s;
program
AskText("年を入力してください。(1-9999)", "", s);
if (StrToNum(y, s) < ISERR_SUCCESS) then abort; endif;
if (y < 1 || y > 9999) then abort; endif;
l = ListCreate(STRINGLIST);
if (l = LIST_NULL) then abort; endif;
for m = 1 to 12
CreateCalendar(l, y, m);
endfor;
SdShowInfoList("", "", l);
ListDestroy(l);
abort;
endprogram
function CreateCalendar(l, y, m)
NUMBER d, i, w;
STRING s, t;
begin
w = GetDayOfWeek(y, m, 1);
d = GetEndOfMonth(y, m);
NumToStr(s, y); t = s;
NumToStr(s, m); if (StrLength(s) = 1) then s = " " + s; endif;
ListAddString(l, t + "/" + s, AFTER); t = "";
ListAddString(l, "日 月 火 水 木 金 土", AFTER);
for i = 1 to w
t = t + " ";
endfor;
for i = 1 to d
NumToStr(s, i);
if (StrLength(s) = 1) then t = t + " " + s; else t = t + s; endif;
if (GetDayOfWeek(y, m, i) = 6 || i = d) then
ListAddString(l, t, AFTER); t = "";
else
t = t + " ";
endif;
endfor;
ListAddString(l, "", AFTER);
end;
function GetDayOfWeek(y, m, d)
begin
if (m <= 2) then y = y - 1; m = m + 12; endif;
return (5 * y / 4 - y / 100 + y / 400 + (26 * m + 16) / 10 + d) % 7;
end;
function GetEndOfMonth(y, m)
begin
switch (m)
case 1, 3, 5, 7, 8, 10, 12 : return 31;
case 2 : if (IsLeapYear(y)) then return 29; else return 28; endif;
case 4, 6, 9, 11 : return 30;
endswitch;
end;
function IsLeapYear(y)
begin
if (y % 400 = 0) then return 1; endif;
if (y % 100 = 0) then return 0; endif;
if (y % 4 = 0) then return 1; endif;
return 0;
end;
|
出力例 1 と同じ形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import std.stdio;
import std.date;
void main(string[] args){
auto year = args[1];
auto newYearsDay = parse("Jan 01 " ~ year ~ " 00:00:00 GMT+0000");
if(newYearsDay == d_time_nan){
return;
}
auto wdayOffset = WeekDay(newYearsDay);
int total;
writefln("#=Saturday, @=Sunday");
foreach(i, n; [31, 28 + !!inLeapYear(newYearsDay), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]){
writef(year, "/", i + 1);
for(int j = 1; j <= n; j++, total++){
writef(" ", ["@", "", "", "", "", "", "#"][(wdayOffset + total) % 7], j);
}
writefln();
}
}
|
「車輪の再発明」の誹りは免れませんが、Shell Scriptで書いてみました。
Bourne Shellでも動作するように書いたので、Unix系OSなら大半で動作すると思います。
時間のある時に AIX, HP-UX, Linux, Solaris などで動作確認してみます。
# 手元のCygwinで動作することを確認しました。
以下のワンライナーを実行することで、「年間カレンダー」を表示することが可能です。
e.g.
$ for i in `seq 1 12`; do ./cal.sh $i 2008; done
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #!/bin/sh
case "`echo -e`" in
-e) echo_() { echo "$@"; };;
*) echo_() { echo -e "$@"; };;
esac
case "`echo_ '\r'`" in
'\r') case "`(print X) 2>/dev/null`" in
X) echo_() { print "$@"; };;
*) PATH=/usr/5bin:$PATH; export PATH;;
esac
;;
esac
is_numeric() { return `echo_ $1 | grep -E '^[0-9]+$' >/dev/null 2>&1`; }
dow() {
y=$1; m=$2
[ $2 -le 2 ] && { y=`expr $y - 1`; m=`expr $m + 12`; }
expr \( 5 \* $y / 4 - $y / 100 + $y / 400 + \( 26 \* $m + 16 \) / 10 + $3 \) % 7
}
eom() {
case $2 in
1|3|5|7|8|10|12) echo_ 31;;
4|6|9|11) echo_ 30;;
2) is_leap_year $1 && echo_ 29 || echo_ 28;;
esac
}
is_leap_year() {
[ `expr $1 % 400` -eq 0 ] && return 0
[ `expr $1 % 100` -eq 0 ] && return 1
[ `expr $1 % 4` -eq 0 ] && return 0
return 1
}
main() {
[ $# -ne 2 ] && { echo_ "usage: $0 [month] [year]"; return 1; }
is_numeric $1 || return 1; [ $1 -lt 1 -o $1 -gt 12 ] && return 1
is_numeric $2 || return 1; [ $2 -lt 1 -o $2 -gt 9999 ] && return 1
w=`dow $2 $1 1`
d=`eom $2 $1`
echo_ "$2/\c"; [ `echo_ "$1\c" | wc -m` -eq 1 ] && echo_ ' \c'; echo_ "$1"
echo_ 'Su Mo Tu We Th Fr Sa'
for i in `seq 1 $w`; do echo_ ' \c'; done
for i in `seq 1 $d`; do
[ `echo_ "$i\c" | wc -m` -eq 1 ] && echo_ ' \c'
echo_ "$i\c"
[ `dow $2 $1 $i` -eq 6 ] && echo_ '' || echo_ ' \c'
done
echo_ '\n'
return 0
}
main $*
|
ANSIカラーに対応してみました。
# ダム端末ではエスケープシーケンスがそのまま表示されるため、レイアウトが崩れます。
e.g.
53,54c54,59
< echo_ "$i\c"
< [ `dow $2 $1 $i` -eq 6 ] && echo_ '' || echo_ ' \c'
---
> case "`dow $2 $1 $i`" in
> 0) echo_ "\033[31m$i\033[m \c";;
> 6) echo_ "\033[34m$i\033[m" ;;
> *) echo_ "$i \c" ;;
> esac
いくつかのUnix系OSでは正常に動作しなかったので、若干修正しました。 以下のOSで動作を確認。 AIX (5.2, 5.3) HP-UX (11.00, 11.11, 11.23) Linux (2.2, 2.4, 2.6) Solaris (5.5, 5.6, 5.7, 5.9, 5.10)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #!/bin/sh
case "`echo -e`" in
-e) echo_() { echo "$@"; };;
*) echo_() { echo -e "$@"; };;
esac
case "`echo_ '\r'`" in
'\r') case "`(print X) 2>/dev/null`" in
X) echo_() { print "$@"; };;
*) PATH=/usr/5bin:$PATH; export PATH;;
esac
;;
esac
(echo '' | grep -E '' >/dev/null 2>&1) && grep_() { grep "$@"; } || grep_() { /usr/xpg4/bin/grep "$@"; }
seq_() { i=$1; while [ $i -le $2 ]; do echo_ "$i \c"; i=`expr $i + 1`; done; }
is_numeric() { return `echo_ $1 | grep_ -E '^[0-9]+$' >/dev/null 2>&1`; }
dow() {
y=$1; m=$2
[ $2 -le 2 ] && { y=`expr $y - 1`; m=`expr $m + 12`; }
expr \( 5 \* $y / 4 - $y / 100 + $y / 400 + \( 26 \* $m + 16 \) / 10 + $3 \) % 7
}
eom() {
case $2 in
1|3|5|7|8|10|12) echo_ 31;;
4|6|9|11) echo_ 30;;
2) is_leap_year $1 && echo_ 29 || echo_ 28;;
esac
}
is_leap_year() {
[ `expr $1 % 400` -eq 0 ] && return 0
[ `expr $1 % 100` -eq 0 ] && return 1
[ `expr $1 % 4` -eq 0 ] && return 0
return 1
}
main() {
[ $# -ne 2 ] && { echo_ "usage: $0 [month] [year]"; return 1; }
is_numeric $1 || return 1; [ $1 -lt 1 -o $1 -gt 12 ] && return 1
is_numeric $2 || return 1; [ $2 -lt 1 -o $2 -gt 9999 ] && return 1
w=`dow $2 $1 1`
d=`eom $2 $1`
echo_ "$2/\c"; [ `echo_ "$1\c" | wc -c` -eq 1 ] && echo_ ' \c'; echo_ "$1"
echo_ 'Su Mo Tu We Th Fr Sa'
for i in `seq_ 1 $w`; do echo_ ' \c'; done
for i in `seq_ 1 $d`; do
[ `echo_ "$i\c" | wc -c` -eq 1 ] && echo_ ' \c'
case "`dow $2 $1 $i`" in
0) echo_ "\033[31m$i\033[m \c";;
6) echo_ "\033[34m$i\033[m" ;;
*) echo_ "$i \c" ;;
esac
done
echo_ '\n'
return 0
}
main $*
|
すでに JavaScript + HTMLによる解が提出されていますが、 SVGで出力してみたかったの
で、 ECMA Script + SVGで書いてみました。
calendar.svgなどの名前でファイルを保存し、ブラウザにドラッグアンドドロップすれば、
以下の形式でカレンダーが表示されます。
e.g.
2008/ 1
日 月 火 水 木 金 土
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
Firefox 2.0.0.8, Internet Explorer 6, Opera 9.23で動作を確認しました。まだ試して
いませんが、Safari 3でも動作すると思います。
[注意]
* IEで表示する場合は、プラグインとしてAdobe SVG Viewerがインストールされている
必要があります。
* IEで SVGファイルを実行するとスクロールバーが表示されないため、カレンダーを全
て見ることができませんでした。スクロールバーを表示するには、別途HTMLファイル
を用意し、 embed要素の src属性に SVGファイルを指定してあげる必要があるのかも
しれません。
* Calendarオブジェクトに何もかも詰め込んでいるので、ソースが汚い点はお許しを。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="new Calendar(2008).draw(10, 10)">
<script type="text/ecmascript">
<![CDATA[
function $(i) { return document.getElementById(i); }
function isNumber(v) { return typeof(v) == 'number' && isFinite(v); }
var Calendar = function (y /* 年 */) {
if (!isNumber(y)) return;
this.y = y;
this.f = 14; // フォントサイズ
this.isLeapYear = function (y) { return y % 4 ? true : y % 100 ? false : y % 400 ? true : false; };
this.draw = function (l /* 左部余白 */, t /* 上部余白 */) {
var d = [ 31, (this.isLeapYear(this.y)) ? 28 : 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
var w = [ '日', '月', '火', '水', '木', '金', '土' ];
var i, m, o, s, x, y;
s = this.f / 2 /* 余白 */; y = t;
for (m = 0; m < 12; m++) {
// 年, 月
x = l; y += this.f + s;
o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
o.setAttribute('x', x);
o.setAttribute('y', y);
o.setAttribute('font-family', 'MS Gothic');
o.setAttribute('font-size', this.f + 'px');
o.setAttribute('text-rendering', 'optimizeLegibility');
o.appendChild(document.createTextNode(this.y + '/' + ((m + 1 < 10) ? ' ' : '') + (m + 1)));
document.rootElement.appendChild(o);
// 曜日
x = l; y += this.f + s;
for (i = 0; i < w.length; i++) {
o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
o.setAttribute('x', x);
o.setAttribute('y', y);
o.setAttribute('font-family', 'MS Gothic');
o.setAttribute('font-size', this.f + 'px');
o.setAttribute('text-rendering', 'optimizeLegibility');
o.appendChild(document.createTextNode(w[i]));
document.rootElement.appendChild(o);
x += this.f + s;
}
// 日
x = l + (this.f + s) * (new Date(this.y, m, 1).getDay()); y += this.f + s;
for (i = 0; i < d[m] ; i++) {
o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
o.setAttribute('x', (i + 1 < 10) ? x + s : x);
o.setAttribute('y', y);
o.setAttribute('font-family', 'MS Gothic');
o.setAttribute('font-size', this.f + 'px');
o.setAttribute('text-rendering', 'optimizeLegibility');
o.appendChild(document.createTextNode(i + 1));
document.rootElement.appendChild(o);
if (new Date(this.y, m, i + 1).getDay() == 6) {
x = l; y += this.f + s;
} else {
x += this.f + s;
}
}
y += this.f + s;
}
// ビューポート
document.rootElement.setAttribute('width', l + (this.f + s) * w.length);
document.rootElement.setAttribute('height', y);
// ビューボックス
document.rootElement.setAttribute('viewBox', '0 0 ' + (l + (this.f + s) * w.length) + ' ' + y);
document.rootElement.setAttribute('preserveAspectRatio', 'xMinYMin slice');
};
};
]]>
</script>
</svg>
|
Safari 3.0.4 (Windows版)で試したところ文字化けが発生したので、フォント指定を以下
のように変更して表示を確認。
e.g.
29c29, 40c40, 53c53
< o.setAttribute('font-family', 'monospace');
---
> o.setAttribute('font-family', 'MS Gothic');
PostScript 版です。A4一枚に出力します。
年号を変更するときには先頭部の書き換えが必要です。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | %!PS
/Year 2008 def
% Design Parameters
/Columns 3 def
/FontSize 10 def
20 600 /Y0 exch def /X0 exch def % Top Left Position
200 150 /VMY exch def /VMX exch def % Size of 1 Month
20 13 /VY exch def /VX exch def % Size of 1 Day
% Color / Font Settings , Tables
% [ Sunday Monday .... Saturday ]
/WColorR { [1 0 0 0 0 0 0] } def
/WColorG { [0 0 0 0 0 0 0] } def
/WColorB { [0 0 0 0 0 0 1] } def
/WFont { [ /Times-Bold /Times-Roman /Times-Roman /Times-Roman /Times-Roman
/Times-Roman /Times-Bold ] } def
/MonthName {[(January) (February) (March) (April) (May) (June)
(July) (Augusut) (September) (October) (November) (December)]} def
/WeekdayName {[(Sun) (Mon) (Tue) (Wed) (Thu) (Fri) (Sat)]} def
/MDays { [31 28 31 30 31 30 31 31 30 31 30 31] } def
% -------------------------------------------------------------------------
/MonthFont {/Times-Roman findfont FontSize 2 mul scalefont setfont 0 setgray} \
def
/SetFont { dup WFont exch get findfont FontSize scalefont setfont
dup WColorR exch get exch dup WColorG exch get exch
WColorB exch get setrgbcolor
} def
/POS { VY mul YM0 exch sub exch VX mul XM0 add exch moveto } def
/POS2 { WOffset add dup 7 mod exch 7 idiv 2 add POS } def
/LeapYear {dup 400 mod 0 eq exch dup 100 mod 0 eq not
exch 4 mod 0 eq and or } def
/MDay { dup MDays exch get exch 1 eq Year LeapYear and { 1 add } if } def
/ZellerFomula {
dup 2 le { 12 add exch 1 sub exch } if
13 mul 8 add 5 idiv exch dup 5 mul 4 idiv exch dup 100 idiv exch
400 idiv exch sub add add 1 add 7 mod
} def
/DrawTitle {
X0 150 add Y0 50 add moveto
/Times-Italic findfont 100 scalefont setfont
Year 4 string cvs show
} def
% -------------- Main Program -----------------
DrawTitle
0 1 11 {
/Month exch def
MonthFont
/XM0 X0 Month Columns mod VMX mul add def
/YM0 Y0 Month Columns idiv VMY mul sub def
XM0 YM0 moveto
Month 1 add 4 string cvs show
MonthName Month get 10 0 rmoveto show
0 1 6 {
dup SetFont
dup 1 POS
WeekdayName exch get show
} for
/WOffset Year Month 1 add ZellerFomula def
0 1 Month MDay 1 sub {
dup POS2
dup WOffset add 7 mod SetFont
1 add 3 string cvs show
} for
grestore
} for
showpage
|
またも失敗。
72行は不要です。
月曜始まりにするには
4行目に
/StartMonday true def
を追加
33行目変更
/POS2 { WOffset StartMonday { 6 add 7 mod } if
add dup 7 mod exch 7 idiv 2 add POS } def
63行目変更
dup StartMonday { 6 add 7 mod } if 1 POS
C言語復習中です. % ./a.out 2008 Calendar 2008 : #=Sun @=Sat Jan | 01 02 03 04 @05 #06 07 08 09 10 11 @12 #13 14 15 16 17 18 @19 #20 21 22 23 24 25 @26 #27 28 29 30 31 Feb | 01 @02 #03 04 05 06 07 08 @09 #10 11 12 13 14 15 @16 #17 18 19 20 21 22 @23 #24 25 26 27 28 29 Mar | @01 #02 03 04 05 06 07 @08 #09 10 11 12 13 14 @15 #16 17 18 19 20 21 @22 #23 24 25 26 27 28 @29 #30 31 Apr | 01 02 03 04 @05 #06 07 08 09 10 11 @12 #13 14 15 16 17 18 @19 #20 21 22 23 24 25 @26 #27 28 29 30 May | 01 02 @03 #04 05 06 07 08 09 @10 #11 12 13 14 15 16 @17 #18 19 20 21 22 23 @24 #25 26 27 28 29 30 @31 Jun | #01 02 03 04 05 06 @07 #08 09 10 11 12 13 @14 #15 16 17 18 19 20 @21 #22 23 24 25 26 27 @28 #29 30 Jul | 01 02 03 04 @05 #06 07 08 09 10 11 @12 #13 14 15 16 17 18 @19 #20 21 22 23 24 25 @26 #27 28 29 30 31 Aug | 01 @02 #03 04 05 06 07 08 @09 #10 11 12 13 14 15 @16 #17 18 19 20 21 22 @23 #24 25 26 27 28 29 @30 #31 Sep | 01 02 03 04 05 @06 #07 08 09 10 11 12 @13 #14 15 16 17 18 19 @20 #21 22 23 24 25 26 @27 #28 29 30 Oct | 01 02 03 @04 #05 06 07 08 09 10 @11 #12 13 14 15 16 17 @18 #19 20 21 22 23 24 @25 #26 27 28 29 30 31 Nov | @01 #02 03 04 05 06 07 @08 #09 10 11 12 13 14 @15 #16 17 18 19 20 21 @22 #23 24 25 26 27 28 @29 #30 Dec | 01 02 03 04 05 @06 #07 08 09 10 11 12 @13 #14 15 16 17 18 19 @20 #21 22 23 24 25 26 @27 #28 29 30 31
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 | #include<stdio.h>
#include<time.h>
int main(int argc, char *argv[])
{
int d = -1;
char date[6], date_m[6];
time_t date_tmp;
struct tm *date_t;
int year = atoi(argv[1]);
time(&date_tmp);
date_t = localtime(&date_tmp);
date_t->tm_year = year - 1900;
date_t->tm_mon = 0;
date_t->tm_mday = 1;
printf("Calendar %d : #=Sun @=Sat", year);
while (year == date_t->tm_year + 1900) {
if (d < date_t->tm_mon) {
printf("\n");
d = date_t->tm_mon;
strftime(date_m, 6, "%b", date_t);
printf("%s | ", date_m);
}
if (date_t->tm_wday == 0) {
printf("#");
} else if (date_t->tm_wday == 6) {
printf("@");
}
strftime(date, 6, "%d", date_t);
printf("%s ", date);
date_t->tm_mday += 1;
date_tmp = mktime(date_t);
date_t = localtime(&date_tmp);
}
putchar('\n');
}
|
365行(or 366行)をだらーっと出力しますが、年間のカレンダーには一応なっています。 +------------------------+ | date | +------------------------+ | 2008/1/1 (Tuesday) | | 2008/1/2 (Wednesday) | | 2008/1/3 (Thursday) | (略) | 2008/12/29 (Monday) | | 2008/12/30 (Tuesday) | | 2008/12/31 (Wednesday) | +------------------------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | -- いつものように数字を用意しておく
DROP TABLE if exists num_chars;
CREATE TABLE num_chars(id int not null);
INSERT INTO num_chars VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
DROP TABLE if exists nums;
CREATE TABLE nums as (
SELECT n1.id + (n2.id * 10) + (n3.id * 100) as id
FROM num_chars n1, num_chars n2, num_chars n3);
-- 2008年を指定
SET @ycalendar = 2008;
SELECT date_format(makedate(@ycalendar, id), '%Y/%c/%e (%W)') as date
FROM nums
WHERE nums.id between 1 and (365 + day(last_day(concat(@ycalendar, '-2-1'))) - 28);
|
Calendar.~ の文字があまりに多すぎるため、 static importで回避しています。 これって正しい使いかたですか?
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 | import java.text.*
import static java.util.Calendar.*
n = 2008
def firstDate = Calendar.getInstance()
def lastDate = Calendar.getInstance()
(0..11).each{ m ->
firstDate.set(n, m, 1)
lastDate.set(n, m+1, 0)
println """< ${new SimpleDateFormat("yyyy/MM/dd").format(firstDate.time)} >"""
["日", "月", "火", "水", "木", "金", "土"].each {
print it.padLeft(3)
}
println()
(firstDate.get(DAY_OF_WEEK)-SUNDAY).times {
print "".padLeft(4)
}
(firstDate.get(DATE)..lastDate.get(DATE)).each { d ->
def eachday = Calendar.getInstance()
eachday.set(n, m, d)
print d.toString().padLeft(4)
if( eachday.get(DAY_OF_WEEK) == SATURDAY ){
println()
}
}
println()
println()
}
|
出力はシンプルなHTMLのtableで。 しかし、曜日を取得する関数を自作しなきゃいかんとわ...
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | <xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:my="uri:ja.doukaku.org:my-functions"
exclude-result-prefixes="xs fn my"
>
<xsl:param name="n" as="xs:integer" >2008</xsl:param>
<xsl:output method="html" />
<xsl:template match="/" >
<html>
<head>
<title><xsl:value-of select="$n" />年の年間カレンダー</title>
</head>
<body>
<h1><xsl:value-of select="$n" />年の年間カレンダー</h1>
<xsl:for-each select="1 to 12">
<hr />
<h2><xsl:value-of select="." />月</h2>
<xsl:call-template name="mcalender">
<xsl:with-param name="year" select="$n" />
<xsl:with-param name="month" select="." />
</xsl:call-template>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name="mcalender">
<xsl:param name="year" as="xs:integer" />
<xsl:param name="month" as="xs:integer" />
<!-- 今月1日 -->
<xsl:variable name="first-date" as="xs:date"
select="xs:date(
fn:string-join(
(my:pad($year,4),my:pad($month,2),'01'),
'-'))" />
<!-- 次月1日 -->
<xsl:variable name="next-first-date" as="xs:date">
<xsl:choose>
<xsl:when test="$month=12">
<xsl:value-of
select="xs:date(
fn:string-join(
(my:pad($year+1,4),'01','01'),
'-'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="xs:date(
fn:string-join(
(my:pad($year,4),my:pad($month+1,2),'01'),
'-'))" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- 今月の日数を求める -->
<xsl:variable name="days" as="xs:integer"
select="fn:days-from-duration($next-first-date - $first-date)" />
<!-- 今月1日 の曜日を求める -->
<xsl:variable name="start-day" as="xs:integer"
select="my:get-day($first-date)" />
<!-- カレンダーの左上の開始日 -->
<xsl:variable name="rstart" as="xs:integer"
select="1 - $start-day" />
<!-- カレンダーの右下の終了日 -->
<xsl:variable name="rend" as="xs:integer">
<xsl:choose>
<xsl:when test="(($days - $rstart + 1) mod 7)=0">
<xsl:value-of select="$days - $rstart + 1" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="((($days - $rstart+1) idiv 7)+1)*7" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<table border="1">
<xsl:call-template name="calender-header" />
<xsl:for-each select="1 to $rend idiv 7">
<tr>
<xsl:for-each select="$rstart+((.-1)*7) to $rstart+(.*7)-1">
<td>
<xsl:choose>
<xsl:when test="1 <= . and . <= $days">
<xsl:value-of select="." />
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="calender-header">
<tr>
<xsl:for-each select="('日','月','火','水','木','金','土')">
<th><xsl:value-of select="." /></th>
</xsl:for-each>
</tr>
</xsl:template>
<!-- 曜日を取得する -->
<xsl:function name="my:get-day" as="xs:integer">
<xsl:param name="date" as="xs:date" />
<xsl:variable name="epoch" as="xs:date"
select="xs:date('1970-01-01')" />
<xsl:variable name="day" as="xs:integer"
select="(fn:days-from-duration($date - $epoch) + 4) mod 7" />
<xsl:choose>
<xsl:when test="$day < 0">
<xsl:value-of select="$day + 7" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$day" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="my:pad" as="xs:string">
<xsl:param name="i" as="xs:integer" />
<xsl:param name="digit" as="xs:integer" />
<xsl:variable name="seq" as="xs:string*">
<xsl:for-each
select="1 to $digit - fn:string-length(xs:string($i))">
<xsl:sequence select="'0'" />
</xsl:for-each>
<xsl:sequence select="xs:string($i)" />
</xsl:variable>
<xsl:value-of select="fn:string-join($seq, '')" />
</xsl:function>
</xsl:stylesheet>
|
Gauche で書いてみました。
出力部が意外と長くなってしまった。
出力例:
<< 2007/1 >>
Sun Mon Tue Wed Thu Fri Sat
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
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 | (use srfi-1)
(use srfi-19)
(use gauche.collection)
(use gauche.sequence)
(define (show-calendar n)
(define (leap-year? n)
(or (zero? (modulo n 400))
(and (zero? (modulo n 4))
(not (zero? (modulo n 100))))))
(define week-days
(circular-list 0 1 2 3 4 5 6))
(define (make-calendar)
(map (lambda (month days)
(let ((m (date-week-day (make-date 0 0 0 0 1 month n 0))))
(append (make-list m #f) (take (drop week-days m) days))))
(iota 12 1)
`(31 ,(if (leap-year? n) 29 28) 31 30 31 30 31 31 30 31 30 31)))
(for-each-with-index
(lambda (i ws)
(format #t " << ~A/~A >>~%" n (+ i 1))
(format #t "Sun Mon Tue Wed Thu Fri Sat~%")
(let loop ((ws ws) (d 1))
(cond
((null? ws)
(format #t "~%~%"))
((not (car ws))
(format #t " ")
(loop (cdr ws) d))
(else
(format #t (case (car ws)
((0) "<~2@A> ")
((6) "[~2@A]~%")
(else " ~2@A "))
d)
(loop (cdr ws) (+ d 1))))))
(make-calendar)))
(define (main args)
(show-calendar (string->number (cadr args))))
|
Lua始めました。
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 45 46 47 48 49 50 51 52 53 54 55 | -- 閏年かどうか判定
L =
function (y)
if y % 400 == 0 then return 1 end
if y % 100 == 0 then return 0 end
if y % 4 == 0 then return 1 end
return 0
end
-- 指定された日の曜日を取得
W =
function (y, m, d)
return tonumber(os.date('%w', os.time({ year = y, month = m, day = d })))
end
(function (v)
local d = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local w = { 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' }
local m, t, y
if #v ~= 2 then
io.stderr:write('usage: ' .. v[0] .. ' [month] [year]\n')
return 1
end
m, y = tonumber(v[1]), tonumber(v[2])
if m == nil or y == nil then
io.stderr:write('usage: ' .. v[0] .. ' [month] [year]\n')
return 1
end
if m < 1 or m > 12 then
io.stderr:write('cal: illegal month value: use 1-12\n')
return 1
end
if y < 1 or y > 9999 then
io.stderr:write('cal: illegal year value: use 1-9999\n')
return 1
end
-- 閏日を補正
d[2] = d[2] + L(y)
t = string.format('%4d/%2d', y, m) .. '\n'
.. table.concat(w, ' ') .. '\n'
.. string.rep(' ', W(y, m, 1))
for i = 1, d[m] do
t = t .. string.format('%2d', i)
t = W(y, m, i) < 6 and t .. ' ' or t .. '\n'
end
print(t)
return 0
end)(arg)
|






186
#4884()
Rating4/4=1.00
nを入力としてn年の年間カレンダーを返すプログラムを作ってください 少なくとも日曜日と土曜日が判別出来るようにしてください 出力は標準出力でもファイルでも構いません デザインは各自のお好みで 出力例1: (y-calendar 2008)=> #=Saturday, @=Sunday 2008/1 1 2 3 4 #5 @6 7 ... 2008/2 1 #2 @3 4 5 6 7 ... ... 2008/12 1 2 3 4 5 #6 @7 ... 出力例2: (y-calendar 2008)=> M T W T F S S M 2008/ 1 1 2 3 4 5 6 7 ... 2008/ 2 1 2 3 4 ... ... 2008/12 1 2 3 4 5 6 7 8 ... 出力例3: (y-calendar 2008)は2008.htmlを出力する 2008.htmlの中身 ---- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>2008 calendar</title> <style type="text/css"> * {font-family: monospace;} span {margin: 0px 3px;} span.sunday {color:red;font-weight:bold;} span.saturday {color:blue;font-weight:bold;} dd ul li{display:inline;} </style> </head> <body> <h1>2008 calendar</h1> <dl> <dt>2008/1</dt> <dd><ul> <li><span class="weekday">1</span></li> <li><span class="weekday">2</span></li> <li><span class="weekday">3</span></li> <li><span class="weekday">4</span></li> <li><span class="saturday">5</span></li> <li><span class="sunday">6</span></li> ... </ul></dd> ... </dl> </body> </html> ----[ reply ]