Skip to content

Instantly share code, notes, and snippets.

@MeilCli
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MeilCli/11115799 to your computer and use it in GitHub Desktop.
Save MeilCli/11115799 to your computer and use it in GitHub Desktop.
/*
* 日付を引数に与えたら何の日か表示されるカレンダー的なの作ってみた
* ※正確な値と違うかもだから何があっても(勘違いとか)自己責任でね
*
* ------------使い方-----------
* 使える形にコンパイルなりなんなりしてコマンドプロンプトとかで引数で日付を与えて起動
* (与えないと2014/4/1-2015/3/31までリストアップ表示)
* ※日付の形式:{年}/{月}/{日} (例)2014/5/5
*
* ポインターとかメモリとか考えずに作った()
* strlenのとこででる警告の意味わからないから放置してるww
*
* */
#include <stdio.h>
int countC(char s[],char c);
int indexOf(char s[],char c,int off);
struct String substring(char s[],int start,int end);
struct Date makeDate(char s[]);
int is4year(int y);
int relativeDays(struct Date d);
struct DetailDate makeDetailDate(struct Date d,int r);
int checkDate(struct Date d);
void printDate(struct DetailDate date);
void print2014to2015();
struct Date { //時間
int y; //年
int m; //月
int d; //日
};
struct DetailDate { //時間
int y; //年
int m; //月
int d; //日
int t; //曜日(日=0,月=1,...
int e; //何週目か(1,2,...
};
struct String {
char *s;
};
struct Holiday {
int m; //月
int d; //日
char *s; //何の日か
};
struct HolidayE {
int m; //月
int t; //曜日(日=0,月=1,...
int e; //何週目か(1,2,...
char *s; //何の日か
};
struct DetailDate base={2014,1,1,3,1}; //基準日
int baseM[]={31,59,90,120,151,181,212,243,273,304,334,365}; //年初めからの日数
int baseM4[]={31,60,91,121,152,182,213,244,274,305,335,366}; //年初めからの日数(閏年)
//国民の祝日(春・秋分の日は別計算)
struct Holiday chs[]={{1,1,"元旦"},{2,11,"建国記念日"},{4,29,"昭和の日"},{5,3,"憲法記念日"},{5,
4,"みどりの日"},{5,5,"こどもの日"},{11,3,"文化の日"},{11,23,"勤労感謝の日"},{12,23,"天皇誕生日"}};
struct HolidayE ches[]={{1,1,2,"成人の日"},{7,1,3,"海の日"},{9,1,3,"敬老の日"},{10,1,2,
"体育の日"}};
//関大制定の記念日
struct Holiday khs[]={{6,5,"大学昇格記念日"},{11,4,"大学創立記念日"}};
int main(int argi,char *arg[]){
printf("Start\n");
if(argi==1){ //引数なかった時
print2014to2015();
return 0;
}
char *p;
p=arg[1];
int size=strlen(p);
char s[size]; //入力された日付を格納する配列
int i;
for(i=0;i<size;i++){
s[i]=*p;
p++;
}
printf("入力したのは\n");
for(i=0;i<size;i++){
printf("%c",s[i]);
}
printf("\nです\n");
int cnt=countC(s,'/');
if(cnt!=2){
printf("不正な入力値です\n");
return 0;
}
struct Date date=makeDate(s);
if(checkDate(date)==0){
printf("不正な日時です\n");
}
struct DetailDate detail=makeDetailDate(date,relativeDays(date));
printDate(detail);
return 0;
}
int countC(char s[],char c){
int size=strlen(s);
int i=0;
int count=0;
for(i=0;i<size;i++){
if(s[i]==c){
count++;
}
}
return count;
}
//見つからなかったら-1を返す
int indexOf(char s[],char c,int off){
int size=strlen(s);
int i=0;
for(i=off;i<size;i++){
if(s[i]==c){
return i;
}
}
return -1;
}
struct String substring(char s[],int start,int end){
int size=end-start;
int i;
int ni;
char nc[size];
for(i=start,ni=0;i<end;i++,ni++){
nc[ni]=s[i];
}
struct String ns={nc};
return ns;
}
struct Date makeDate(char s[]){
int y=0;
int m=0;
int d=0;
int off=0;
{ //年取得
int next_off=indexOf(s,'/',off);
char* t=substring(s,off,next_off).s;
off=next_off;
int size=strlen(t);
char s[size];
int i;
for(i=0;i<size;i++){
s[i]=*t;
t++;
}
y=atoi(s);
off++;
}
{ //月取得
int next_off=indexOf(s,'/',off);
char* t=substring(s,off,next_off).s;
off=next_off;
int size=strlen(t);
char s[size];
int i;
for(i=0;i<size;i++){
s[i]=*t;
t++;
}
m=atoi(s);
off++;
}
{ //日取得
char* t=substring(s,off,strlen(s)).s;
int size=strlen(t);
char s[size];
int i;
for(i=0;i<size;i++){
s[i]=*t;
t++;
}
d=atoi(s);
}
struct Date date={y,m,d};
return date;
}
int is4year(int y){
return (y%4)==0&&(y%100)!=0||(y%400)==0;
}
int relativeDays(struct Date d){ //基準日からの日数を調べる
int days=0;
if(d.y-base.y>0){ //一年以上差があった時に一年の日数を追加
int y;
for(y=base.y;y<d.y;y++){
if(is4year(y)==0){
days=days+365;
}else{ //閏年
days=days+366;
}
}
}
//このあとは当年次の動作
if(d.m>1){ //2月以降の時あらかじめ出しておいた日数を追加
if(is4year(d.y)==0){
days=days+baseM[d.m-2]; //前月のとこの値を得る
}else{ //閏年
days=days+baseM4[d.m-2];
}
}
days=days+d.d;
return days;
}
struct DetailDate makeDetailDate(struct Date d,int r){ //r=基準日からの日数
int t=base.t;
{ //曜日処理
t=t+(r-1)%7; //基準日も含まれているためずらしてから計算
if(t>6){ //次週に飛んでいた場合ずらす
t=t-7;
}
}
int e=1;
{ //週処理
int de=d.d-t; //当週の日曜日(週始め)に飛ばす
int ne=de%7; //7で割ったあまり
int pe=(de-ne)/7; //7で割った商
e=e+pe; //月-日の完全体の数を追加
if(ne>1){ //第一日曜日が月初めではなく余ってた時週が一つずれる
e++;
}
}
struct DetailDate detail={d.y,d.m,d.d,t,e};
return detail;
}
int checkDate(struct Date d){ //return 1=正常値
if(d.y<2014){ //基準日過去にする必要あり
return 0;
}
if(d.m<0||d.m>12){
return 0;
}
if(d.d<0){
return 0;
}
if(d.m==1||d.m==3||d.m==5||d.m==7||d.m==8||d.m==10||d.m==12){
if(d.d>31){
return 0;
}
}
if(d.m==4||d.m==6||d.m==9||d.m==11){
if(d.d>30){
return 0;
}
}
if(d.m==2){
if(is4year(d.y)==0){
if(d.d>28){
return 0;
}
}else{ //閏年
if(d.d>29){
return 0;
}
}
}
return 1;
}
void printDate(struct DetailDate date){
printf("\n");
printf("%d年%d月%d日 第%d",date.y,date.m,date.d,date.e);
if(date.t==0){
printf("日曜日");
}else if(date.t==1){
printf("月曜日");
}else if(date.t==2){
printf("火曜日");
}else if(date.t==3){
printf("水曜日");
}else if(date.t==4){
printf("木曜日");
}else if(date.t==5){
printf("金曜日");
}else if(date.t==6){
printf("土曜日");
}
printf(" ");
{ //祝日判定
int i;
int size=sizeof(chs);
for(i=0;i<size;i++){
struct Holiday d=chs[i];
if(date.m==d.m&&date.d==d.d){
printf("%s",d.s);
goto END;
}
}
}
{ //祝日判定
int i;
int size=sizeof(ches);
for(i=0;i<size;i++){
struct HolidayE d=ches[i];
if(date.m==d.m&&date.e==d.e&&date.t==d.t){
printf("%s",d.s);
goto END;
}
}
}
{ //記念日判定
int i;
int size=sizeof(khs);
for(i=0;i<size;i++){
struct Holiday d=chs[i];
if(date.m==d.m&&date.d==d.d){
printf("%s",d.s);
goto END;
}
}
}
{ //春分の日判定 参考:http://ja.wikipedia.org/wiki/%E6%98%A5%E5%88%86%E3%81%AE%E6%97%A5
if(date.m!=3){
goto END3;
}
int p4=date.y%4;
if(p4==0){
if(date.y<2098){
if(date.d==20){
printf("春分の日(推測値)");
goto END;
}
}else{
if(date.d==19){
printf("春分の日(推測値)");
goto END;
}
}
}else if(p4==1||p4==2){
if(date.d==20){
printf("春分の日(推測値)");
goto END;
}
}else if(p4==3){
if(date.y<2056){
if(date.d==21){
printf("春分の日(推測値)");
goto END;
}
}else{
if(date.d==20){
printf("春分の日(推測値)");
goto END;
}
}
}
END3:;
}
{ // 秋分の日判定 参考:http://ja.wikipedia.org/wiki/%E7%A7%8B%E5%88%86%E3%81%AE%E6%97%A5
if(date.m!=9){
goto END9;
}
int p4=date.y%4;
if(p4==0){
if(date.d==22){
printf("秋分の日(推測値)");
goto END;
}
}else if(p4==1){
if(date.y<2042){
if(date.d==23){
printf("秋分の日(推測値)");
goto END;
}
}else{
if(date.d==22){
printf("秋分の日(推測値)");
goto END;
}
}
}else if(p4==2){
if(date.y<2075){
if(date.d==23){
printf("秋分の日(推測値)");
goto END;
}
}else{
if(date.d==22){
printf("秋分の日(推測値)");
goto END;
}
}
}else if(p4==3){
if(date.d==23){
printf("秋分の日(推測値)");
goto END;
}
}
END9:;
}
END:;
if(date.y==2014){
if((date.m==4&&date.d>4)||(date.m==7&&date.d<25)||(date.m>4&&date.m<7)){ //春学期
printf(" (授業期間)");
}
if((date.m==7&&date.d>24)||(date.m==8&&date.d==1)){ //春学期
printf(" (試験期間)");
}
if((date.m==9&&date.d>21)||(date.m==12&&date.d<27)
||(date.m>9&&date.m<12)){ //秋学期
printf(" (授業期間)");
}
}else if(date.y==2015){
if((date.m==1&&date.d>5)||(date.m==1&&date.d<23)){ //秋学期
printf(" (授業期間)");
}
if(date.m==1&&(date.d>22||date.d<31)){
printf(" (試験期間)");
}
}
}
void print2014to2015(){ //2014/6/27の出力途中で255コードで終了するなんでだろ(笑)
int m;
int d;
for(m=4;m<13;m++){
for(d=1;;d++){
struct Date date={2014,m,d};
struct DetailDate detail=makeDetailDate(date,relativeDays(date));
printDate(detail);
if((m==5||m==7||m==8||m==10||m==12)&&d==31){
break;
}
if((m==4||m==6||m==9||m==11)&&d==30){
break;
}
}
}
for(m=1;m<4;m++){
for(d=1;;d++){
struct Date date={2015,m,d};
struct DetailDate detail=makeDetailDate(date,relativeDays(date));
printDate(detail);
if((m==1||m==3)&&d==31){
break;
}
if(m==2&&d==28){
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment