Subdate

두 날짜(YYYYMMDD)의 차이 일수를 구하는 프로그램을 작성하시오.

※ 단, 프로그래밍 언어에서 지원하는 날짜차이를 계산하는 라이브러리는 사용하지 말것

예)

20070515 sub 20070501 = 14
20070501 sub 20070515 = 14
20070301 sub 20070515 = 75

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

31개의 풀이가 있습니다. 3 / 4 Page

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;
            }
        }
    }
}


※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

include

include

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))    



※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 31
r x 1
perl x 1
python x 10
php x 2
기 타 x 6
java x 3
cs x 1
cpp x 3
go x 1
ruby x 1
javascript x 2