두 날짜(YYYYMMDD)의 차이 일수를 구하는 프로그램을 작성하시오.
※ 단, 프로그래밍 언어에서 지원하는 날짜차이를 계산하는 라이브러리는 사용하지 말것
예)
20070515 sub 20070501 = 14
20070501 sub 20070515 = 14
20070301 sub 20070515 = 75
85개의 풀이가 있습니다.
R로 짰습니다.
왠지 날짜를 숫자로 변환해주는 함수를 쓰면 반칙인 것 같아서 직접 구해보기로 했습니다.
윤년을 구하는 것만 조금 위키를 참고했는데 매 4년은 윤년, 매 100년은 평년, 매 400년은 윤년이라는 사실을 참고했습니다.
결과는 서기 1년부터 3000년 사이일 때만 구할 수 있습니다. 몰랐는데 서기 0년은 존재하지 않더군요. 부끄럽네요.
m.month1=matrix(0, 3000, 12)
rownames(m.month1) = paste("year", 1:3000)
m.month1[,c(4,6,9,11)]=30
m.month1[,c(1,3,5,7,8,10,12)]=31
m.month1[,2]=28
m.month1[1:3000 %% 4 == 0, 2] = 29
m.month1[1:3000 %% 100 == 0, 2] = 28
m.month1[1:3000 %% 400 == 0, 2] = 29
m.days=matrix(0, 4, sum(m.month1))
rownames(m.days) = c("num", "year", "month", "day")
m.days[1,]=1:sum(m.month1)
v.year=rep(1:3000, times=rowSums(m.month1))
v.month=unlist(apply(m.month1, 1, function(x) rep(1:12, times=x)))
v.day=unlist(apply(m.month1, 1, function(x) unlist(sapply(x, function(y) 1:y))))
m.days[2,]=v.year
m.days[3,]=v.month
m.days[4,]=v.day
subdate=function(c1, c2){
y1=as.integer(substr(c1, 1, 4))
y2=as.integer(substr(c2, 1, 4))
m1=as.integer(substr(c1, 5, 6))
m2=as.integer(substr(c2, 5, 6))
d1=as.integer(substr(c1, 7, 8))
d2=as.integer(substr(c2, 7, 8))
n1=m.days[1, y1==m.days[2,] & m1==m.days[3,] & d1==m.days[4,]]
n2=m.days[1, y2==m.days[2,] & m2==m.days[3,] & d2==m.days[4,]]
abs(n1-n2)
}
결과입니다.
> subdate(20070301 , 20070515 )
num
75
> subdate(10000101 , 19991231 )
num
365241
def date_count(date):
year = int(date[0:4])
month = int(date[4:6])
day = int(date[6:8])
# 년을 일수로 치환
year_cnt=(year-1)*365 + (year-1)//4 - (year-1)//100 +(year-1)//400
# 월을 일수로 치환
month_cnt = 0
for mon in range(1,month):
if mon == 2:
if year//400 == 0:
month_cnt += 29
elif year//100 == 0:
month_cnt += 28
elif year//4 ==0:
month_cnt +=29
else:
month_cnt +=28
elif mon in [1,3,5,7,8,10,12]:
month_cnt +=31
else:
month_cnt +=30
return year_cnt+month_cnt+day
def main():
date1 = input('날짜 :')
date2 = input('날짜 :')
print(abs(date_count(date1)-date_count(date2)))
main()
펄입니다 윤년과 2월달 그리고 4,6,9,11월은 30일까지만 있다는것을 감안했습니다
my @days=(31,28,31,30,31,30,31,31,30,31,30,31);
my ($s,$y,$m,$d,$y2,$m2,$d2)=(0);
sub isyoon{unless($y%400){return 1}unless($y%100){return 0}unless($y%4){return 1}0}
sub lastday{if($m==2 and isyoon){return $days[1]+1}$days[$m-1]}
sub thisyear{unless(isyoon()){return 365}else{return 366}}
sub addday{if($d==lastday()){addmonth();$d=0}$d++;}
sub addmonth{if($m==12){$y++;$m=0}$m++;}
if($ARGV[0]>$ARGV[1]){my $t=$ARGV[0];$ARGV[0]=$ARGV[1];$ARGV[1]=$t}
$y=substr($ARGV[0],0,4,'');$y2=substr($ARGV[1],0,4,'');$m=substr($ARGV[0],0,2,'');$m2=substr($ARGV[1],0,2,'');$d=substr($ARGV[0],0,2,'');$d2=substr($ARGV[1],0,2,'');
until($d==$d2){$s+=1;addday();}until($m==$m2){$s+=lastday();addmonth()}until($y==$y2){$s+=thisyear()}
print "$s\n";
ef days_month(month):
return [0,31,28,31,30,31,30,31,31,30,31,30,31][month]
def days_year(year):
if year%400==0:return 366
if year%100==0:return 365
if year%4==0:return 366
return 365
def convert(yyyymmdd):
res = 0
ymd = str(yyyymmdd)
y = int(ymd[:-4])
m = int(ymd[-4:-2])
d = int(ymd[-2:])
for i in range(1900,y):res += days_year(i)
for i in range(1,m):res += days_month(i)
res += d
return res
def subdate(a,b):
return abs(convert(a)-convert(b))
print subdate(20070515,20070501)
print subdate(20070301,20070515)
Ruby
require 'date'
class String
def -(o)
([self, o].map{|i|Date.strptime(i, "%Y%m%d").strftime('%s').to_i}.inject(:-) / 86400).abs
end
end
Test
require 'test/unit'
extend Test::Unit::Assertions
assert_equal ("20070501" - "20070515"), 14
assert_equal ("20070515" - "20070501"), 14
assert_equal ("20070301" - "20070515"), 75
좀 더 간단하게 짜보고 싶은데.. 어렵네요. 서기 1000년 부터 9999년까지 계산 가능 합니다.
package my;
import java.util.HashMap;
import java.util.Map;
public class T {
public static void main(String[] args) {
day(20070515,20070501);
}
public static int day(int a, int b){
int A;
int B;
Map map = new HashMap();
map.put("1", 31);
map.put("2", 28);
map.put("3", 31);
map.put("4", 30);
map.put("5", 31);
map.put("6", 30);
map.put("7", 31);
map.put("8", 30);
map.put("9", 31);
map.put("10", 31);
map.put("11", 30);
map.put("12", 31);
if(a>b){
A=a;
B=b;
}else{
A=b;
B=a;
}
int yA=A/10000;
int yB=B/10000;
int mA=A%10000/100;
int mB=B%10000/100;
int dA=A%100;
int dB=B%100;
/*A*/
//연도 차이 계산
int totA = 0;
for(int i=yB;i<yA;i++){
for(int j=1;j<=12;j++){
totA+=(int)map.get(String.valueOf(j));
}
//윤년 일 추가
if(i%400==0||i%4==0&&i%100!=0){
totA+=1;
System.out.println(i+"윤년 + 1일");
}
}
//해당 년 월 계산
for(int i=1;i<mA;i++){
totA+=(int)map.get(String.valueOf(i));
}
//윤년 추가 계산
if((yA%400==0||yA%4==0&&yA%100!=0)&&(mA>=3||mA==2&&dA==29)){
totA+=1;System.out.println("윤년 + 1일");
}
//해당 년 일 계산
totA+=dA;
/*B*/
//해당 년 월계산
int totB = 0;
for(int i=1;i<mB;i++){
totB+=(int)map.get(String.valueOf(i));
}
//윤년 추가 계산
if((yB%400==0||yB%4==0&&yB%100!=0)&&(mB>=3||mB==2&&dB==29)){
totB+=1;System.out.println("윤년 + 1일");
}
//해당 년 일 계산
totB+=dB;
System.out.println(totA - totB+"일 차이");
System.out.println(yA+"년"+mA+"월"+dA+"일");
System.out.println(yB+"년"+mB+"월"+dB+"일");
return totA - totB;
}
}
루비 입니다. 윤년까지만 고려했어요. 1900년부터 계산했고, 없는 날짜도 그냥 받아버립니다.
class CustomDate
attr_reader :year, :month, :day
MONTH_DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def initialize(str)
raise ArgumentError unless str.size == 8
@year = str[0, 4].to_i
@month = str[4, 2].to_i
@day = str[6, 2].to_i
end
def to_i
year_to_i + month_to_i + day
end
def -(other)
to_i - other.to_i
end
private
def month_to_i
leap = leap_year?(year) && month > 2 ? 1 : 0
MONTH_DAYS[0, month].reduce(:+) + leap
end
def year_to_i
(1900...year).map { |y| leap_year?(y) ? 366 : 365 }.reduce(:+)
end
def leap_year?(year)
if year.modulo(4).zero?
return true unless year.modulo(100).zero? && !year.modulo(400).zero?
end
false
end
end
def sub(a, b)
(CustomDate.new(a) - CustomDate.new(b)).abs
end
p sub("20070515", "20070501")
p sub("20070501", "20070515")
p sub("20070301", "20070515")
자바입니다.
날짜 계산 알고리즘을 조금 다르게 해봤습니다.
먼저 각 피연산자를 각해의 1월 1일 + #월 #일로 조정한 후,
연도부와 월일부를 따로 계산해서 합쳐줍니다.
ex) 20150501 sub 20140601
-> 20150501 - 20140601
-> 20150101 + 0501 - 20140101 - 0601
-> 20150101 - 20140101 + 0501 - 0601
-> 365 (2014년 한 해) - (0601 - 0501)
-> 365 - 31 (5월 한 달)
-> 334
만약 거꾸로 들어왔으면 재귀로 인자를 반대로 줍니다.
public class CD394 {
public static void main(String[] args){
System.out.println(subdate(20150501,20140601));
}
private static int subdate(int a, int b){
if(a < b) return subdate(b,a);
if(a == b) return 0;
int bigmonth = 31, smallmonth = 30, small2 = 28, big2 = 29;
int bigyear = 366, smallyear = 365;
int result = 0;
int aday = a%100, amonth = (a%10000-aday)/100, ayear =a/10000;
int bday = b%100, bmonth = (b%10000-bday)/100, byear =b/10000;
for(int month = 1; month < amonth; month++){
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
result+=bigmonth;
break;
case 4:
case 6:
case 9:
case 11:
result+= smallmonth;
break;
case 2:
if(ayear%4 == 0 &&(ayear % 100 != 0 || ayear % 400 == 0)){
result+= big2;
} else {
result+= small2;
}
default:
break;
}
}
for(int month = 1; month < bmonth; month++){
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
result-=bigmonth;
break;
case 4:
case 6:
case 9:
case 11:
result-=smallmonth;
break;
case 2:
if(byear%4 == 0 &&(byear % 100 != 0 || byear % 400 == 0)){
result-= big2;
} else {
result-= small2;
}
default:
break;
}
}
result = result + aday - bday;
for(int year = byear; year < ayear; year++){
if(year%4 == 0 &&(year % 100 != 0 || year % 400 == 0)){
result += bigyear;
} else {
result += smallyear;
}
}
return result;
}
}
C#으로 작성했습니다. 각 input에 0001년 01월 01일 기준으로 몇 일이 흘렀는지 계산 후 빼기 후 absolute로 출력했습니다.
public int CountIntervalDays(string a, string b)
{
var firstYear = int.Parse(a.Substring(0, 4));
var firstMonth = int.Parse(a.Substring(4, 2));
var firstDay = int.Parse(a.Substring(6, 2));
var secondYear = int.Parse(b.Substring(0, 4));
var secondMonth = int.Parse(b.Substring(4, 2));
var secondDay = int.Parse(b.Substring(6, 2));
var first = CountYear(firstYear) + CountMonth(firstMonth, firstYear) + firstDay;
var second = CountYear(secondYear) + CountMonth(secondMonth, secondYear) + secondDay;
return Math.Abs(first - second);
}
public int CountYear(int year)
{
return year*365 + year/4;
}
public int CountMonth(int month, int year)
{
var sum = 0;
for (int i = 1; i < month; i++)
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
sum += 31;
else if (i == 4 || i == 6 || i == 9 || i == 11) sum += 30;
else if (year%4 == 0) sum += 29;
else sum += 28;
return sum;
}
```{.vbnet} Sub Main() Console.WriteLine(Math.Abs(DateToDay("20070501") - DateToDay("20070515")))
Console.ReadLine()
End Sub
Public Function DateToDay(dStr As String) As Integer Dim mLDays() As Integer = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
Dim y As Integer = dStr.Substring(0, 4)
Dim m As Integer = dStr.Substring(4, 2)
Dim d As Integer = dStr.Substring(6, 2)
Dim td As Integer = y * mLDays.Sum + d
For i As Integer = 1 To m - 1
td += mLDays(i - 1)
Next
Return td
End Function ```
public class Subdate {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(true) {
String date1 = sc.nextLine();
String date2 = sc.nextLine();
if("".equals(date1) || "".equals(date2)) {
break;
}
if(Integer.parseInt(date1) < Integer.parseInt(date2)) {
String temp = date1;
date1 = date2;
date2 = temp;
}
int y1 = Integer.parseInt(date1.substring(0, 4));
int y2 = Integer.parseInt(date2.substring(0, 4));
int days = 0;
for(int i = y2 + 1; i < y1; i++) {
days += 365;
if(i % 4 == 0) days++;
if(i % 100 == 0) days--;
if(i % 400 == 0) days++;
}
boolean yun1 = false;
boolean yun2 = false;
if(y1 % 4 == 0) yun1 = true;
if(y1 % 100 == 0) yun1 = false;
if(y1 % 400 == 0) yun1 = true;
if(y2 % 4 == 0) yun2 = true;
if(y2 % 100 == 0) yun2 = false;
if(y2 % 400 == 0) yun2 = true;
int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int m1 = Integer.parseInt(date1.substring(4, 6));
int m2 = Integer.parseInt(date2.substring(4, 6));
if(y1 == y2) {
for(int i = m2 + 1; i < m1; i++) {
days += months[i - 1];
if(yun1 && i == 2) {
days++;
}
}
} else {
for(int i = m2 + 1; i <= 12; i++) {
days += months[i - 1];
if(yun2 && i == 2) {
days++;
}
}
for(int i = 1; i < m1; i++) {
days += months[i - 1];
if(yun1 && i == 2) {
days++;
}
}
}
int d1 = Integer.parseInt(date1.substring(6, 8));
int d2 = Integer.parseInt(date2.substring(6, 8));
if(y1 == y2 && m1 == m2) {
days += d1 - d2;
} else {
days += d1;
days += (months[m2 - 1] - d2);
if(yun1 && m1 == 2)
days++;
if(yun2 && m2 == 2)
days++;
}
System.out.println(date1 + " sub " + date2 + " = " + days);
}
sc.close();
}
}
int getDays(char flag, int value)
{
int result = 0;
int mDay[13] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
switch (flag)
{
case 'y':
result += (value-1) * 365;
result += (value-1) / 4;
result -= (value-1) / 100;
result += (value-1) / 400;
break;
case 'm':
for(int i = 0; i < value - 1; i++)
result += mDay[i];
break;
case 'd':
result += value;
break;
}
return result;
}
void exce8()
{
int a, b;
int ayy, amm, add, byy, bmm, bdd;
printf("비교할 두 날짜를 YYYYMMDD형식으로 입력 해 주십시오.\n");
scanf_s("%d", &a);
scanf_s("%d", &b);
ayy = a / 10000;
amm = (a / 100) % 100;
add = a % 100;
byy = b / 10000;
bmm = (b / 100) % 100;
bdd = b % 100;
a = getDays('y', ayy);
a += getDays('m', amm);
a += getDays('d', add);
if (ayy % 4 == 0)
{
if (ayy % 100 == 0)
{
if (ayy % 400 == 0)
a++;
}
else
a++;
}
b = getDays('y', byy);
b += getDays('m', bmm);
b += getDays('d', bdd);
if (byy % 4 == 0)
{
if (byy % 100 == 0)
{
if (byy % 400 == 0)
b++;
}
else
b++;
}
printf("%d%d%d 와 %d%d%d는 %d일 차이 납니다.\n", ayy, amm, add, byy, bmm, bdd, abs(a - b));
}
윤년계산은 했는데 각 달이 몇일인가에 대해서는 일반식이 떠오르지 않아서..그냥 배열로 떄려 박았습니다.
율리우스 날짜 셈법(JDN)을 이용해서 python으로 구현했습니다. JDN 계산법을 이용한걸 명확히 보이기 위해 수식을 더 줄이지는 않았습니다. JDN 계산법은 과거 어느 시점 이후로 오늘이 며칠째인지를 알려줍니다. (자세한건 위키 참조(Julian day))
def getJDN(date):
year, month, day = int(date[0:4]), int(date[4:6]), int(date[6:8])
a = int((14 - month) / 12)
y = year + 4800 - a
m = month + 12 * a - 3
JDN = day + int ((153 *m + 2) / 5) + 365 * y + int(y / 4) + int(y / 100) + int(y / 400) - 32045
return JDN
def subdate(a, b):
return str(abs(getJDN(a) - getJDN(b)))
for (a, b) in ([("20070515", "20070501"), ("20070501", "20070515"), ("20070301", "20070515")]):
print (a + " sub " + b + " = " + subdate(a, b))
C입니다. 실행 후 연월일을 두개 입력해주면 작동합니다.
#include <stdio.h>
int isleapyear(int year)
{
if (year % 400 == 0) return 1;
if (year % 100 == 0) return 0;
if (year % 4 == 0) return 1;
return 0;
}
int datetodays(int date)
{
int i, result, year, month, day;
result = 0;
day = date % 100;
month = ((date/100)%100)-1;
year = (date / 10000)-1;
result += year/4;
result -= year/100;
result += year/400;
result += year * 365;
if (month==0) ;
else if (month == 1) result += 31;
else if (month < 8)
{
if (isleapyear(year+1)) result++;
result += 61*(month/2)+31*(month&1)-2;
}
else
{
if (isleapyear(year+1)) result++;
month -= 7;
result += 212+61*(month/2)+31*(month&1);
}
result += day;
return result;
}
int subdate(int date1, int date2)
{
int temp;
if (date1==date2)
{
return 0;
}
if (date1>date2)
{
temp = date1;
date1 = date2;
date2 = temp;
}
if (date1/100 == date2/100)
{
return (date2%100 - date1%100);
}
else
{
return datetodays(date2) - datetodays(date1);
}
}
int main()
{
int date1, date2;
int temp;
scanf("%d %d", &date1, &date2);
printf("%d sub %d = %d\n", date1, date2, subdate(date1, date2));
return 0;
}
//0 ~3000year
//
//윤년 : 4년마다 돌아오는 해는 하루가 더 많음(366days)
//평년 : (365days)
//
// 28(29)일
// 2
// 30일
// 4.6.9.11
// 31일
// 1.3.5.7.8.10.12
//
// YEAR(2010 - 1) * 365
// 1 윤년이냐
// 2윤년인데 MONTH가 02월 이상이냐
// MONTH 01 * 31
// + DAY 20
// --------------------------------------
#include <iostream>
using namespace std;
typedef struct _data
{
int nYear;
int nMonth;
int nDay;
int nSum;
}DATA;
void EndProgram(bool *bButton); //더 이상의 계산을 하고 싶지 않다면
void InputData(int *Start, int *End); //날짜 입력 받음
int DataManage(char* Days); //날짜 일수를 카운트함
int DataManage(int nYear, int nMonth, int nDay);
int Result(int Start, int End); //날자 계산 결과를 리턴함
void main()
{
//////////
DATA *_dpStartDay = NULL;
//////////
int nStartSum = 0;
int nEndSum = 0;
bool bButton = true; //프로그램 종료용 변수
int nStartData = 0; //계산 시작 날짜
int nEndData = 0; //계산 종료 날짜
char cStartData[9] = "0,"; //시작 날짜 문자열
char cEndData[9] = "0,"; //종료 날짜 문자열
//입력 뺑뺑이
while (bButton)
{
//날짜 입력 받음
//InputData(&nStartData, &nEndData);
//int형으로 입력받은 것을 char배열로 변경
//_itoa_s(nStartData, cStartData, 10);
//_itoa_s(nEndData, cEndData, 10);
int a = DataManage( 2016, 01, 20 );
int b = DataManage( 2016, 02, 01 );
cout << " a = " << a << endl;
cout << " b = " << b << endl;
cout << "a - b = " << -1 * (a - b) << endl;
//더 이상의 계산을 하고 싶지 않다면
EndProgram(&bButton);
}
}
int DataManage(int nYear, int nMonth, int nDay )
{
int nLoopYear = 0;
int nTempYear = nYear;
int nTempMonth = nMonth;
int nTempDay = nDay;
bool bLoopYear = false;
//매개변수로 받은 문자열에서
//year
//Month
//day
//를 분류한다.
DATA _dDays;
//오늘까지 윤년(Loop year)이 몇번 있는지 파악
//작년까지 뺑뺑이를 돌면서
for (int i = 0; i < nTempYear; i++)
{
//윤년이라면 nLoopYear를 하나 증가 시킴
if (i % 4 == 0)
{
nLoopYear++; //요놈은 윤년이니까, 실제 일수 = nLoopYear * 366
}
}
//올해가 윤년이면 true
//올해가 평년이면 false
if (nTempYear % 4 == 0)
{
bLoopYear = true;
}
int a = nTempYear - 1;
int b = a - nLoopYear;
int sumLoopYear1 = b * 365; //윤년
int sumLoopYear2 = nLoopYear * 366; //평년
nTempYear = sumLoopYear1 + sumLoopYear2;
nTempMonth -= 1;
switch (nTempMonth)
{
case 0:
{
break;
}
case 2:
{
//윤년인가요?
if (bLoopYear)
{
//그럼 일(日)수는 29일 이겠군요.
cout << "그럼 일(日)수는 29일 이겠군요." << endl;
nTempMonth = nTempMonth * 29;
}
else
{
//아니라구요?
//그럼 일(日)수는 28일 이겠군요
cout << "그럼 일(日)수는 28일 이겠군요" << endl;
nTempMonth = nTempMonth * 28;
}
break;
}
//이 월(月)에 해당되사나요?
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
{
cout << "31" << endl;
nTempMonth = nTempMonth * 31;
break;
}
//이 월(月)에 해당되사나요?
case 4:
case 6:
case 9:
case 11:
{
cout << "30" << endl;
nTempMonth = nTempMonth * 30;
break;
}
break;
}
_dDays.nSum = nTempYear + nTempMonth + nTempDay;
//cout << _dDays.nSum << endl;
return _dDays.nSum;
}
int DataManage(char* Days)
{
int nLoopYear = 0;
int nTempYear = 4;
int nTempMonth = 1;
int nTempDay = 28;
bool bLoopYear = false;
//매개변수로 받은 문자열에서
//year
//Month
//day
//를 분류한다.
DATA _dDays;
//오늘까지 윤년(Loop year)이 몇번 있는지 파악
//작년까지 뺑뺑이를 돌면서
for (int i = 0; i < nTempYear; i++)
{
//윤년이라면 nLoopYear를 하나 증가 시킴
if (i % 4 == 0)
{
nLoopYear++; //요놈은 윤년이니까, 실제 일수 = nLoopYear * 366
}
}
//올해가 윤년이면 true
//올해가 평년이면 false
if (nTempYear % 4 == 0)
{
bLoopYear = true;
}
int a = nTempYear - 1;
int b = a - nLoopYear;
int sumLoopYear1 = b * 365; //윤년
int sumLoopYear2 = nLoopYear * 366; //평년
nTempYear = sumLoopYear1 + sumLoopYear2;
nTempMonth -= 1;
switch (nTempMonth)
{
case 0:
{
break;
}
case 2:
{
//윤년인가요?
if (bLoopYear)
{
//그럼 일(日)수는 29일 이겠군요.
cout << "그럼 일(日)수는 29일 이겠군요." << endl;
nTempMonth = nTempMonth * 29;
}
else
{
//아니라구요?
//그럼 일(日)수는 28일 이겠군요
cout << "그럼 일(日)수는 28일 이겠군요" << endl;
nTempMonth = nTempMonth * 28;
}
break;
}
//이 월(月)에 해당되사나요?
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
{
cout << "31" << endl;
nTempMonth = nTempMonth * 31;
break;
}
//이 월(月)에 해당되사나요?
case 4:
case 6:
case 9:
case 11:
{
cout << "30" << endl;
nTempMonth = nTempMonth * 30;
break;
}
break;
}
_dDays.nSum = nTempYear + nTempMonth + nTempDay;
cout << _dDays.nSum << endl;
return _dDays.nSum;
}
void InputData(int *Start, int *End)
{
//시작날짜를 입력 받음
cout << "시작 날짜를 입력해주세요( ex, 20160120 ) : ";
cin >> *Start;
//끝날짜를 입력받음
cout << "끝 날짜를 입력해주세요 ( ex, 20160122 ) : ";
cin >> *End;
}
int Result(int Start, int End)
{
return Start - End;
}
void EndProgram(bool *bButton)
{
char cTemp = 'N';
cout << "종료 하시겠습니까? ( Y / N )" << endl;
cin >> cTemp;
if (cTemp == 'Y' || cTemp == 'y')
{
*bButton = false;
}
else if (cTemp == 'N' || cTemp == 'n')
{
*bButton = true;
}
}
조잡하지만... 기능은 이상없이 작동합니다..
일단 방식은 시작일부터 종료일까지 하루씩 세는 방식입니다. 계산할 일자의 범위와 사용하는 달력이 정해지지 않은 부분이 좀 애매하네요. 일단 그레고리력으로 계산했고, 그레고리력에서 윤년은
으로 계산합니다.
그런데, 그레고리력으로 계산하는 경우 1582년 10월 5일 ~ 1582년 10월 14일의 10일은 그레고리력상 없는 날짜이기 때문에 이 부분에 대한 보정을 넣어봤습니다.
파이썬입니다.
days1 = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
days2 = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
def leap(y):
if y % 400 == 0:
return True
if y % 100 == 0:
return False
if y % 4 == 0:
return True
return False
def nextday(data):
y, m, d = (int(x) for x in (data[:4], data[4:6], data[6:]))
if y == 1582 and m == 10 and d == 4:
d += 11
else:
d += 1
md = days2 if leap(y) else days1
if d == md[m - 1] + 1:
d = 1
m += 1
if m == 13:
m = 1
y += 1
return ''.join(("{:02d}".format(x) for x in (y, m, d)))
def do(xs):
s, e = sorted(xs.split()[:2])
d = 0
while e != s:
s = nextday(s)
d += 1
return "{} sub {} => {}".format(e, s, d)
samples =\
"""20070501 20070515
20070301 20070515""".split('\n')
for v in samples:
print(do(v))
```
파이썬 3.4.2
def makeitday(s):
year = int(s[:4])-1
month = int(s[4:6])-1
day = int(s[6:])-1
totald = year*365+day
for i in range(1,year+2):
if i%4 == 0 and i%100 != 0 and i%400 == 0:
totald += 1
mondir = {1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
for i in range(1,month+2):
totald += mondir[i]
return totald
a,b = map(str,input().split())
print(abs(makeitday(a)-makeitday(b)))
출력:
[입력] : 20070515 20070501
[출력] : 14
def daycount(a,b,c):
month=[31,28,31,30,31,30,31,31,30,31,30,31]
if a%4==0:
month[1]=29
yearday=(a-1)*365+(a//4)-(a//100)+(a//400)
monthday=sum(month[0:b-1])
return monthday+yearday+c
while 1:
a,b=input("계산할 날짜를 두개 입력하세요(YYYYMMDD YYYYMMDD)=").split()
ayear=int(a[:4])
amon=int(a[4:6])
aday=int(a[6:])
byear=int(b[:4])
bmon=int(b[4:6])
bday=int(b[6:])
print("두 날짜의 차는 %s 일입니다" % abs((daycount(ayear,amon,aday)-daycount(byear,bmon,bday))))
package main
import (
"fmt"
"strconv"
)
func CheckYunYear(year int) bool {
return ((year%4 == 0) && (year%100 != 0)) || (year%400 == 0)
}
func Days(date string) int {
year, _ := strconv.Atoi(date[:4])
month, _ := strconv.Atoi(date[4:6])
day, _ := strconv.Atoi(date[6:])
for i := 1; i < year; i++ {
if CheckYunYear(i) {
day += 366
} else {
day += 365
}
}
day_per_month := []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if CheckYunYear(year) {
day_per_month[1]++
}
for i := 0; i < month-1; i++ {
day += day_per_month[i]
}
return day
}
func main() {
var date1, date2 string
fmt.Print("Input Date(YYYYMMDD): ")
fmt.Scan(&date1)
fmt.Print("Input Date(YYYYMMDD): ")
fmt.Scan(&date2)
diff := Days(date1) - Days(date2)
fmt.Println(diff)
}
Ruby
그레고리력으로 계산.
class RDate
attr_reader :year, :month, :day
attr_reader :year_to_days, :month_to_days
def initialize(date)
ymd = ->str{ [[0,4],[4,2],[6,2]].map {|s,e| str[s,e].to_i } }
@year, @month, @day = ymd[date]
raise "서기 0년은 존재하지 않습니다" if @year == 0
@month_to_days = cnt_days_with_month
@year_to_days = cnt_days_with_year
end
def leaf_year?
@year%4==0 && @year%100!=0 || @year%400==0
end
def count_days
@year_to_days + @month_to_days + @day
end
def self.subdate(from, to)
( RDate.new(to).count_days - RDate.new(from).count_days ).abs
end
private
def cnt_days_with_month
day_per_month = [0,31,28 + (leaf_year?? 1:0),31,30,31,30,31,31,30,31,30,31]
days = day_per_month[0,@month].reduce(:+)
end
def cnt_days_with_year
year = @year - 1
days = year == 0 ? 0 : 365*year
leaf_days = year/4 - year/100 + year/400
days + leaf_days
end
end
Test
expect{ RDate.subdate("00000101", "20160706" ) }.
to raise_error.with_message "서기 0년은 존재하지 않습니다"
expect( RDate.subdate("20160301", "20160201") ).to eq 29 # params reverse-case
expect( RDate.subdate("20070515", "20070501") ).to eq 14
expect( RDate.subdate("20070501", "20070515") ).to eq 14
expect( RDate.subdate("20070301", "20070515") ).to eq 75
기준일을 day(0년, 1월1일) =1로 하였습니다
예를 들어 2016년 8월 12일이면 day(2015년12월31일) + day(11월 30일) + 12 로 계산하였습니다
for문과 if문을 이용해서 윤년과 2월, 31일 등을 고려하였습니다.
def is_yoon(year):
if year%4==0 and year%100!=0:
return True
else:
if year%400==0:
return True
else:
return False
#기준일 : 0년 // 1월1일
def day(date): #yyyymmdd
d=0
#2015년이면 기준~2014년12월31일
year=int(date[:4])
for i in range(1, year):
if bool(is_yoon(i))==True:
d+=366
else:
d+=365
#7월이면 1월1일~6월30일
month=int(date[4:6])
br31=[1, 3, 5, 7, 8, 10, 12]
for i in range(1, month):
if i in br31:
d+=31
elif i==2:
if bool(is_yoon(year))==True:
d+=29
else:
d+=28
else:
d+=30
#일수
d+=int(date[6:])
return d
#날짜
a=input('날짜1: ')
b=input('날짜2: ')
sub=abs(day(a)-day(b))
print('%s sub %s = %s' %(a, b, sub))
#include <stdio.h>
struct Date{
int year;
int month;
int day;
};
int subdate(Date temp1, Date temp2 );
int getdate(int value);
int before(Date value);
int after(Date value);
void main(void) {
int input1 = 0;
int input2 = 0;
char temp[3];
scanf("%d",&input1);
scanf("%d",&input2);
Date date;
date.year= input1/10000;
date.month = (input1%10000)/100;
date.day = input1%100;
Date date2;
date2.year= input2/10000;
date2.month = (input2%10000)/100;
date2.day = input2%100;
int out = 0;
if(date2.year > date.year) {
out = subdate(date2, date);
}
else if (date2.year == date.year) {
if(date2.month > date.month) {
out = subdate(date2, date);
}
else if(date2.month == date.month) {
if(date2.day > date.day) {
out = subdate(date2, date);
}
else if(date2.day == date.day) {
out = subdate(date, date2);
}
else {
out = subdate(date, date2);
}
}
else {
out = subdate(date, date2);
}
}
else {
out = subdate(date, date2);
}
printf("%d - %d = %d\t",input1, input2, out);
}
int subdate(Date temp2, Date temp1) {
int year = 0;
int month = 0;
int day = 0;
if(temp1.year == temp2.year) {
if(temp1.month == temp2.month) {
day = temp2.day - temp1.day;
}
else {
for(int i = temp1.month; i <= temp2.month; i++) {
if(i == temp2.month) {
day = day+ temp2.day;
} else if(i == temp1.month) {
day = day + getdate(temp1.month) - temp1.day;
} else {
day = day + getdate(i);
}
}
}
}
else {
for(int i = temp1.year; i <= temp2.year; i++) {
if(i == temp1.year) {
day = day + after(temp1);
} else if(i == temp2.year) {
day = day + before(temp2);
} else {
day = (temp2.year-temp1.year)*365;
}
}
day = day -1;
}
return day;
}
int getdate(int value) {
if(value == 1 || value == 3 || value == 5 || value ==7 || value == 8 || value == 10 || value == 12) {
return 31;
}
else if( value == 2) {
return 29;
}
else {
return 30;
}
}
int before(Date value) {
int result = 0;
for(int i = 1; i < value.month; i++) {
result = getdate(i) + result;
}
return result + value.day;
}
int after(Date value) {
int result = 0;
for(int i = value.month; i <= 12; i++) {
result = getdate(i) + result;
}
return result - value.day;
}
def chk_leap_month(year):
if year % 100 == 0:
if year % 400 == 0:
return 29
pass
elif year % 4 == 0:
return 29
return 28
# ↑윤년 체크하는 함수
date_1,date_2 = input().split(' ')
if int(date_1[:4]) <= int(date_2[:4]):
y1,m1,d1 = int(date_1[:4]),int(date_1[4:6]),int(date_1[6:])
y2,m2,d2 = int(date_2[:4]),int(date_2[4:6]),int(date_2[6:])
else:
y1,m1,d1 = int(date_2[:4]),int(date_2[4:6]),int(date_2[6:])
y2,m2,d2 = int(date_1[:4]),int(date_1[4:6]),int(date_1[6:])
# ↑앞쪽에 입력받은 날짜의 년도가 더 클경우 뒤집어서 대입.
start,end,total_month = 0,0,0
if m1 <= m2:
start = m1
end = m2
else:
start = m2
end = m1
# ↑월의 크기에 따라서 #2에 사용하는 start월과 end월을 변경을 해주는 코드
# 년도가 같을때 m1의 월이 더크면 문제가 발생함.
month = {i:{1:31,2:chk_leap_month(i),3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31} for i in range(y1,y2+1)}
for i in range(start,end): #2
total_month += month[y1][i]
total_day = abs(d1-d2)
total_year = abs(y1-y2)*365 + sum([1 for i in range(y1,y2+1) if month[i][2] == 29])
if m1 > m2:
print(abs(total_year-total_month+total_day))
elif m1 <= m2:
print(abs(total_year+total_month+total_day))
#### 2016.12.08 D-441 ####
var a = '26001130'
var b = '20160430'
var days = [31,59,90,120,151,181,212,243,273,304,334,365]
if(a > b)
var answer = sub_date(a,b)
else
var answer = sub_date(b,a)
function sub_date(a, b){
var total = 0
var a_split = [Number(a.substring(0,4)), Number(a.substring(4,6)), Number(a.substring(6,8))]
var b_split = [Number(b.substring(0,4)), Number(b.substring(4,6)), Number(b.substring(6,8))]
total += (a_split[0]-b_split[0]) * 365 //년 계산
total += days[a_split[1]-1] - days[b_split[1]-1]//월 계산
total += a_split[2] - b_split[2] //일 계산
total += leapyear(a_split, b_split) //윤년에 낀 날짜 계산
return total;
}
function leapyear(a_date, b_date){
var leap = 0
/*윤년을 계산하기 전 윤년이 두 날짜사이에 끼어있는지 계산한다.*/
if((a_date[0] <= 2) && parseInt(a_date[0] / 4) == 0)
if(parseInt(a_date[0] / 100) != 0 || parseInt(a_date[0] / 400) == 0)
leap--
if((b_date[0] > 2) && parseInt(b_date[0] / 4) == 0)
if(parseInt(b_date[0] / 100) != 0 || parseInt(b_date[0] / 400) == 0)
leap--
/*반복문으로 두 날짜 사이의 년도에 윤년이 얼마나 껴있는지 계산한다.*/
for(var temp = a_date[0]; temp >= b_date[0]; temp--){
if(parseInt(temp%4) == 0)
leap++
if(parseInt(temp%100) == 0)
leap--
if(parseInt(temp%400) == 0)
leap++
}
return leap
}
console.log(a + " sub "+ b +" = "+answer)
#ifndef _SUBDATE_H
#define _SUBDATE_H
#include <stdio.h>
/* Information of how many days that each month contain
* align index same as month; it means DAYS[0] is a garbage data
* (there is no 0-month)*/
static int DAYS[] = {__INT_MAX__, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int YEAR_DAYS[] = {365, 366};
typedef struct
{
int year;
int month;
int day;
} date;
void printDate(date day)
{
/* Print Date Information */
printf("Year : %d, Month : %d, Day : %d\n", day.year, day.month, day.day);
}
int getMax(int i1, int i2)
{
if(i1 > i2) return i1;
else return i2;
}
int getMin(int i1, int i2)
{
if(i1 < i2) return i1;
else return i2;
}
int formatCheck(date day);
int isLeap(int year);
int getDiff(date day1, date day2);
#endif
// Header file ends
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "subdate.h"
int main(void)
{
int temp;
date day1, day2;
printf("Subdate Program. Input date format must be YYYYMMDD.\n");
printf("Example: 20170310\n");
printf("Input First Day : ");
scanf("%d", &temp);
day1.day = temp % 100;
temp /= 100;
day1.month = temp % 100;
temp /= 100;
day1.year = temp;
while(!formatCheck(day1))
{
printf("Error : Non-Existing Date.\n");
printf("Input Again : ");
scanf("%d", &temp);
day1.day = temp % 100;
temp /= 100;
day1.month = temp % 100;
temp /= 100;
day1.year = temp;
}
printf("First Day is = ");
printDate(day1);
printf("Input Second Day : ");
scanf("%d", &temp);
day2.day = temp % 100;
temp = (temp - day2.day) / 100;
day2.month = temp % 100;
temp = (temp - day2.month) / 100;
day2.year = temp;
while(!formatCheck(day2))
{
printf("Error : Non-Existing Date.\n");
printf("Input Again : ");
scanf("%d", &temp);
day2.day = temp % 100;
temp /= 100;
day2.month = temp % 100;
temp /= 100;
day2.year = temp;
}
printf("Second Day is = ");
printDate(day2);
printf("Difference = %d days!\n", getDiff(day1, day2));
return 0;
}
int isLeap(int year)
{
/* Check Whether target year is leap year or not
* Criteria
* - whether it can be divided by 4 -> leap year
* - whether it can be divided by 100 -> normal year
* - whether it can be divided by 400 -> leap year */
if(year % 4 == 0)
{
if(year % 100 == 0)
{
if(year % 400 == 0)
return 1;
else
return 0;
}
return 1;
}
else
return 0;
}
int getDiff(date day1, date day2)
{
/* First Condition; if year is same
* just calculate difference between month-day */
int result = 0;
if(day1.year == day2.year)
{
/* If year is same, check wheter month is same
* if month is same, just calculate difference between day */
if(day1.month == day2.month)
return abs(day1.day - day2.day);
else
{
if(day1.month > day2.month)
{
for(int i = day2.month + 1; i <= day1.month - 1; i++)
{
if(i == 2)
{
if(isLeap(day1.year))
result += 29;
else
result += 28;
}
else
{
result += DAYS[i];
}
}
if(day2.month == 2)
{
if(isLeap(day2.year))
result += 29 - day2.day;
else
result += 28 - day2.day;
}
else result += (DAYS[day2.month] - day2.day);
result += day1.day;
}
else
{
for(int i = day1.month + 1; i <= day2.month - 1; i++)
{
if(i == 2)
{
if(isLeap(day1.year))
result += 29;
else
result += 28;
}
else
{
result += DAYS[i];
}
}
if(day1.month == 2)
{
if(isLeap(day1.year))
result += 29 - day1.day;
else
result += 28 - day1.day;
}
else result += (DAYS[day1.month] - day1.day);
result += day2.day;
}
}
}
else
{
/* Must include January First. Thus, set date arbitrary to be
* Januaray 0-th */
date temp1 = {getMax(day1.year, day2.year), 1, 0};
date temp2 = {getMin(day1.year, day2.year), 12, 31};
if(day1.year > day2.year)
{
for(int i = day2.year + 1; i <= day1.year - 1; i++)
{
result += YEAR_DAYS[isLeap(i)];
}
result += getDiff(temp1, day1);
result += getDiff(temp2, day2);
}
else
{
for(int i = day1.year + 1; i <= day2.year - 1; i++)
{
result += YEAR_DAYS[isLeap(i)];
}
result += getDiff(temp1, day2);
result += getDiff(temp2, day1);
}
}
return result;
}
int formatCheck(date day)
{
/* Check Whether input date is real-existing date */
if(day.year < 0) return 0;
else
{
/* First, year's validity checking */
if(day.month > 12 || day.month < 1) return 0;
else
{
if(day.month == 2)
{
if(day.day == 29)
{
if(isLeap(day.year)) return 1;
else return 0;
}
else if(day.day > 29 || day.day < 1) return 0;
else return 1;
}
else
{
if(day.day < 1 || day.day > DAYS[day.month]) return 0;
else return 1;
}
}
}
}
int main(void) { int day;
printf(" 첫번 째 날짜를 입력하시오 : \n");
scanf_s("%d", &day);
int month = 0;
int date = 0;
int year = 0;
int leftDay = 0;
date = day % 100;
leftDay = day / 100;
month = leftDay % 100;
leftDay = leftDay / 100;
year = leftDay;
int day2;
printf(" 두번 째 날짜를 입력하시오 : \n");
scanf_s("%d", &day2);
int month2 = 0;
int date2 = 0;
int year2 = 0;
int leftDay2 = 0;
date2 = day2 % 100;
leftDay2 = day2 / 100;
month2 = leftDay2 % 100;
leftDay2 = leftDay2 / 100;
year2 = leftDay2;
printf("첫번 째 :: year : %d / month : %d / date : %d \n", year, month, date);
printf("두번 째 :: year : %d / month : %d / date : %d \n", year2, month2, date2);
///////////////////////////////////////////////
long long firstleft = 0;
long long secoundleft = 0;
long long leftdate = 0;
if (month % 2 == 0)//짝수
{
firstleft = (year * 365) + (month * 30) + date;
}
else //홀수
{
firstleft = (year * 365) + (month * 31) + date;
}
if (month2 % 2 == 0) //짝수
{
secoundleft = (year2 * 365) + (month2 * 30) + date2;
}
else //홀수
{
secoundleft = (year2 * 365) + (month2 * 31) + date2;
}
if (firstleft > secoundleft)
{
leftdate = firstleft - secoundleft;
}
else
{
leftdate = secoundleft - firstleft;
}
printf("일수 차이 : %d \n", leftdate);
return 0;
}
DAYS_LIST = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
def is_leap_year(year):
return (year%4==0 and (year%100!=0 or year%400==0))
def get_sum_of_leap_year(start, target:'[start, target)'):
count = 0
for i in range(start, target):
if is_leap_year(i):
count += 1
return count
def get_abs_day_year(end:'[1538, end)'):
exclusive_years = end - 1538
leap_years_count = get_sum_of_leap_year(1538, end)
result = leap_years_count * 366 + (exclusive_years - leap_years_count) * 365
return result
class day:
def __init__(self, day_string:str):
self.year = int(day_string[:4])
self.month = int(day_string[4:6])
self.day = int(day_string[6:])
def __sub__(self, other):
return abs(self.get_abs_day() - other.get_abs_day())
def get_abs_day(self):
res = get_abs_day_year(self.year)
res += sum(DAYS_LIST[:self.month-1])
res += self.day
res += 1 if self.month >= 3 and is_leap_year(self.year) else 0
return res
while __name__ == '__main__':
a, b = input().split()
print(day(a) - day(b))
파이썬 3.6.0 64
string1=20170529
string2=19930525
def month_cal(x):
count=1
total_day=0
while count<=x:
if count==1 or count==3 or count==5 or count==7 or count==8 or count==10 or count==12:
total_day+=31
elif count==2:
total_day+=28
else:
total_day+=30
count+=1
return total_day
def subday(string1,string2):
string1_year=int(string1/10000)
string2_year=int(string2/10000)
#윤년계산
if string1_year%4==0 and string1_year%100!=0:
string1+=1
elif string1_year%100==0 and string1_year%400==0:
string1+=1
if string2_year%4==0 and string2_year%100!=0:
string2+=1
elif string2_year%100==0 and string2_year%400==0:
string2+=1
str1_month=int((string1%10000)/100)-1
str2_month=int((string2%10000)/100)-1
str1_mon=month_cal(str1_month)
str2_mon=month_cal(str2_month)
str1_day=((string1%10000)%100)
str2_day=((string2%10000)%100)
total1=string1_year*365+str1_day+str1_mon
total2=string2_year*365+str2_day+str2_mon
return total1-total2
print(subday(string1,string2))
javascript(ES6)
var daysOfYear = [365, 366];
var daysOfMonth = [
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
];
var isLeapYear = y => (y % 4 == 0 && y % 100 !== 0) || y % 400 == 0;
var add = (a, b) => a + b;
var parseDate = function(s) {
var [, year, month, day] = /^(\d{4})(\d{2})(\d{2})$/g.exec(s).map(v => parseInt(v));
return [year, month, day];
}
var getDaysOfMonth = function(y, m) {
return daysOfMonth[~~isLeapYear(y)].filter((v, i) => i < m).reduce(add);
};
var getDaysBetweenYears = function(y1, y2) {
if (y1 === y2) return 0;
return Array.from(Array(y2 - y1), (v, i) => i + y1).map(v => daysOfYear[~~isLeapYear(v)]).reduce(add);
};
var subdate = function(s1, s2) {
var s = [s1, s2].sort(),
[year1, month1, day1] = parseDate(s[0]),
[year2, month2, day2] = parseDate(s[1]),
days1 = day1 + getDaysOfMonth(year1, month1);
days2 = day2 + getDaysOfMonth(year2, month2) + getDaysBetweenYears(year1, year2);
console.log(days2 - days1);
};
subdate(20070515, 20070501); // 14
subdate(20070501, 20070515); // 14
subdate(20070301, 20070515); // 75
[Python 3.6]
def subdate(date1, date2):
if(date1 > date2): (date1, date2) = (date2, date1)
result = 0
for year in range(int(date1[:4]), int(date2[:4])):
if(isLeafYear(year)): result += 366
else: result+= 365
result += calcYearDays(date2) - calcYearDays(date1)
return result
def calcYearDays(date):
sum = 0
year = date[:4]
for month in range(1, int(date[4:6])+1):
if month != int(date[4:6]):
sum += getMonthDays(year + str(month).rjust(2, '0'))
else:
sum += int(date[6:])
return sum
def getMonthDays(yearmonth):
if(isLeafYear(int(yearmonth[:4])) and yearmonth[4:] == "02"): return 29
if(yearmonth[4:] == "02") : return 28
if(yearmonth[4:] in ["01", "03", "05", "07", "08", "10", "12"]) : return 31
if(yearmonth[4:] in ["04", "06", "09", "11"]): return 30
def isLeafYear(year):
return year % 4 == 0 and (year % 400 == 0 or year % 100 != 0)
print(subdate("20070515", "20070501"))
print(subdate("20070501", "20070515"))
print(subdate("20070301", "20070515"))
입력받은 두 date를 1년 1월 1일부터 며칠 지났는지 각각 구해서 뺍니다.
함수명은 줄여 썼습니다.
days_of_year(y): 1년 1월 1일부터 y년 12월 31일까지 지난 날 수
days_of_month(m, y): y년 1월 1일부터 y년 m월 말일까지 지난 날 수
days_of_date(d): 1년 1월 1일부터 d(date)까지 지난 날 수
def year(date): return int(date[:4])
def month(date): return int(date[4:6])
def day(date): return int(date[6:])
def isleaf(y): return y % 400 == 0 or y % 100 > 0 and y % 4 == 0
def doy(y): return y * 365 + (y // 4 - y // 100 + y // 400);
def dom(m, y): return sum([0, 31, 30 + isleaf(y), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][1:m + 1])
def dod(d): return doy(year(d) - 1) + dom(month(d) - 1, year(d)) + day(d)
def subdate(date1, date2): return abs(dod(date1) - dod(date2))
print(subdate("20070515", "20070501"));
print(subdate("20070501", "20070515"));
print(subdate("20070301", "20070515"));
C#
using static System.Console;
class Date
{
public string date { get; set; }
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
public Date(string date)
{
this.date = date;
this.year = int.Parse(date.Substring(0, 4));
this.month = int.Parse(date.Substring(4, 2));
this.day = int.Parse(date.Substring(6));
}
}
class Program
{
static int doy(int y)
{
return y * 365 + (y / 4 - y / 100 + y / 400);
}
static int dom(int m, int y)
{
int[] doms = new int[13] {0, 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (y % 400 == 0 || (y % 100 > 0 && y % 4 == 0))
{
doms[2] += 1;
}
int sum = 0;
for (int i = 1; i <= m; i++)
{
sum += doms[i];
}
return sum;
}
static int SubDate(string s1, string s2)
{
Date date1 = new Date(s1);
Date date2 = new Date(s2);
return Math.Abs(
(doy(date1.year - 1) + dom(date1.month - 1, date1.year) + date1.day)
- (doy(date2.year - 1) + dom(date2.month - 1, date2.year) + date2.day)
);
}
static void Main(string[] args)
{
WriteLine(SubDate("20070515", "20070501"));
WriteLine(SubDate("20070501", "20070515"));
WriteLine(SubDate("20070301", "20070515"));
}
}
months = [31,28,31,30,31,30,31,31,30,31,30,31]
def f(day1, day2):
if day1 > day2:
day1, day2 = day2, day1
days = 0
for check1 in range(day1, day2):
check1 = list(map(int, [str(check1)[0:4], str(check1)[4:6],str(check1)[6:]]))
if days == 0 or check1[1] == 1:
if (check1[0]%400 == 0 or check1[0]%4 == 0) and (check1[0]%100 != 0):
months[1] = 29
else:
months[1] = 28
if check1[1] > 12:
continue
elif check1[2] > months[check1[1]-1]:
continue
elif check1[2] == 0:
continue
elif check1[1] == 0:
continue
days += 1
print(days)
f(20070515,20070501)
f(20070501,20070515)
f(20070301,20070515)
# python 3.6
def isYun(yy):
chk = False
if (yy % 4 == 0 and yy % 100 != 0) or yy % 400 == 0:
chk = True
return chk
def d1582(yy, mm, dd):
mdays_e = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
mdays_y = [0, 31, 29] + mdays_e[2:]
days = 0
for yr in range(1582, yy):
if isYun(yr):
days += sum(mdays_y)
else:
days += sum(mdays_e)
if isYun(yy):
days += sum(mdays_y[:mm]) + dd
else:
days += sum(mdays_e[:mm]) + dd
return days
def subdate(sdate, edate):
st = d1582(int(sdate[:4]), int(sdate[4:6]), int(sdate[6:8]))
en = d1582(int(edate[:4]), int(edate[4:6]), int(edate[6:8]))
return abs(en - st)
print(subdate("20070515", "20070501"))
print(subdate("20070501", "20070515"))
print(subdate("20070301", "20070515"))
class myDate(object):
def __init__(self, date):
temp = str(date)
self.date = date
self.year = int(temp[:4])
self.month = int(temp[4:6])
self.day = int(temp[6:8])
def subdate(idate1, idate2):
month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
date1 = myDate(idate1 if idate1>idate2 else idate2)
date2 = myDate(idate2 if idate1>idate2 else idate1)
difyearday = (date1.year - date2.year)*365
difmonthday = sum(month_list[0:date1.month-1]) - sum(month_list[0:date2.month-1])
difday = date1.day - date2.day + difyearday + difmonthday
return difday
def main():
print(subdate(20170101, 20170202))
main()
def datematch(n):
sent = str(n)
y = int(sent[0:4])
m = int(sent[5:6])
d = int(sent[7:])
nist = [y,m,d]
return nist
def ex_y(n):
if n % 4 == 0:
if n % 100 == 0:
if n % 400 == 0:
return True
else:
return False
return True
else:
return False
def count_y(n):
n = int(n - 1)
opt1 = n // 4
opt2 = n // 100
opt3 = n // 400
all = n * 365 + opt1 - opt2 + opt3
return all
def count_m(y, m):
count = 0
norm = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
ex = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if ex_y(y) == True:
for i in range(m):
count = count + ex[i]
else:
for i in range(m):
count = count + norm[i]
return count
def count_all(y,m,d):
all = count_y(y) + count_m(y, m) + d
return all
def final(n):
kist = datematch(n)
y = kist[0]
m = kist[1]
d = kist[2]
derm = count_all(y,m,d)
return derm
a = input("input date early: ")
b = input("input date late: ")
print (final(b))
print (final(a))
print (final(b)-final(a))
#include <stdio.h>
int getYear(char* d)
{
int result = 0;
int digit = 1000;
char c;
for (int i = 0; i < 4; i++)
{
c = *d;
d++;
result += (c - 48) * digit;
digit = digit / 10;
}
return result;
}
int getMonth(char* d)
{
d += 4;
int result = 0;
int digit = 10;
char c;
for (int i = 0; i < 2; i++)
{
c = *d;
d++;
result += (c - 48) * digit;
digit = digit / 10;
}
return result;
}
int getDay(char* d)
{
d += 6;
int result = 0;
int digit = 10;
char c;
for (int i = 0; i < 2; i++)
{
c = *d;
d++;
result += (c - 48) * digit;
digit = digit / 10;
}
return result;
}
int main()
{
char* a = "20070301";
char* b = "20070515";
int y1 = getYear(a), m1 = getMonth(a), d1 = getDay(a);
int y2 = getYear(b), m2 = getMonth(b), d2 = getDay(b);
int y3 = 0, m3 = 0, d3 = 0;
for (int i = 0; i < 8; i++)
{
if (a[i] > b[i])
{
break;
}
else if (a[i] < b[i])
{
y3 = y1; m3 = m1; d3 = d1;
y1 = y2; m1 = m2; d1 = d2;
y2 = y3; m2 = m3; d2 = d3;
break;
}
}
int result = 0;
int dayCountIndex = 0;
int maxDay;
int dayCount[2][13] = {{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }};
if ((y2 % 4) == 0 && ((y2 % 100) != 0 || (y2 % 400) == 0))
{
dayCountIndex = 1;
}
else
{
dayCountIndex = 0;
}
maxDay = dayCount[dayCountIndex][m2];
while (y1 != y2 || m1 != m2 || d1 != d2)
{
if ((d2 + 1) > maxDay)
{
if ((m2 + 1) > 12)
{
y2++;
m2 = 1;
d2 = 1;
if ((y2 % 4) == 0 && ((y2 % 100) != 0 || (y2 % 400) == 0))
{
dayCountIndex = 1;
}
else
{
dayCountIndex = 0;
}
maxDay = dayCount[dayCountIndex][m2];
result++;
}
else
{
m2++;
d2 = 1;
maxDay = dayCount[dayCountIndex][m2];
result++;
}
}
else
{
d2++;
result++;
}
}
printf("diff:%d\n", result);
}
파이썬 3.6
"""
아이디어>
1)입력받은 날짜 데이터의 시작날짜와 끝날짜 사이의 일 수를 윤년,월별 총일 수를 고려하여 구합니다.
- 윤년은 4로 나누어 떨이지는 해, 다만 100년 단위에서는 400으로 나누어 떨어지는 해만 윤년임.
- 평년 = 365, 윤년 = 366
- 월 별 일수:
: 1,3,5,7,8,10,12월 = 31
: 4,6,9,11월 = 30
: 2월 = 28/29(윤달)
2) 날짜 차이 계산 방법
- 시작하는 날짜가 속한 해와 끝나는 날짜가 속한 해의 사이의 연도들은 윤년 여부를 체크하여 date_sub에 더하여 줍니다.
- 시작하는 해의 1월 1일 부터 시작하는 날짜까지의 일수는 date_sub에서 빼 줍니다.(2월 윤달 여부 확인)
- 끝나는 해의 1월 1일 부터 시작하는 날까지의 일수는 date_sub에 더하여 줍니다.(2월 윤달 여부 확인)
"""
def subdate(data):
date_sub = 0
data.sort(reverse = True)
for year in range(int(data[1][:4])+1,int(data[0][:4])+1):
if year%4 == 0:
if year%100 == 0 and year%400 != 0:
date_sub += 365
else: date_sub += 366
else: date_sub += 365
for i, date in enumerate(data):
if i == 0:
for g in range(1,int(data[i][4:6])):
if data[i][4:6] in ['01','03','05','07','08','10','11']:
date_sub += 31
elif data[i][4:6] in ['04','06','09','11']:
date_sub += 30
elif data[i][4:6] == '02':
if int(data[i][:4])%4 == 0:
if int(data[i][:4])%100 == 0 and year%400 != 0:
date_sub += 28
else:
date_sub += 29
else:
date_sub += 28
date_sub += int(data[i][6:])
if i == 1:
for g in range(1,int(data[i][4:6])):
if data[i][4:6] in ['01','03','05','07','08','10','11']:
date_sub -= 31
elif data[i][4:6] in ['04','06','09','11']:
date_sub -= 30
elif data[i][4:6] == '02':
if int(data[i][:4])%4 == 0:
if int(data[i][:4])%100 == 0 and year%400 != 0:
date_sub -= 28
else:
date_sub -= 29
else:
date_sub -= 28
date_sub -= int(data[i][6:])
print("\n""%s sub %s = %d 일"%(date_1,date_2,date_sub))
if __name__ == "__main__":
date_1,date_2 = input("date_1(YYYYMMDD): "),input("date_2(YYYYMMDD): ")
data = [ date_1,date_2]
subdate(data)
*결과값
date_1(YYYYMMDD): 20090515
date_2(YYYYMMDD): 20070501
20090515 sub 20070501 = 745 일
date_1(YYYYMMDD): 20070501
date_2(YYYYMMDD): 20090515
20070501 sub 20090515 = 745 일
date_1(YYYYMMDD): 20070501
date_2(YYYYMMDD): 20070515
20070501 sub 20070515 = 14 일
package subdate;
public class Subdate {
// 서력 기원 연수가 4로 나누어떨어지는 해는 윤년으로 한다.(1988년, 1992년, 1996년, 2004년, 2008년, 2012년
// …)
// 이 중에서 100으로 나누어떨어지는 해는 평년으로 한다.(1900년, 2100년, 2200년, 2300년, 2500년 …)
// 그중에 400으로 나누어떨어지는 해는 윤년으로 둔다.(1600년, 2000년, 2400년 …)
private boolean isLeapYear(int year) {
if (year % 4 == 0)
if (year % 100 == 0 && year % 400 != 0)
return false;
else
return true;
return false;
}
private int[] getDateToIntArray(int n) {
String str = Integer.toString(n);
if (str.length() != 8)
return null;
return new int[] { Integer.parseInt(str.substring(0, 4)), Integer.parseInt(str.substring(4, 6)),
Integer.parseInt(str.substring(6, str.length())) };
}
private int sumYears(int nYear, int mYear) {
int year = Math.abs(nYear - mYear);
int minYear = Math.min(nYear, mYear);
int result = 0;
for (int i = 0; i < year; i++) {
if (isLeapYear(minYear + i))
result += 1;
result += 365;
}
return result;
}
private int sumMonthsAndDays(int[] nArray, int[] mArray) {
int[] months = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int month = Math.abs(mArray[1] - nArray[1]);
int result = 0;
if (month > 0) {
if (Math.abs(month) == 1)
result += (months[nArray[1]] - nArray[2]) + mArray[2];
else {
for (int i = nArray[1] + 1; i < mArray[1]; i++)
result += months[i];
result += (months[nArray[1]] - nArray[2]) + mArray[2];
}
} else
result += nArray[2] - mArray[2];
return result;
}
public int subdate(int n, int m) {
int result = 0;
int[] nArray = getDateToIntArray(n);
int[] mArray = getDateToIntArray(m);
// sum to years, months, days
result = sumYears(nArray[0], mArray[0]) + sumMonthsAndDays(nArray, mArray);
return Math.abs(result);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Subdate sd = new Subdate();
System.out.println(sd.subdate(20070505, 20070525));
System.out.println(sd.subdate(20070405, 20070525));
System.out.println(sd.subdate(20070305, 20070525));
System.out.println(sd.subdate(20070515, 20070501));
System.out.println(sd.subdate(20070501, 20070525));
System.out.println(sd.subdate(20070301, 20070515));
System.out.println(sd.subdate(20030303, 20180201));
System.out.println(sd.subdate(10000101, 19991231));
System.out.println(sd.subdate(20180101, 20170101));
System.out.println(sd.subdate(20170101, 20180101));
}
}
common = {1:0, 2:31, 3:59, 4:90, 5:120, 6:151, 7:181, 8:212, 9:243, 10:273, 11:304, 12:334}
leap = {1:0, 2:31, 3: 60, 4:91, 5:121, 6:152, 7:182, 8:213, 9:244, 10:274, 11:305, 12:335}
def date(n):
result = 0
year = int(n[0:4])
result += 366 + year*365 + year//4 - year//100 + year//400
month = int(n[4:6])
if not(year%400):
result += leap.get(month)
elif not(year%100):
result += leap.get(month)
elif not(year%4):
result += leap.get(month)
else:
result += leap.get(month)
result += int(n[6:8])
return result
def subdate(m, n):
if m < n:
(m,n) = (n,m)
return date(m) - date(n)
a = input().split(' ')
print(subdate(a[0], a[1]))
def day(n):
mon_day=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
yy=n//10000
mm=(n//100)%100
print(mm)
dd=n%100
re=(yy-1)*365+(yy-1)%4-(yy-1)%100+(yy-1)%400+sum(mon_day[0:mm-1])+dd
if mm>2: re+=(yy%4==0 and 1 or 0)-(yy%100==0 and 1 or 0)+(yy%400==0 and 1 or 0)
return re
def sub(n,m): print(abs(day(n)-day(m)))
def resort(a):
print([a[i//2+((len(a)//2)*((-1)**(i%2+1))+(len(a)//2))//2 ] for i in range(len(a))])
#include <stdio.h>
int day(int n) {
int re, yy, mm, dd;
int mon_day[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
yy = n / 10000;
mm = (n / 100) % 100;
dd = n % 100;
re = (yy - 1) * 365 + (yy - 1) % 4 - (yy - 1) % 100 + (yy - 1) % 400 +mon_day[mm-1] +dd;
if (mm>2) re += (yy % 4 == 0 ? 1 : 0) - (yy % 100 == 0 ? 1 : 0) + (yy % 400 ==0? 1 : 0);
return re;
}
int main() {
int n, m;
printf("날짜 두개를 입력해주세요. 첫번째 날짜 : ");
scanf_s("%d", &n);
printf("날짜 두개를 입력해주세요. 두번째 날짜 : ");
scanf_s("%d", &m);
printf("%d일 차이가 납니다.", m > n ? day(m) - day(n) : day(n) - day(m));
return 0;
}
public class Subdate {
public static int compute(String dateInput){
int result = 0;
int intYear = Integer.parseInt(dateInput.substring(0,4));
int intMonth = Integer.parseInt(dateInput.substring(4, 6));
int intDate = Integer.parseInt(dateInput.substring(6));
result = (intYear * 365) + (intYear / 4) + (intYear / 400) - (intYear / 100);
if(intMonth == 1){ //31
result += intDate;
}else if(intMonth == 2){ //28
result += intDate + 31;
}else if(intMonth == 3){//31
result += intDate + 59;
}else if(intMonth == 4){//30
result += intDate + 90;
}else if(intMonth == 5){//31
result += intDate + 120;
}else if(intMonth == 6){//30
result += intDate + 151;
}else if(intMonth == 7){//31
result += intDate + 181;
}else if(intMonth == 8){//31
result += intDate + 212;
}else if(intMonth == 9){//30
result += intDate + 243;
}else if(intMonth == 10){//31
result += intDate + 273;
}else if(intMonth == 11){//30
result += intDate + 304;
}else if(intMonth == 12){//31
result += intDate + 334;
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int result = Math.abs(compute("20070515") - compute("20070501"));
System.out.println("20070515 sub 20070501 = " + result);
result = Math.abs(compute("20070501") - compute("20070515"));
System.out.println("20070501 sub 20070515 = " + result);
result = Math.abs(compute("20070301") - compute("20070515"));
System.out.println("20070301 sub 20070515 = " + result);
}
}
20070515 sub 20070501 = 14
20070501 sub 20070515 = 14
20070301 sub 20070515 = 75
파이썬입니다. 실력이 부족해 조금 노가다 식으로 작성했습니다...
def subdate(s1,s2):
day=0
month={'1':31,'2':28,'3':31,'4':30,'5':31,'6':30,'7':31,'8':31,'9':30,'10':31,'11':30,'12':31}
y1,m1,d1=int(s1[:4]),int(s1[4:6]),int(s1[6:])
y2,m2,d2=int(s2[:4]),int(s2[4:6]),int(s2[6:])
if y1>=y2:
day+=(y1-y2)*365
if m1>=m2:
day+=sum(list(month[str(n)] for n in range(m2,m1)))
if d1>=d2:
day+=d1-d2
elif d2>d1:
day-=d2-d1
elif m2>m1:
day-=sum(list(month[str(n)] for n in range(m1,m2)))
if d1>=d2:
day+=d1-d2
elif d2>d1:
day-=d2-d1
elif y2>y1:
day+=(y2-y1)*365
if m2>m1:
day+=sum(list(month[str(n)] for n in range(m1,m2)))
if d2>d1:
day+=d2-d1
elif d1>d2:
day-=d1-d2
elif m1>m2:
day-=sum(list(month[str(n)] for n in range(m2,m1)))
if d2>d1:
day+=d2-d1
elif d1>d2:
day-=d1-d2
print(s1,'sub',s2,'=',abs(day))
subdate('20070515','20070501')
subdate('20070501','20070515')
subdate('20070301','20070515')
subdate('20080515','20070601')
subdate('10000101','20180325')
결과입니다.
20070515 sub 20070501 = 14
20070501 sub 20070515 = 14
20070301 sub 20070515 = 75
20080515 sub 20070601 = 348
10000101 sub 20180325 = 371653
/* Subdate */
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(subDate(20070515, 20070501))
fmt.Println(subDate(20070301, 20070515))
}
func isYun(year int) bool {
rst := false
if (year%4 == 0 && year%100 != 0) || year%400 == 0 {
rst = true
}
return rst
}
func daysInMonth(year int) []int {
days := []int{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // don't count days[0]
if isYun(year) {
days[2] = 29
}
return days
}
func daysInYear(year int) int {
days := 0
for m := 1; m <= 12; m++ {
days += daysInMonth(year)[m]
}
return days
}
func daysFromOrigin(year, month, day int) int {
days := day
for m := 1; m < month; m++ {
days += daysInMonth(year)[m]
}
for y := 1582; y < year; y++ { // Gregorian calendar starts in 1582
days += daysInYear(y)
}
return days
}
func parseDate(date int) (year, month, day int) {
datestr := fmt.Sprint(date)
n, err := fmt.Sscanf(datestr, "%4d%2d%2d", &year, &month, &day)
if n != 3 || err != nil {
panic("Invalid date string")
}
return
}
func subDate(date1, date2 int) int {
y1, m1, d1 := parseDate(date1)
y2, m2, d2 := parseDate(date2)
sub := math.Abs(float64(daysFromOrigin(y1, m1, d1) - daysFromOrigin(y2, m2, d2)))
return int(sub)
}
import datetime
import re
import time
a, b = input(), input()
date = re.compile("(\d\d\d\d)(\d\d)(\d\d)")
m = date.search(a)
year1 = int(m.group(1))
month1 = int(m.group(2))
day1 = int(m.group(3))
m = date.search(b)
year2 = int(m.group(1))
month2 = int(m.group(2))
day2 = int(m.group(3))
date1 = time.mktime((year1, month1, day1,0, 0, 0, 0, 0, 0))
date2 = time.mktime((year2, month2, day2,0, 0, 0, 0, 0, 0))
print(abs(date1 - date2) // 86400)
package my;
import java.util.HashMap;
import java.util.Map;
public class T {
public static void main(String[] args) {
day(20070515,20070501);
}
public static int day(int a, int b){
int A;
int B;
Map map = new HashMap();
map.put("1", 31);
map.put("2", 28);
map.put("3", 31);
map.put("4", 30);
map.put("5", 31);
map.put("6", 30);
map.put("7", 31);
map.put("8", 30);
map.put("9", 31);
map.put("10", 31);
map.put("11", 30);
map.put("12", 31);
if(a>b){
A=a;
B=b;
}else{
A=b;
B=a;
}
int yA=A/10000;
int yB=B/10000;
int mA=A%10000/100;
int mB=B%10000/100;
int dA=A%100;
int dB=B%100;
/*A*/
//연도 차이 계산
int totA = 0;
for(int i=yB;i<yA;i++){
for(int j=1;j<=12;j++){
totA+=(int)map.get(String.valueOf(j));
}
//윤년 일 추가
if(i%400==0||i%4==0&&i%100!=0){
totA+=1;
System.out.println(i+"윤년 + 1일");
}
}
//해당 년 월 계산
for(int i=1;i<mA;i++){
totA+=(int)map.get(String.valueOf(i));
}
//윤년 추가 계산
if((yA%400==0||yA%4==0&&yA%100!=0)&&(mA>=3||mA==2&&dA==29)){
totA+=1;System.out.println("윤년 + 1일");
}
//해당 년 일 계산
totA+=dA;
/*B*/
//해당 년 월계산
int totB = 0;
for(int i=1;i<mB;i++){
totB+=(int)map.get(String.valueOf(i));
}
//윤년 추가 계산
if((yB%400==0||yB%4==0&&yB%100!=0)&&(mB>=3||mB==2&&dB==29)){
totB+=1;System.out.println("윤년 + 1일");
}
//해당 년 일 계산
totB+=dB;
System.out.println(totA - totB+"일 차이");
System.out.println(yA+"년"+mA+"월"+dA+"일");
System.out.println(yB+"년"+mB+"월"+dB+"일");
return totA - totB;
}
}
import datetime
def sub(a,b): a, b = str(a), str(b) ay , am, ad = int(a[:4]), int(a[4:6]), int(a[6:]) by, bm, bd = int(b[:4]), int(b[4:6]), int( b[6:]) day1 = datetime.datetime(ay,am,ad) day2 = datetime.datetime(by,bm,bd) term = day2 - day1 print("{0} - {1} = {2}days ".format(b,a,term.days))
sub(20070501, 20070515)```{.python}
```
Python
test = [[20070515, 20070501], [20070501, 20070515], [20070301, 20070515], [20080614, 20080711]]
def isleapyear(i):
leapYear = False
if i % 4 == 0:
leapYear = True
if i % 100 == 0:
leapYear = False
if i % 400 == 0:
leapYear = True
return leapYear
def cntDay(m, d, y):
#1월부터 셈
leapYear = isleapyear(y)
cnt = 0
feb = 29 if leapYear else 28
for i in range(1, m):
if i == 2:
cnt += feb
elif str(i) in ["4","6","9","11"]:
cnt += 30
else:
cnt += 31
cnt += d
return cnt
#y1, y2 = map(int, input().split(' '))
for y1, y2 in test:
if y2 < y1:
y1, y2 = y2, y1
y1 = str(y1); y2 = str(y2)
cnt = 0
for i in range(int(y1[:4]), int(y2[:4])):
leapYear = isleapyear(i)
k = 366 if leapYear else 365
cnt += k
cnt += cntDay(int(y2[4:6]), int(y2[6:]), int(y2[4:])) - cntDay(int(y1[4:6]), int(y1[6:]), int(y2[4:]))
print(cnt)
Swift입니다.
let days = [31,28,31,30,31,30,31,31,30,31,30,31]
func getDaysInYear(_ year: Int) -> Int {
if year % 400 == 0 {
return 366
} else if year % 100 == 0 {
return 365
} else if year % 4 == 0 {
return 366
} else {
return 365
}
}
func countDay(_ year:Int, _ startMonth:Int, _ startDay: Int, _ endMonth: Int, _ endDay: Int) -> Int {
if startMonth == endMonth {
return endDay - startDay
} else {
let remainingDay1 = days[startMonth - 1] - startDay
var monthDay = 0
if endMonth > startMonth + 1 {
for monthIndex in (startMonth + 1)..<endMonth {
monthDay += days[monthIndex - 1]
}
}
var leapDay = 0
if getDaysInYear(year) == 366 {
if startMonth >= 2 || endMonth <= 2 {
leapDay = 1
}
}
return remainingDay1 + leapDay + monthDay + endDay
}
}
func subDate(_ dateOne: Int, _ dateTwo: Int) -> Int {
let date1 = dateOne > dateTwo ? dateTwo : dateOne
let date2 = dateOne <= dateTwo ? dateTwo : dateOne
let day1 = date1 % 100
let month1 = (date1 / 100) % 100
let year1 = date1 / 10000
let day2 = date2 % 100
let month2 = (date2 / 100) % 100
let year2 = date2 / 10000
if year1 == year2 {
// #1. Same year
// 2018 03 01 ==> Count day from the begining of the year
// 2018 01 15 ==> Count day from the begining of the year
// ==> Subtract the days
return countDay(year1, 1, 1, month2, day2) - countDay(year1, 1, 1, month1, day1)
} else {
// #2. Different year
// 2018 01 02 ==> Count day from the begining of the year
// 2017 10 01 ==> Count day from the given date upto the end of the year
// ==> Add the days and days of the year between years
let d1 = countDay(year1, month1, day1, 12, 31);
let d2 = countDay(year2, 1, 1, month2, day2);
var yearDays = 0
if year2 > year1 + 1 {
for yearIndex in (year1 + 1) ..< year2 {
yearDays += getDaysInYear(yearIndex)
}
}
return d1 + yearDays + d2;
}
}
print( subDate( 20070515, 20070301) )
using System;
namespace CD008
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(SubDate("20070515 sub 20070501"));
Console.WriteLine(SubDate("20070501 sub 20070515"));
Console.WriteLine(SubDate("20070301 sub 20070515"));
}
static int SubDate(string aString)
{
string[] input = aString.Split();
return Math.Abs(new CalDays(input[0]).Count() - new CalDays(input[2]).Count());
}
}
// this.Count(): 그레고리력 시작년도부터의 일 수 반환
class CalDays
{
readonly int Year, Month, Day;
int[] _DaysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int[] DaysInMonth
{
get
{
if (IsYun(Year)) { _DaysInMonth[2] = 29; }
return _DaysInMonth;
}
}
public CalDays(string dateString)
{
Year = int.Parse(dateString.Substring(0, 4));
Month = int.Parse(dateString.Substring(4, 2));
Day = int.Parse(dateString.Substring(6, 2));
}
public int Count() // days from 1582 그레고리력 시작년도
{
int days = Day;
for (int y = 1582; y < Year; y++)
{
days += DaysInYear(y);
}
for (int m = 1; m < Month; m++)
{
days += DaysInMonth[m];
}
return days;
}
static int DaysInYear(int year) => IsYun(year) ? 366 : 365;
static bool IsYun(int year)
{
bool check = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
return check ? true : false;
}
}
}
def absdate(n):
n = str(n)
em = [31,28,31,30,31,30,31,31,30,31,30,31]
Y,M,D = map(int,[n[:4],n[4:6],n[6:]])
Yd = 365*abs(Y - 1601)+abs(Y - 1601)//4+abs(Y - 1601)//400-abs(Y - 1601)//100
Md = sum(em[:M-1])+ ( 1 if M>2 and Y%4==0 and (Y%400==0 or Y%100!=0) else 0 )
Dd = D-1
return Yd+Md+Dd
subdate = lambda x,y: abs(absdate(x)-absdate(y))
print(subdate(20060701,20070801))
그레고리력 기준으로 1601년부터 찾습니다.
start_date,end_date = raw_input().split()
d = [31,28,31,30,31,30,31,31,30,31,30,31]
def is_yun_year(y):
if y % 400 == 0: return 1
if y % 100 == 0: return 0
if y % 4 == 0: return 1
def calc_date(y,s,e):
if is_yun_year(y) == 1: d[1] = 29
else: d[1] = 28
smon = int(s[:2])
emon = int(e[:2])
sdat = int(s[-2:])
edat = int(e[-2:])
if smon == emon:
return (edat - sdat)
else:
v = d[smon-1] - sdat
for x in range(smon+1, emon ):
v += d[x-1]
v += edat
return v
y_list = [ x for x in range(int(start_date[:4]), int(end_date[:4]) + 1) ]
if y_list[0] == y_list[-1]:
ret = calc_date(y_list[0],start_date[4:],end_date[4:])
else:
ret = calc_date(y_list[0],start_date[4:],'1231')
for x in range(1,len(y_list)-1):
if is_yun_year(y_list[x]) == 1:
ret += 366
else:
ret += 365
ret += calc_date(y_list[-1],'0100',end_date[4:])
print(ret)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
namespace Subdate
{
class Program
{
static void Main(string[] args)
{
int diffDay;
TimeSpan SubDate;
string[,] strDate ={{"20070515", "20070501"},
{"20070501", "20070515"},
{"20070301", "20070515"}};
for (int i = 0; i < strDate.GetLength(0); i++)
{
var FirDate = DateTime.ParseExact(strDate[i,0], "yyyyMMdd", CultureInfo.InvariantCulture);
var SecDate = DateTime.ParseExact(strDate[i,1], "yyyyMMdd", CultureInfo.InvariantCulture);
if (FirDate > SecDate)
SubDate = FirDate.Subtract(SecDate);
else
SubDate = SecDate.Subtract(FirDate);
diffDay = SubDate.Days;
Console.WriteLine(diffDay.ToString());
}
}
}
}
def deter_extra_years(y):# y값을 받아서 윤년인 경우 1을 아닌경우 0을 반환하는 함수.
if y%400==0:
return 1
elif y%100==0:
return 0
elif y%4==0:
return 1
else:
return 0
dates={'1':31, '2':28,'3':31,'4':30,'5':31,'6':30,'7':31,'8':31,'9':30,'10':31,'11':30,'12':31}
date1,date2=input().split(' sub ')
if int(date1)>int(date2): #무조건 date2가 더 나중값으로 설정.
temp = date1
date1=date2
date2=temp
date1_y = int(date1[:4])
date1_m = int(date1[4:6])
date1_d = int(date1[6:])
date2_y = int(date2[:4])
date2_m = int(date2[4:6])
date2_d = int(date2[6:])
stand_d1=0
total_d2=0
if date1_m>1:
stand_d1+=deter_extra_years(date1_m) # 만약 윤년이라면 1을 더해준다.
for i in range(date1_m-1): #그 해 1월달 부터 m달 이전까지의 일수 구하기
stand_d1+=dates[str(i+1)]
#이렇게 하면 기준이 되는 해에 1월1일 기준으로 값을 구 할 수 있다.
stand_d1+=date1_d
if (date2_y - date1_y)>0:
for j in range(date2_y - date1_y):
total_d2+=deter_extra_years(date1_y+j) # 해당년이 윤년인 경우 하루를 더해준다.
total_d2+=365
#여기까지 진행했다면 년차로 차이나는 일수는 정확히 계산됨.
for i in range(date2_m-1): #그 해 1월달 부터 m달 이전까지의 일수 구하기
total_d2+=dates[str(i+1)]
total_d2+=date2_d
print('두 날짜의 차이는 {0}'.format(total_d2-stand_d1))
def sub(a,b):
a,b = [int(a[0:4]),int(a[4:6]),int(a[6:8])],[int(b[0:4]),int(b[4:6]),int(b[6:8])]
md = [31,59,90,120,151,181,212,243,273,304,334,365]
print(abs((365*a[0]+md[a[1]-1]+a[2]+int(97*a[0]/400))-
(365*b[0]+md[b[1]-1]+b[2]+int(97*b[0]/400))))
#include <iostream>
using namespace std;
const int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int subdat(int n1, int n2){
int m1, m2, y1,y2,d1,d2;
int a, b;
d1=n1%100,d2=n2%100;
m1=(n1%10000)/100,m2=(n2%10000)/100;
y1=n1/10000,y2=n2/10000;
a= (y1-1)*365 + int(y1/4) - int(y1/100) + int(y1/400);
b= (y2-1)*365 + int(y2/4) - int(y2/100) + int(y2/400);
for(int i=0;i<m1;i++) a+=months[i];
if(m1>1 && y1/4==0) a++;
for(int i=0;i<m2;i++) b+=months[i];
if(m2>1 && y2/4==0) b++;
a+=d1,b+=d2;
if(a>b) return a-b;
else return b-a;
}
int main(){
cout<< "10000101 sub 19991231 = "<<subdat(10000101,19991231) <<endl;
cout<< "20070515 sub 20070501 = "<<subdat(20070301,20070515) <<endl;
}
#1801년 1월 1일=> 1
def date(day):
year=int(day[0:4])
mon=int(day[4:6])
day=int(day[6:8])
if year < 1801:
print('범위 초과, 1801년 1월 1일 이후 날짜만 가능')
return 1
month=[31,28,31,30,31,30,31,31,30,31,30]#1~11월
if year%4==0 :
month[1]=29
elif year%4!=0 or year%400!=0:
month[1]=28
y19=year-1801
years=(y19*365)+(y19//4)-(y19//100)+((year-1601)//400)
#1801 이후 400의 배수는 2000부터
dday=years+sum(month[0:mon-1])+day
return dday
day1=input('날짜 입력: ')
day2=input('날짜 입력: ')
subday=abs(date(day1)-date(day2))
print('두 날짜의 차이 일수: ',subday)
leap_year = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
non_leap_year = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def get_data_of_year(year, month):
days = 0
month_tbl = leap_year if 0 == year % 4 or 0 != year % 100 else non_leap_year
for i in range(month - 1):
days += month_tbl[i]
return days
def get_diff_date(date1, date2):
days = (int(date1[:4]) - int(date2[:4]))*365
days1 = get_data_of_year(year1, int(date1[4:6])) + int(date1[6:])
days2 = get_data_of_year(year2, int(date2[4:6])) + int(date2[6:])
return days + days1 - days2
date1 = input('input date1: ')
date2 = input('input date2: ')
if int(date1) < int(date2):
date1, date2 = date2, date1
print(get_diff_date(date1, date2))
package problem08;
import java.util.Scanner;
public class solution {
public static int day_of_year(int num) {
int sum = 0;
if(num%100==0) {
if(num%400==0) {
sum=366;
}
else {
sum=365;
}
}
else if(num%4==0) {
sum=366;
}
else {
sum=365;
}
return sum;
}
public static int counter(int year, int month) {
int sum=0;
int[] day_366 = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] day_365 = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(year%100==0) {
if(year%400==0) { //2월 29일
for(int i = month; i<12;i++) {
sum+=day_366[i];
}
}
else { //2월 28일
for(int i = month; i<12;i++) {
sum+=day_365[i];
}
}
}
else if(year%4==0) { //2월 29일
for(int i = month; i<12;i++) {
sum+=day_366[i];
}
}
else { //2월 28일
for(int i = month; i<12;i++) {
sum+=day_365[i];
}
}
return sum;
}
public static int counting_start_date(int year, int month, int day) {
int sum=0;
int[] day_366 = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] day_365 = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(year%100==0) {
if(year%400==0) { //2월 29일
for(int i = month; i<12;i++) {
sum+=day_366[i];
}
sum+= (day_366[month-1]-day) ;
}
else { //2월 28일
for(int i = month; i<12;i++) {
sum+=day_365[i];
}
sum+=(day_365[month-1]-day) ;
}
}
else if(year%4==0) { //2월 29일
for(int i = month; i<12;i++) {
sum+=day_366[i];
}
sum+= (day_366[month-1]-day) ;
}
else { //2월 28일
for(int i = month; i<12;i++) {
sum+=day_365[i];
}
sum+=(day_365[month-1]-day) ;
}
return sum;
}
public static int counting_end_date(int year, int month, int day) {
int sum=0;
int[] day_366 = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] day_365 = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(year%100==0) {
if(year%400==0) { //2월 29일
for(int i = 0; i < month-1 ; i++) {
sum+=day_366[i];
}
sum+=day;
}
else { //2월 28일
for(int i = 0; i < month-1 ; i++) {
sum+=day_365[i];
}
sum+=day;
}
}
else if(year%4==0) { //2월 29일
for(int i = 0; i < month-1 ; i++) {
sum+=day_366[i];
}
sum+=day;
}
else { //2월 28일
for(int i = 0; i < month-1 ; i++) {
sum+=day_365[i];
}
sum+=day;
}
return sum;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("두 날짜를 입력해주세요 : (예: 20190210)");
int a = scan.nextInt();
int b = scan.nextInt();
int start_date = 0;
int end_date = 0;
if(a<b) {
start_date = a;
end_date = b;
}
else {
start_date = b;
end_date = a;
}
int sum = 0;
//년, 월, 일 분해
int start_day=start_date%100;
int start = start_date/100;
int start_month = start%100;
int start_year = start/100;
int end_day=end_date%100;
int end = end_date/100;
int end_month = end%100;
int end_year = end/100;
if(end_year-start_year==0) {
if(end_month-start_month==0) {
sum = end_day-start_day;
}
else {
sum = counting_end_date(end_year, end_month, end_day)- counting_end_date(start_year, start_month, start_day);
}
}
else if(end_year-start_year==1) {
sum = counting_start_date(start_year, start_month, start_day) + counting_end_date(end_year, end_month, end_day);
}
else {
sum = counting_start_date(start_year, start_month, start_day) + counting_end_date(end_year, end_month, end_day);
for(int i=1; i< end_year - start_year-1; i++) {
sum+= day_of_year(start_year+i);
}
}
System.out.println(a+" sub "+ b + " = " + sum);
}
}
첫번째 메서드(day_of_year) : 해당 년도의 총 일수를 반환하는 기능. 두번째 메서드(counter) : 년도와 월이 주어졌을 때, 그 다음달부터 해당 년도 마지막 날까지의 일수를 반환하는 기능. 세번째 메서드(counting_start_date) : 입력받은 시작날짜를 기준으로 그 해당년도 마지막 날 까지의 일수를 반환하는 기능. 네번째 메서드(counting_end_date) : 입력받은 마지막 날짜를 기준으로 그 해당년도 첫 날부터 입력받는 마지막 날까지의 일수를 반환하는 기능.
마지막으로 메인에서는 같은 년도일 때 그중에서도 월이 같을 때와 다를 때를 각각 계산고 만약 년도의 차이가 1년일 때, 그리고 년도의 차이가 2년이상 차이날 때로 경우를 나누어서 계산하게 하였습니다.
dic={'01':0, '02':31, '03':59, '04':90, '05':120, '06':151, '07':181, '08':212, '09':243, '10':273, '11':304, '12':334}
def Cal(x,y):
lun=int(str(x)[0:4])//4
dy=(int(str(x)[0:4])-lun)*365+lun*366 #윤달을 계산한 년자에 대한 일수
dd=int(str(x)[6:8]) #일자에 대한 일수
for i in dic:
if i==str(x)[4:6]:
dm=dic[i] #월자에 대한 일수
xd=dy+dm+dd #전체 일수
lun=int(str(y)[0:4])//4
ddy=(int(str(y)[0:4])-lun)*365+lun*366 #윤달을 계산한 년자에 대한 일수
ddd=int(str(y)[6:8]) #일자에 대한 일수
for i in dic:
if i==str(y)[4:6]:
ddm=dic[i] #월자에 대한 일수
yd=ddy+ddm+ddd #전체 일수
dif=xd-yd #두 전체 일수의 차
if dif>=0:
print(dif)
else:
print(-dif)
코린입니다. 두 입력값을 각각 전체 일수로 변환하고 차를 구했습니다. 윤달도 계산했습니다. 너무 긴 것 같네용
파이썬 3.7.2
def day(n1: str, n2: str):
y = [int(n1[:4]), int(n2[:4])]
m = [int(n1[4:6]), int(n2[4:6])]
d = [int(n1[6:]), int(n2[6:])]
M = [31,[28,29],31,30,31,30,31,31,30,31,30,31,30]
date = [0, 0]
for x in range(2):
for i in range(y[x]):
if i % 4 == 0:
date[x] += 366
else:
date[x] += 365
for j in range(m[x]):
if j == 1:
if y[x] % 4 == 0:
date[x] += M[j][1]
else:
date[x] += M[j][0]
else:
date[x] += M[j]
date[x] += d[x]
if date[0] > date[1]:
return date[0]-date[1]
elif date[0] == date[1]:
return 0
elif date[0] < date[1]:
return date[1]-date[0]
a = input("> ")
b = input("> ")
print(a+" sub "+b+" = "+str(day(a, b)))
year = 365
month = [31,28,31,30,31,30,31,31,30,31,30,31]
month_leap =[31,29,31,30,31,30,31,31,30,31,30,31]
sum_month = [[sum(month[0:i+1]) for i in range(0,12)],[sum(month_leap[0:i+1]) for i in range(0,12)]]
def leap_year(num1):
leap_year=0
if(num1%4==0):
leap_year=1
return leap_year
def isit_year(date,leap_year):
isityear=True
if(int(''.join(date[4:6]))>12 | int(''.join(date[6:]))>int(month[date[4:6][leap_year]])):
isityear=False
return isityear
date1 = list(input(">> ")) # 20140605
date2 = list(input(">> ")) # 19950706
year1 = int(''.join(date1[:4]))
year2 = int(''.join(date2[:4]))
leap_year1 = leap_year(year1)
leap_year2 = leap_year(year2)
isityear1 = isit_year(date1,leap_year1)
isityear2 = isit_year(date2,leap_year2)
if(isityear1==False or isityear2==False):
print('잘못된 날짜입니다.')
else:
month1 = int(''.join(date1[4:6]))
month2 = int(''.join(date2[4:6]))
day1 = int(''.join(date1[6:]))
day2 = int(''.join(date2[6:]))
date_year = abs(year1 - year2)
if(date_year!=0):
leap_year_cnt = date_year / 4 + 1
else:
leap_year_cnt=0
date_day = abs(day1-day2)
date_month1 = sum_month[leap_year1][month1]
date_month2 = sum_month[leap_year2][month2]
date_month = abs(date_month1 - date_month2)
year_sub = (leap_year_cnt * 366) + ((date_year-leap_year_cnt) * 365)
print(year_sub + date_month + date_day)
Javascript(ES6)...
`엑셀처럼 날짜를 일련번호화 하여 계산, 날짜를 받으면 1년 1월 1일 부터 시작해서 떨어진 날짜만큼 일련번호 부여, 두 날짜의 일련번호 차이가 날짜 차이가 됨
윤년 판별은 위키피디아(https://ko.wikipedia.org/wiki/%EC%9C%A4%EB%85%84)를 참고하여 윤년여부 판단
클래스를 생성할 때 주어지는 날짜가 현실에 존재하는 날짜인지 확인하는 로직은 구현하지 아니함`;
class CustomDate {
constructor(date = '00010101') {
this.date = date.toString();
this.year = Number(this.date.substring(0, 4));
this.month = Number(this.date.substring(4, 6));
this.day = Number(this.date.substring(6, 8));
this.end_of_month = [0, 31, this._is_leapyear(this.year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// 연도, 월, 일에 해당하는 날짜만큼 일련번호 화
this.serial = (this.year - 1) * 365 + this._count_leapyears();
this.serial += this.end_of_month.slice(1, this.month).reduce((acc, val) => acc + val);
this.serial += this.day;
}
// 주어진 연도가 윤년인지 검사
_is_leapyear(y) {
return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0) ? true : false;
}
// 주어진 기간(start_y 이상 end_y 미만) 사이에 윤년이 몇번 있는지 검사
_count_leapyears(start_y = 1, end_y = this.year) {
let count = 0;
for(let i = start_y; i < end_y; i++) {
(this._is_leapyear(i)) ? count++ : 0;
}
return count;
}
// 날짜 차이 구하는 함수
sub(other) {
console.log(`${this.date} sub ${other.date} = ${Math.abs(this.serial - other.serial)}`);
}
}
new CustomDate(20070515).sub(new CustomDate(20070501)); // 20070515 sub 20070501 = 14
new CustomDate(20070501).sub(new CustomDate(20070515)); // 20070501 sub 20070515 = 14
new CustomDate(20070301).sub(new CustomDate(20070515)); // 20070301 sub 20070515 = 75
Python 3
class CustomDate:
def __init__(self, date = '00010101'):
self.date = str(date)
self.year = int(self.date[0:4])
self.month = int(self.date[4:6])
self.day = int(self.date[6:8])
self.end_of_month = [0, 31, 29 if self.is_learyear(self.year) else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
self.serial = (self.year - 1) * 365 + self.count_leapyear()
self.serial += sum([self.end_of_month[m] for m in range(1, self.month)])
self.serial += self.day
# 윤년인지 검사
def is_learyear(self, y = None):
if y is None:
y = self.year
return True if (y % 400 == 0) or (y % 4 == 0 and y % 100 != 0) else False
# 주어진 기간 사이에 윤년이 몇번 있는지 반환
def count_leapyear(self, start_y = 1, end_y = None):
if end_y is None:
end_y = self.year
return len([1 for y in range(start_y, end_y) if self.is_learyear(y)])
# return (end_y - start_y) // 4 - (end_y - start_y) // 100 + (end_y - start_y) // 400
# 마이너스(-) 연산자 오버라이드
def __sub__(self, other):
return '{} sub {} = {}'.format(self.date, other.date, abs(self.serial - other.serial))
print(CustomDate(20070515) - CustomDate(20070501)) # 20070515 sub 20070501 = 14
print(CustomDate(20070501) - CustomDate(20070515)) # 20070501 sub 20070515 = 14
print(CustomDate(20070301) - CustomDate(20070515)) # 20070301 sub 20070515 = 75
파이썬으로 짠 코드입니다
d1 = input('첫번째 날짜입력 (YYYYMMDD):') # d1, d2는 YYYYMMDD 형태의 문자열로 들어온다
d2 = input('두번째 날짜입력 (YYYYMMDD):')
year1, month1, day1 = tuple(map(int, (d1[0:4], d1[4:6], d1[6:8])))
year2, month2, day2 = tuple(map(int, (d2[0:4], d2[4:6], d2[6:8])))
# 윤년
def count_leap(y1, y2): # y1 < year < y2의 윤년 개수
year = y1 + 1
count = 0
while year < y2:
count += (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
year += 1
return count
# 월별 날짜 (윤년 포함)
def days(year, month):
if month in (1, 3, 5, 7, 8, 10, 12):
return 31
elif month in (4, 6, 9, 11):
return 30
elif month == 2:
return 28 + (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
else:
print('잘못된 숫자 입력')
# 연초부터 현재까지: 1월1일과 현재와의 차이 ex) 1월 15일 --> return 14
def before(year, month, day):
count = day - 1
for i in range(1, month):
count += days(year, i)
return count
# 전체 코드
day_diff = abs(
365 * (year2 - year1) + count_leap(year1, year2) + before(year2, month2, day2) - before(year1, month1, day1))
print('{0} sub {1} = {2}'.format(d1, d2, day_diff))
day_1 = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
day_2 = {1:31, 2:29, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
a="20200505"
b="20190601"
if int(a[:4])/4==0:
a_num = int(a[:4]) * 365 + day_2[int(a[4:6])] + int(a[6:])
else:
a_num = int(a[:4]) * 365 + day_1[int(a[4:6])] + int(a[6:])
if int(b[:4])/4==0:
b_num = int(b[:4]) * 365 + day_2[int(b[4:6])] + int(a[6:])
else:
b_num = int(b[:4]) * 365 + day_1[int(b[4:6])] + int(a[6:])
print(a_num-b_num)
4년마다 2월이 29일이라 하여 참고하여 만들었습니다. 틀리더라도 양해부탁드려요..
def subdate(d1, d2):
global day2
if d1 > d2:
d1, d2 = d2, d1
year2 = int(d2[:4])
year1 = int(d1[:4])
leaf_year = lambda year: (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
if year2 == year1:
year = year2
days = [31, 28 + leaf_year(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if int(d2[4:6]) == int(d1[4:6]):
result = (int(d2[6:]) - int(d1[6:]))
else:
result = (days[int(d1[4:6])-1] - int(d1[6:])) \
+ sum(days[int(d1[4:6]):int(d2[4:6])-1]) \
+ int(d2[6:])
else:
day3 = 0
for year in range(year1, year2+1):
days = [31, 28 + leaf_year(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if year == year1:
day1 = sum([days[d] for d in range(int(d1[4:6]), 12)]) + (days[int(d1[4:6]) - 1] - int(d1[6:]))
elif year == year2:
day2 = sum([days[d] for d in range(0, int(d2[4:6])-1)]) + int(d2[6:])
else:
day3 += sum(days)
result = day1 + day2 + day3
print('{} sub {} = {}'.format(d1, d2, result))
if __name__ == '__main__':
date1 = '20181129'
date2 = '20200314'
subdate(date1, date2)
2월은 28일로 고정!
public class calculation {
public int year,month,day;
public int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public void year_to_day(String[] a)
{
year= (Integer.parseInt(a[0])*1000 + Integer.parseInt(a[1])*100
+ Integer.parseInt(a[2])*10 + Integer.parseInt(a[3]))*365;
}
public void month_to_day(String[] a)
{
int b = Integer.parseInt(a[4])*10 +Integer.parseInt(a[5]);
int sum=0;
for(int i=0;i<b;i++)
sum += months[i];
month = sum;
}
public void day(String[] a)
{
day = Integer.parseInt(a[6])*10 + Integer.parseInt(a[7]);
}
public int total()
{
return year+month+day;
}
}
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
calculation a = new calculation();
int num_1, num_2;
String number = scan.next();
String[] num1 = number.split("");
number = scan.next();
String[] num2 = number.split("");
a.year_to_day(num1);
a.month_to_day(num1);
a.day(num1);
num_1 = a.total();
a.year_to_day(num2);
a.month_to_day(num2);
a.day(num2);
num_2=a.total();
System.out.println("날짜 차이: " + Math.abs(num_1-num_2));
}
}
4, 100, 400 윤년 고려하였으며 1000년~9999년까지 모두 계산 가능합니다. 윤년 파악 때문에 길어졌지만 크게 반복됩니다.
def sub(a,b) :
month_day = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
month_day2 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
a_year = int(a[0:4])
a_month = int(a[4:6])
a_day = int(a[6:8])
b_year = int(b[0:4])
b_month = int(b[4:6])
b_day = int(b[6:8])
year = 0
a_M = 0
b_M = 0
if a_year > b_year :
for D_year in range(b_year,a_year) :
if D_year%4 == 0 and D_year%100 != 0 :
year = year + 366
elif D_year%400 == 0 :
year = year + 366
else :
year = year + 365
if a_year%4 == 0 and a_year%100 != 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
elif a_year%400 == 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
else :
for i in range(a_month-1) :
a_M = a_M + month_day[i]
if b_year%4 == 0 and b_year%100 != 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
elif b_year%400 == 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
else :
for i in range(b_month-1) :
b_M = b_M + month_day[i]
month = a_M - b_M
day = a_day - b_day
return year + month + day
elif a_year < b_year :
for D_year in range(a_year,b_year) :
if D_year%4 == 0 and D_year%100 != 0 :
year = year + 366
elif D_year%400 == 0 :
year = year + 366
else :
year = year + 365
if a_year%4 == 0 and a_year%100 != 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
elif a_year%400 == 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
else :
for i in range(a_month-1) :
a_M = a_M + month_day[i]
if b_year%4 == 0 and b_year%100 != 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
elif b_year%400 == 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
else :
for i in range(b_month-1) :
b_M = b_M + month_day[i]
month = a_M - b_M
day = a_day - b_day
return -(-year + month + day)
elif a_month > b_month :
if a_year%4 == 0 and a_year%100 != 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
elif a_year%400 == 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
else :
for i in range(a_month-1) :
a_M = a_M + month_day[i]
if b_year%4 == 0 and b_year%100 != 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
elif b_year%400 == 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
else :
for i in range(b_month-1) :
b_M = b_M + month_day[i]
month = a_M - b_M
day = a_day - b_day
return month + day
elif a_month < b_month :
if a_year%4 == 0 and a_year%100 != 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
elif a_year%400 == 0 :
for i in range(a_month-1) :
a_M = a_M + month_day2[i]
else :
for i in range(a_month-1) :
a_M = a_M + month_day[i]
if b_year%4 == 0 and b_year%100 != 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
elif b_year%400 == 0 :
for i in range(b_month-1) :
b_M = b_M + month_day2[i]
else :
for i in range(b_month-1) :
b_M = b_M + month_day[i]
month = a_M - b_M
day = a_day - b_day
return -(month + day)
else :
return abs(a_day - b_day)
first_date = input()
second_date = input()
print(sub(first_date,second_date))
#include <iostream>
#include <vector>
using namespace std;
typedef struct _ss {
int years;
int months;
int days;
} _ss;
int year2day(int year) {
int day=0;
for(int i =0;i<year;i++) {
if (i%400==0) {
day+=366;
}
else if(i%100==0) {
day+=365;
}
else if(i%4) {
day+=366;
}
else {
day+=365;
}
}
return day;
}
int month2day(int year, int month) {
int day=0;
for(int i =1;i<month;i++) {
if(i==1 || i==3 || i== 5 || i==7 || i==8 || i==10 || i==12) {
day+=31;
}
else if(i==4 || i==6 || i==9|| i==11) {
day+=30;
}
else if(i==2) {
if(year%400==0) {
day+=29;
}
else if(year%100==0) {
day+=28;
}
else if(year%4==0) {
day+=29;
}
else {
day+=28;
}
}
}
return day;
}
int main() {
int cal[2];
_ss ss[2];
cin >> cal[0] >> cal[1];
if (cal[0]<cal[1]) {
int tmp=cal[0];
cal[0]=cal[1];
cal[1]=tmp;
}
int savecal[2];
savecal[0]=cal[0];
savecal[1]=cal[1];
for(int i=0;i<2;i++) {
ss[i].days=cal[i]%100;
cal[i]/=100;
ss[i].months=cal[i]%100;
cal[i]/=100;
ss[i].years=cal[i];
}
int a=year2day(ss[0].years)-year2day(ss[1].years);
int b=month2day(ss[0].years, ss[0].months)-month2day(ss[1].years, ss[1].months);
int c=ss[0].days-ss[1].days;
cout << savecal[0] << " sub " << savecal[1] << " = " << a+b+c << endl;
return 0;
}
/* 주어진 조건을 완벽하게는 맞지 않는 코드이지만 vector과 for문을 이용하여 간단히 해결가능 */
//주어진 조건이란 일련의 숫자를 입력할 수 있게 해주는 것. 이 코드는 하나씩 입력해야 함
month_dict = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
def subdate(a, b):
y_a, m_a, d_a = int(str(a)[:4]), int(str(a)[4:6]), int(str(a)[6:])
y_b, m_b, d_b = int(str(b)[:4]), int(str(b)[4:6]), int(str(b)[6:])
m_to_d_a, m_to_d_b = 0, 0
for i in range(1, m_a): # 1 2
m_to_d_a += month_dict[i]
for j in range(1, m_b): # 1 2
m_to_d_b += month_dict[j]
A = y_a*365 + m_to_d_a + d_a
B = y_b*365 + m_to_d_b + d_b
return abs(A-B)
print(subdate(20070515, 20070501))
print(subdate(20070501, 20070515))
print(subdate(20070301, 20070515))
def SubDate(s1 , s2):
q=[]
for i in [s1,s2]:
Y=int(i[:4])
M=int(i[4:6])
D=int(i[6:])
total=0
year = (Y-1)*365 + (Y-1)//4 - (Y-1)//100 + (Y-1)//400
total+=year
mon = [31,28,31,30,31,30,31,31,30,31,30,31]
if Y%4 ==0 and Y%100!=0 or Y%400==0:
mon[1]=29
else:
mon[1]=28
i=1
while i<M:
total+=mon[i]
i+=1
total+=D
q.append(total)
if len(q)==2:
print(abs(q[0]-q[1]))
SubDate("20200101","20210311")
def date_calculater(date1, date2):
def turn_to_total_date(date):
year = date[0:4]
month = date[4:6]
day = date[6:]
total_day = 0
for i in range(1, int(month) + 1):
if i == 2:
total_day+= 28
elif i == 4 or i == 6 or i == 9 or i == 11:
total_day += 30
else:
total_day += 31
total_day += int(day)
for i in range(1, int(year) + 1):
if i % 4 == 0:
total_day += 366
else:
total_day += 365
return total_day
date1 = turn_to_total_date(date1)
date2 = turn_to_total_date(date2)
return abs(date1 - date2)
def leaf(year):
if year%400==0 : return True
elif year%100==0:return False
elif year%4==0 :return True
else : return False
def day(date):
date = str(date)
y,m,d = map(int,(date[:4],date[4:6],date[-2:]))
month = [0,31,30,31,28+leaf(y),31,30,31,31,30,31,30,31]
days = sum(month[:m])+d
return days
def sub_day(a,b):
return day(a)-day(b)
print(sub_day(20070515,20070501))
n = input("YYYYMMDD sub YYYYMMDD 를 입력하세요")
def total (a):
year = int(a[0:4])
month = int(a[4:6])
day = int(a[6:])
sum = 0
for i in range(1,year):
if i%4==0 and i%400==0 and i%100 !=0:
sum+=366
else:
sum+=365
for m in range(1,month):
if m==2:
if year%4==0 and year%400==0 and year%100 !=0:
sum+=29
else:
sum+=28
elif m==1 or m==3 or m==5 or m==7 or m==8 or m==10 or m==12:
sum+=31
else:
sum+=30
sum +=day
return sum
def sol (n):
a = n.split(" ")[0]
b = n.split(" ")[2]
return abs(total(a)-total(b))
print(sol(n))
유년을 고려해서 total day를 구해서 그 차이를 절대값으로 반환시켰어요
// Rust
// 연월일 데이터를 (연, number of days)로 바꾸고 (예: 20070201 -> (2007, 32))
// 윤년(%400 또는 (%4 and !%100))이면 해당연도는 365+1일, 윤년의 2월은 28+1일임을 이용했습니다
fn subdate() {
let input_ = [(20070515, 20070501), (20070501, 20070515), (20070301, 20070515),
(20120101, 20130101)];
for input in input_ {
let mut start = parse_y_days(input.0);
let mut end = parse_y_days(input.1);
if start > end { let t = start; start = end; end = t;}
let mut result = 0;
if end.0 == start.0 { result = end.1 - start.1; }
else {
result += 365 - start.1 + if is_lunar(start.0) { 1} else {0};
for y in start.0+1..end.0 { result += 365 + if is_lunar(y) { 1} else {0}}
result += end.1;}
println!("{:?} sub {:?} : {}", input.0, input.1, result);
}
} fn parse_y_days(n: usize) -> (usize, usize) {
let days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; //days[month-1]
let year = n/10000;
let month = (n%10000)/100;
let day = n%100;
let mut num_days = day;
for m in 0..month-1 {
if is_lunar(year) && m==2 {num_days += 1;}
num_days += days[m];
}
(year, num_days) }
fn is_lunar(y: usize) -> bool {
y%400==0 || (y%4==0 && y%100!=0) }
a = int(input('Enter first date : '))
b = int(input('Enter second date : '))
ya = (a // 10000) % 10000
yb = (b // 10000) % 10000
ma = (a // 100) % 100
mb = (b // 100) % 100
da = a % 100
db = b % 100
d_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
min_ya = (ya - 1) * 365
min_yb = (yb - 1) * 365
min_ma = sum(d_list[:ma - 1])
min_mb = sum(d_list[:mb - 1])
min_da = da - 1
min_db = db - 1
yya = int(ya / 4) - int(ya / 100) + int(ya / 400)
yyb = int(yb / 4) - int(yb / 100) + int(yb / 400)
aa = (min_ya + min_ma + min_da + yya)
bb = (min_yb + min_mb + min_db + yyb)
print(int(((bb - aa) ** 2) ** (1 / 2))) # 절대값 비슷
# Subdate
in1, dummy, in2 = input('YYYYMMDD sub YYYYMMDD : ').split()
md = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
y1 = int(in1[:4])
m1 = int(in1[4:6])
d1 = int(in1[6:8])
y2 = int(in2[:4])
m2 = int(in2[4:6])
d2 = int(in2[6:8])
days1 = y1 * 365 + (y1 // 4) + sum(md[:m1]) + d1
days2 = y2 * 365 + (y2 // 4) + sum(md[:m2]) + d2
print(in1, dummy, in2, '=', abs(days2-days1))
파이썬 3.11입니다. 풀이가 너무 길고 뭔가 뻔한듯한 ㅠ
def Sub(a,b):
sub = 0
a1 = int(a[:4])
if int(a[4]) == 0:
a2 = int(a[5])
else:
a2 = int(a[4:6])
if int(a[6]) == 0:
a3 = int(a[7])
else:
a3 = int(a[6:8])
b1 = int(b[:4])
if int(b[4]) == 0:
b2 = int(b[5])
else:
b2 = int(b[4:6])
if int(b[6]) == 0:
b3 = int(b[7])
else:
b3 = int(b[6:8])
if a2 < b2:
for i in range(a2,b2):
if i == 2:
sub+=28
elif i==4 or i==6 or i==9 or i==11:
sub+=30
else:
sub+=31
elif a2 > b2:
for i in range(b2,a2):
if i == 2:
sub+=28
elif i==4 or i==6 or i==9 or i==11:
sub+=30
else:
sub+=31
return sub + 365*abs(a1-b1) + abs(a3-b3)
print(Sub(a,b))
def cal_days(y, m):
day = 0
for d in range(1,m+1):
if d in [1,3,5,7,8,10,12]:
day += 31
elif d ==2:
if (y % 100 != 0 and y % 4 == 0) or y % 400 == 0:
day += 29
else:
day += 28
else:
day += 30
return day
inp = input('두 날짜를 각각 입력하세요(예:20070515 20070501): ').split()
if int(inp[0])>int(inp[1]):
inp[0], inp[1] = inp[1], inp[0]
year = [int(inp[0][:4]), int(inp[1][:4])]
month = [int(inp[0][4:6]), int(inp[1][4:6])]
day = [int(inp[0][6:]), int(inp[1][6:])]
for y in range(year[0], year[1]+1):
if y == year[1]:
day[1] += cal_days(y, month[1]-1)
else:
day[1] += cal_days(y, 12)
day[0] += cal_days(year[0], month[0]-1)
print('%s sub %s = %d' %(inp[0], inp[1], day[1]-day[0]))
common_year={1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
leap_year={1:31,2:29,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
start_yyyymmdd,operator,end_yyyymmdd=input().split(' ')
start_yyyy=int(start_yyyymmdd[0:4])
start_mm=int(start_yyyymmdd[4:6])
start_dd=int(start_yyyymmdd[6:8])
end_yyyy=int(end_yyyymmdd[0:4])
end_mm=int(end_yyyymmdd[4:6])
end_dd=int(end_yyyymmdd[6:8])
yyyy_days=0
mm_days=0
dd_days=0
if operator=='sub':
if start_yyyy-end_yyyy<0:
for a in range(start_yyyy,(end_yyyy+1)):
if start_yyyy==a:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
for c in range(1,start_mm):
mm_days-=leap_year[c]
dd_days-=start_dd
else:
for b in range(1,13):
yyyy_days+=common_year[b]
for c in range(1,start_mm):
mm_days-=common_year[c]
dd_days-=start_dd
elif end_yyyy==a:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
for c in range(end_mm,13):
mm_days-=leap_year[c]
dd_days+=end_dd
else:
for b in range(1,13):
yyyy_days+=common_year[b]
for c in range(end_mm,13):
mm_days-=common_year[c]
dd_days+=end_dd
else:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
else:
for b in range(1,13):
yyyy_days+=common_year[b]
if start_yyyy-end_yyyy>0:
start_yyyy,end_yyyy=end_yyyy,start_yyyy
for a in range(start_yyyy,(end_yyyy+1)):
if start_yyyy==a:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
for c in range(1,start_mm):
mm_days-=leap_year[c]
dd_days-=start_dd
else:
for b in range(1,13):
yyyy_days+=common_year[b]
for c in range(1,start_mm):
mm_days-=common_year[c]
dd_days-=start_dd
elif end_yyyy==a:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
for c in range(end_mm,13):
mm_days-=leap_year[c]
dd_days+=end_dd
else:
for b in range(1,13):
yyyy_days+=common_year[b]
for c in range(end_mm,13):
mm_days-=common_year[c]
dd_days+=end_dd
else:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
else:
for b in range(1,13):
yyyy_days+=common_year[b]
if start_yyyy-end_yyyy==0:
for a in range(start_yyyy,(end_yyyy+1)):
if start_yyyy==a:
if (a%4)==0:
for b in range(1,13):
yyyy_days+=leap_year[b]
for c in range(1,start_mm):
mm_days-=leap_year[c]
dd_days-=start_dd
for c in range(end_mm,13):
mm_days-=leap_year[c]
dd_days+=end_dd
else:
for b in range(1,13):
yyyy_days+=common_year[b]
for c in range(1,start_mm):
mm_days-=common_year[c]
dd_days-=start_dd
for c in range(end_mm,13):
mm_days-=common_year[c]
dd_days+=end_dd
print(start_yyyymmdd,'sub',end_yyyymmdd,'=',abs(yyyy_days+mm_days+dd_days))
JAVA입니다. 생각나는 방법이 한 날짜에서 다른 날짜가 될 때까지 하루씩 더하는 것밖에 없어서 그렇게 무식하게 짰습니다.
package subdate;
public class SDate {
int year;
int month;
int date;
public SDate(String str) {
this.year = Integer.parseInt(str.substring(0, 4));
this.month = Integer.parseInt(str.substring(4, 6));
this.date = Integer.parseInt(str.substring(6));
}
void nextDate() {
int[] monthDate = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(year%4 == 0 && (year%100 != 0 || year%400 == 0)) {
monthDate[1] = 29; //윤년
}
if(monthDate[month - 1] == date) { //한 달의 마지막 날
nextMonth();
}
else {
date++;
}
}
void nextMonth() {
date = 1;
if(month == 12) {
nextYear();
}
else {
month++;
}
}
void nextYear() {
month = 1;
year++;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof SDate) {
SDate sd = (SDate) obj;
return ((sd.date == date) && (sd.month == month) && (sd.year == year));
}
else {
return false;
}
}
}
package subdate;
public class Subdate {
public static void main(String[] args) {
// TODO Auto-generated method stub
String date1 = "19000101";
String date2 = "20250117";
SDate sd1 = new SDate(date1);
SDate sd2 = new SDate(date2);
int count = 0;
while (!sd1.equals(sd2)) {
sd1.nextDate();
count++;
}
System.out.println(count);
}
}