質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1545閲覧

2つのグレゴリオ暦を修正ユリウス通日に変換して差を求めてグレゴリオ暦に直すと誤差がひどい

Kazumori102

総合スコア45

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/03/05 04:37

編集2019/03/05 09:07

前提・実現したいこと

二つの日付の差を年月日で求めたい。

発生している問題・エラーメッセージ

そのためタイトルの通りのことをしたが、なんか誤差がひどい。
変換式の仕様なのか、コーディングのバグなのか、Cの仕様なのか、わからない。
素直に、日めくり方式がいいのだろうか。

コードはこちら

C

1#include <stdio.h> 2#include <string.h> 3#include <ctype.h> 4#include <stdlib.h> 5#include <time.h> 6#include <math.h> 7 8void mjd2data(int mjd, int *data){ 9 int n, a, b; 10 n=mjd+678881; 11 //printf("n=%d",n); 12 a=4*n +3 +4*floor( 3/4.0* floor( 4*(n+1)/146067.0 ) ); 13 b=5*floor(a%1461/4.0 )+2; 14 data[0]=floor(a/1461.0); 15 data[1]=floor(b/153.0)+3; 16 data[2]=floor(b%153/5.0)+1; 17 if(12<data[1]){ 18 data[0]+=1; 19 data[1]-=12; 20 } 21} 22int data2mjd(int y, int m, int d){ 23 if(m<3){ 24 y-=1; 25 m+=12; 26 } 27 return floor(365.25*y)+floor(y/400.0)-floor(y/100.0)+floor(30.59*(m-2))+d-678912; 28} 29int data_dif(int y1, int m1, int d1, int y2, int m2, int d2){ 30 printf("[db]%d\n",data2mjd(y1,m1,d1)); 31 printf("[db]%d\n",data2mjd(y2,m2,d2)); 32 printf("[db]%d\n",abs( data2mjd(y1,m1,d1)-data2mjd(y2,m2,d2) )); 33 34 return abs( data2mjd(y1,m1,d1)-data2mjd(y2,m2,d2) )-678973;//-678973ほどしないと、日付が変になる。基準点問題? 35} 36void main(){ 37 int data1[3]={},data2[3]={},data3[3]={}; 38 scanf("%d%d%d",&data1[0],&data1[1],&data1[2]); 39 scanf("%d%d%d",&data2[0],&data2[1],&data2[2]); 40 mjd2data( data_dif(data1[0],data1[1],data1[2],data2[0],data2[1],data2[2]) ,data3); 41 printf("%d/%d/%d\n",data3[0],data3[1],data3[2]); 42 43}

補足情報(FW/ツールのバージョンなど)

Windows10 MinGW

###参考ページ
1.知恵袋
2.Wikipedia

###追記
mjd2dataにtm構造体を使ってみようとしましたが、表示されないです。使い方を間違っているのでしょうが、自前で検索しようにもワードが思いつきません。

C

1#include <stdio.h> 2#include <string.h> 3#include <ctype.h> 4#include <stdlib.h> 5#include <time.h> 6#include <math.h> 7 8void mjd2data(int mjd, struct tm *data){ 9 int n, a, b; 10 //printf("n=%d",n); 11 a=4*n +3 +4*floor( 3/4.0* floor( 4*(n+1)/146067.0 ) ); 12 b=5*floor(a%1461/4.0 )+2; 13 data->tm_year=floor(a/1461.0); 14 data->tm_mon =floor(b/153.0)+3; 15 data->tm_mday=floor(b%153/5.0)+1; 16 if(12 < data->tm_mon ){ 17 data->tm_year+=1; 18 data->tm_mon-=12; 19 } 20} 21char printd(struct tm *data, int fg){//fg=0なら4桁、1なら2桁 22 if(fg){ 23 data->tm_year-=2000; 24 } 25 sprintf(a,"%d/%d/%d",data->tm_year,data->tm_mon,data->tm_mday); 26 return a; 27} 28 29 30void main(){ 31 int mjd; 32 struct tm *data; 33 char *a; 34 scanf("%d",&mjd); 35 mjd2data(mjd,data); 36 puts("hoge"); 37 printf("%4d/", data->tm_year); 38 printf("%2d/", data->tm_mon); 39 printf("%2d ", data->tm_mday); 40 printf("%s\n",printd(data,0)); 41}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2019/03/05 05:13

どのような入力(2つのグレゴリオ暦の日付)で、どのような結果が出たのですか?
Kazumori102

2019/03/05 05:26

2000/1/1、2000/3/5で、差日数64 日付-1/2/-28です。
coco_bauer

2019/03/05 05:30

「日付-1/2/-28」というのは、どういう意味ですか?
Kazumori102

2019/03/05 05:36

maisumakun氏曰く、差の日数はユリウス通日じゃないので変換できないはずのを無理やり変換しているので意味のない日付になっていますね。
guest

回答1

0

ベストアンサー

二つの日付の差を年月日で求めたい。

日付の差は修正ユリウス日ではありませんので、mjd2dateを使って変換することはできません(「ちょうど2ヶ月」のような表現は、日付として表すことが不可能です)。

そして、同じ日数でも年月日で表した場合の差は一定しませんので、日付同士を直接見て差を調べるしかありません。

  • 例1→1月1日の90日後は4月1日(ちょうど3ヶ月後)
  • 例2→2月28日の90日後は5月29日(3ヶ月と1日)

投稿2019/03/05 04:47

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/03/05 04:50

なお、「例」は平年として計算したものです。
Kazumori102

2019/03/05 05:10

ほー。日付等の理解の時点で間違ってたということですかね?差は変換不能はわかりました。個々のコーディング自体が間違っていなければそのまま、日付の差は変換などせずに使ってしまおう思いますが...
maisumakun

2019/03/05 05:11

差の日数だけ必要なら、ユリウス通日の差を取っても問題はありません。
Kazumori102

2019/03/05 05:24

変換して日付になるものだと思い込んでただけなので実のところ基準日から何日後かが分かれば用が足りてます。 ありがとうございました。
Kazumori102

2019/03/05 05:38

基準日y/m/dのn日後のy'/m'/d'は求められますよね?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問