曜日が変わらないカレンダーについて書きましたが、これをJavaScriptのユーザー定義関数にしてみました。
JavaScriptの通常の日付(日付オブジェクト、ndate)を与えると「ハンキ・ヘンリー・パーマネント・カレンダー」における日付(文字列、pdate)に変換します。
返る値は「2012-1-19」という形式です。
使い道が思い当たりませんが。
function date2hhpc(ndate) {
var di, ldi, preldi, y, ydi, isext, sdi, pdate;
di = (ndate - (new Date(2012, 0, 1))) / 86400000; //日のインデックス。2012-01-01(初日)を0日目とする
if (di < 0 || di > 20453) { //対応しているのは2012年から2167年まで
return ("error");
}
ldi = -1; //大晦日のインデックス
year = 2011;
while (di > ldi) {
year++;
preldi = ldi; //前年の大晦日
isext = String(year).match(/(2015|2020|2026|2032|2037|2043|2048|2054|2060|2065|2071|2076|2082|2088|2093|2099|2105|2111|2116|2122|2128|2133|2139|2144|2150|2156|2161|2167)/) ? 1 : 0;
ldi += 364 + isext * 7;
}
ydi = di - preldi - 1;
if (ydi > 363) {
pdate = "E/" + (ydi - 363);
} else {
sdi = ydi % 91;
x = Math.floor(sdi / 30) + 1;
x = (x > 3) ? 3 : x;
pdate = (Math.floor(ydi / 91) * 3 + x) + "-" + (sdi - 30 * (x - 1) + 1);
}
return (year + "-" + pdate);
}
毎年、曜日が変わらないカレンダーが紹介されていました。
[曜日が変わらない「合理的な新しい暦」 ≪ WIRED.jp 世界最強の「テクノ」ジャーナリズム]
このカレンダーは発案者の名前から「ハンキ・ヘンリー・パーマネント・カレンダー」と名付けられています。
- 毎年1月1日が日曜日から始まる。
- 年間364日。1月は30日まで、2月は30日まで、3月は31日まで、以下同様に12月まで。
- 何年かに一度、「追加週」を7日間、加える。曜日はずれず、これにより公転周期とのずれが修正される。
メリットは年によって曜日がずれないので毎年、同じスケジュールが使えるということ。確かに毎年、同じようなことをやっているのに、スケジュールの見直しをしていますが、これが不要に。
特に元日やクリスマスが日曜日に固定されるので仕事に支障をきたすことがありません。
カレンダー以外の主張としては、「時差を気にせず、世界中で、世界標準時を使おう」というのがあります。
「正午にキックオフ(日本時間午後9時)」という表記、注釈は不要です。この場合、日本でも『12時』にキックオフです。「午前9時から午後5時まで」は『0時から8時まで』となります。
素晴らしいアイディアですが、気になる点があります。
- 給与はどうするのか?通常は月給だと思いますが追加週のある年は給与も追加されるのでしょうか。もっとも現行のカレンダーでも30日までの月と31日までの月は同じ給与で誰も文句は言いませんが。
- 世界中で世界標準時を使うと、勤務時間が『23時から7時まで』の場合、勤務日は当日なのか、翌日なのか?「昨日」や「明日」も安易に使えません。一々『15日の23時』などと日付を付けないと危ないかもしれません。
曜日の変わらないカレンダーと言うことならば、こんなカレンダーはどうでしょうか。
- 毎年1月1日が日曜日から始まる。
- 各月の日数は現行と同じ。
- 2月は固定して29日までとする。12月は通常は30日、閏年は31日までとする。
この方式だと2012年のカレンダーがそのまま使えます。
現行のカレンダーは、閏年の調整を2月という半端な位置で行うのが、問題の一つだと思います。これを12月の最後に行えばよいでしょう。日本ならば、どうせ年末で休むのだから。
今年だと12月30日が日曜日、31日が月曜日、翌年1月1日が日曜日、となります。2013年のカレンダーは12月31日がなくなるだけ。
ある日からその日を含んでX日を経過した日をExcelで求めるには「始期となる日+X-1」とすればOKです。
では日曜日を含まないで計算するにはどうしたらよいでしょうか。
たとえば2011年12月8日(木)の7日経過した日は単純に計算すると14日(水)になります。
しかし日曜日を含まない場合、8日(木)の7日経過した日は15日(木)になります。
「木、金、土、月、火、水、木」と日曜日をとばすからです。
この日曜日をとばすという処理が面倒です。 続きを読む…
PHPのdate関数は日付を整形するときによく使うのですが、フォーマット文字列をすぐに忘れてしまうので、よく使うものだけをピックアップして整理してみました。
| 区分 |
数値 |
英文字 |
| 年 |
Y (4桁)、y (2桁) |
| 月 |
m (2桁)、n (1or2桁) |
F (フル)、M (3文字) |
| 日 |
d (2桁)、j (1or2桁) |
| 曜日 |
w (0:日曜日) |
l (フル)、D (3文字) |
| 時 |
H (2桁)、G (1or2桁) |
| 分 |
i (2桁) |
| 秒 |
s (2桁) |
※「O」はグリニッジ標準時との時差。
サンプル
date(“Ymd”)→「20110901」
date(“Y-m-d”)→「2011-09-01」
date(“Y-n-j”)→「2011-9-1」
date(“D M j H:i:s \U\T\CO Y”)→「Thu Sep 1 14:26:38 UTC+0900 2011」
※JavaScript(IE)の日付。
date(“D M d Y H:i:s \G\M\TO”)→「Thu Sep 01 2011 14:26:38 GMT+0900」
※JavaScript(Firefox)の日付。
date(“c”)→「2011-09-01T14:26:38+09:00」
※ISO8601の日付。
date(“r”)→「Thu, 01 Sep 2011 14:26:38 +0900」
※RFC2822の日付。
余命計算機を作りました。
余命計算機
生年月日と性別を入力すると「現在まで生きてきた日数」と「これから生きる日数(余命)」を計算します。
余命は「生命表」というものを見ると分かるのですが、それをもっと手軽に分かるようにしたのが「余命計算機」です。
なお「生命表」は厚生労働省のウェブサイトにあります。今回は平成21年簡易生命表を使いました。
東日本大地震が起きたのが3月11日。
ちょうど3か月が経過しました。
これを自動的にカウントするJavaScriptのコードを書いてみました。
document.write(count_ymd());
function count_ymd() {
var fdy = 2011,
fdm = 3 - 1,
fdd = 11;
var td = new Date();
var tdy = td.getFullYear(),
tdm = td.getMonth(),
tdd = td.getDate();
var dy = tdy - fdy;
var dm = tdm - fdm;
var dd = tdd - fdd;
if (dd < 0) {
dd = (new Date(tdy, tdm, 0)).getDate() - fdd + tdd;
dm--;
}
if (dm < 0) {
dm = dm + 12;
dy = dy - 1;
}
return ((dy > 0 ? dy + "年" : "") + (dm + "か月") + (dd > 0 ? dd + "日" : "ちょうど"));
}
JavaScriptの日付オブジェクトは、年、月、日とバラバラにセットして使いますが、日付を表す文字列をセットしても日付として認識します。
document.write(new Date("15 June 2008"));
これを実行すると次の通り表示されます。
Sun Jun 15 00:00:00 UTC+0900 2008
では、どのような日付文字列ならば正しく処理されるのでしょうか。 続きを読む…
「20101231」という8桁で表示された日付をExcelで使える形式、シリアル値に変換する方法をまとめておきます。
=DATE(INT(A1/10000),MOD(INT(A1/100),100),MOD(A1,100))
DATE関数を使い、年、月、日をそれぞれ代入すれば、シリアル値に変換できます。
年は10000で割って切り捨て。
月は100で割って切り捨て、さらに100で割った余り。
日は100で割った余り。
=DATE(LEFT(A2,4),MID(A2,5,2),RIGHT(A2,2))
8桁の数値を文字列としてとらえる方法です。
年は左から4文字。
月は左から5番目から2文字。
日は右から2文字。
=VALUE(TEXT(A3,”0000!/00!/00″))
TEXT関数を使い表示形式を変える方法です。
「20101231」を「2010/12/31」という形式に変えます。
これを数値に変換すればExcelでは日付として認識します。
=VALUE(TEXT(A4,”00!/00!/00″))
応用として「101231」という6桁で表示された日付を変換します。
Twilogでは日付がこの形式で出力されます。
一見すると「10/12/31」という形式になりそうですが、Excel(2007)では年の部分について次の通り解釈します。
「00」から「29」までは、2000年から2029年まで。
「30」から「99」までは、1930年から1999年まで。
この仕組みにより、問題なく変換されます。心配ならば先頭に「20」を付加してもよいでしょう。
なお「29」を2029年と解釈するところはWindowsで設定を変えられます。
XPの場合、コントロールパネルの「[地域と言語のオプション」を探すと「2桁の数字で年を入力すると、次の範囲内での暦年として解釈されます」という箇所があります。
Windows7の場合、「地域と言語」に同様の箇所があります。
Excelのワークシート関数の「DATEDIF」で引数に「MD」を使うと月未満の日数が計算できます。
バグがあることで有名ですが、具体的な不具合を挙げておきます。
月末から1日まで
明らかにおかしいのは終期を3月1日にした場合。値がマイナスになります。
DATEDIFのロジックはおそらく終期の前月の応当日から数えるようになっているようです。「2月31日から3月1日まで」というありえない日付で計算するのでこのような不具合が生じるのだと思います。 続きを読む…
今月(2010年10月)は金曜日、土曜日、日曜日が5回あります。
三日続きの週末が他の月よりも多いということになります。
「だから何だ」と言われるかもしれませんが。
| 月 |
火 |
水 |
木 |
金 |
土 |
日 |
|
|
|
|
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 |
2038年1月までの「金土日」が5回ある月をリストアップしてみました。
以後、28年周期で繰り返されます。「13日の金曜日の規則性」で書いたようにカレンダーは28年周期になります。 続きを読む…
最近のコメント