特定の年のゼロ日(1月1日)の曜日を把握しようとしています。
これまで、ウィキペディアのページ「曜日の計算」を見てきましたが、ゼロ日を見つけようとしているだけの場合、最も簡単なアルゴリズムがあるかどうか疑問に思いました。
これが簡単なワンライナーです。私はこれを、Excelを使用して1901-2200年、Pythonを使用して1582-3000年の間ずっと検証してきましたdatetime
。
dayOfWeek = (year*365 + trunc((year-1) / 4) - trunc((year-1) / 100) +
trunc((year-1) / 400)) % 7
これにより、曜日は0 =日曜日、6=土曜日になります。この結果は、モジュロ7の前後に定数を追加することで簡単に調整できます。たとえば、Pythonの0 =月曜日の規則に一致させるには、モジュロの前に6を追加します。
ほとんどの言語は、日付を表現および操作するための機能を提供します...私は、いくつかの(おそらく不完全な)アルゴリズムを実装する代わりに、それらに依存します。
public String DayOfWeek()
{
int dayofweek;
int c,y,m,d;
int cc,yy;
String dayString;
//Im using the guassian algorithm for finding day of the week
cc = year/100;
yy = year - ((year/100)*100);
c = (cc/4) - 2*cc-1;
y = 5*yy/4;
m = 26*(month+1)/10;
d = day;
dayofweek = (c+y+m+d)%7;
switch(dayofweek)
{
case 0: dayString = "Sunday";
break;
case 1: dayString = "Monday";
break;
case 2: dayString = "Tuesday";
break;
case 3: dayString = "Wednesday";
break;
case 4: dayString = "Thursday";
break;
case 5: dayString = "Friday";
break;
case 6: dayString = "Saturday";
break;
default: dayString = "Sorry Could not compute month :(";
}
return dayString;
}
上記のコードはJavaで書かれている
ので、なぜ機能するのかわかりませんが、Google検索の奥深くにあるアルゴリズムを見つけて、すぐにプロジェクトに飛びつきました。上に表示されているのは、大学のJavaクラスで行っていたプロジェクトのために作成しなければならなかったメソッドであるため、私が作成したものですが、アルゴリズムは私自身のものではありません。
この方法は100%動作することが保証されています。私は歴史を通して何日も試し、正解がこの方法で見つかったものであることを確認するためにそれらを調べました。
日付をDD/MM / CCYY(ヨーロッパ形式)とします。ここで、DDは月の日、MMは月、CCは世紀の数字、YYは世紀内の年です。したがって、ウィルマの誕生日は1994年6月23日でした。世紀のCC桁から始めて、CC / 4- 2 * CC-1を計算し、結果を覚えておいてください。この演習のすべての部門で、残りを破棄し、全体を保持します。したがって、この例では、これは19/4=4マイナス2*19 = 38マイナス1であり、マイナス35
になります。ここで、年YYを使用して、5 * YY/4を計算します。この例では、5 * 94 = 470/4 = 117であり、残りを破棄します。これを既存の結果に追加すると、117-35 = 82になります。
月のMMを使用して、26 *(MM + 1)/10を計算します。この例では、これは26 * 7 = 182/10 = 18であり、残りを破棄します。これを現在の合計に追加すると、82 + 18=100になります。
最後に、日DDを追加します。ここで、100 + 23 = 123です。
ここで、結果を7で割り、余りを残します。ここで123(mod 7)= 4.日曜日をゼロ、月曜日= 1などとして数えると、4=木曜日になります。方法を知っていれば簡単です:-)
アルゴリズムはGaussによるものです。はい、私はユダヤ人とイスラム教徒などが異なるカレンダーを持っていることを知っています、そして私はさまざまなカレンダー改革について知っています、それでこれは現代のキリスト教に基づく標準化された日付にのみ適用されます、キリストのはりつけの日をチェックするためにそれを使用しないでください( -フィクション?)またはChaucerの誕生。
暗算(つまり、パブでビールを獲得する)としてこれを行うことができない場合は、鉛筆と紙(または電卓)を自由に使用してください。
MATLAB ルーチン:
関数 w = week_day(m,d,cy)
m > 2 の場合、m = m-2; それ以外の場合、m = m+10; cy = cy-1; 終わり;
c = 修正 (cy/100); y = mod(cy,100);
w = mod(d+fix(m*2.59)+fix(y*1.25)+fix(c*5.25),7);
コツは、3 月 1 日を年の最初の日とすることです。日付がうるう年かどうかは関係ありません。
例:
w = week_day(01,23,2016) ---> w = 6 {Sat) Today
w = week_day(12,31,1999) ---> w = 5 {Fri)
w = week_day(01,01,2000) ---> w = 6 {Sat)
w = week_day(02,28,1900) ---> w = 3 {Wed) not leap year
w = week_day(03,01,1900) ---> w = 4 {Thu)
w = week_day(02,29,2000) ---> w = 2 {Tue) leap year
w = week_day(03,01,2000) ---> w = 3 {Wed)
Mathwork File Exchange ファイル ID #54784 を参照してください。
フォン・チェン・チャン
#!/usr/local/bin/perl
use integer
%day= (0=>Sunday,1=>Monday,2=>Tuesday,3=>Wednesday,4=>Thursday,5=>Friday,6=>Saturday);
print("entered date is");
$day=30;
$month=11;
$year=2680;
$x=&day_of_week($year,$month,$day);
if($day>31||$month>12)
{
print("this date doesn't exist \n");
exit;
}
if($year%400 ==0 || ($year%100 != 0 && $year%4 == 0))
{
if($day>29&&$month==2)
{
printf("this date dosen't exist \n");
exit;
}
}
if($month==(4,6,9,11)&&$day>30)
{
printf("this date dosen't exist \n");
exit;
}
sub day_of_week{
my ($year,$month,$day)=@_;
print("yy/mm/dd: $year/$month/$day\n");
my $a=(14-$month)/12;
my $y=$year-$a;
my $m=$month+12*$a-2;
my $d=($day+$y+$y/4-$y/100+$y/400+31*$m/12)%7;
return $d;
}
if(exists($day{$x}))
{
print("$day{$x}\n");
}
else
{
print("invalid date entered\n");
}
「曜日の計算」に関するウィキペディアのページの下部には、必要なルールが記載されています。月と日をハードコーディングすることで、ツェラーの公式を単純化することもできます。
年は28年周期で繰り返されます。年を28で割り、それぞれの曜日を返します(曜日の値は配列/ベクトルに格納されます)。これは、最も高速で単純なアルゴリズムです。しかし、このアルゴリズムは、コードを読んでいる人にはまったくわかりません。どちらを選択するかは、高速、単純、または「明らかに正しい」かどうかによって異なります。
いつでも基準日を保持し、1年の日数(mod 7)を追加して集計を継続することができますが、Zachが述べたように、組み込み関数の使用ははるかに簡単になります。