-1

I need to get input from user in string (for example 20.10.2020) and add 7 days to it. So far, I have something like that but do not know how what to do next.

This is whatI have so far:

   #include <stdio.h>

static int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int day, month, year;

unsigned short day_counter;

int is_leap(int y) {
    return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
}

void next_day()
{
    day += 1; day_counter++;
if (day > days_in_month[month]) {
    day = 1;
    month += 1;
    if (month > 12) {
        month = 1;
        year += 1;
        if (is_leap(year)) {
            days_in_month[2] = 29;
        } else {
            days_in_month[2] = 28;
        }
    }
}
}

void set_date(int d, int m, int y) 
{
m < 1 ? m = 1 : 0;
m > 12 ? m = 12 : 0;
d < 1 ? d = 1 : 0;
d > days_in_month[m] ? d = days_in_month[m] : 0;
if (is_leap(y)){
    days_in_month[2] = 29;
} else {
    days_in_month[2] = 28;
}
day = d;
month = m;
year = y;
}

void skip_days(int x)
{
    int i;
    for (i=0;i<x;i++) next_day();
}

void print_date()
{
    printf (" %d.%d.%d\n", day, month, year);
}

    int main(int argc, char **argv)
    {
    int i;

    set_date(5, 2, 1980);

    skip_days(7);
    day_counter = 0;

    print_date();

    return 0;
} 
Filburt
  • 17,626
  • 12
  • 64
  • 115
  • 4
    The code in `set_date()` does not do what you think it does. The first line sometimes sets `m`. The `: 0` bit is pointless. Use `if` statements. The ternary conditional operator has uses. This is not one of them. – Jonathan Leffler Mar 20 '21 at 13:50
  • 1
    An array called `daysInMonth` that has 13 entries, the first of which is zero is enough to make me run away. But not before saying I immediately thought of adding the equivalent of 7 days to the unix timestamp for the given time. Something like this: https://stackoverflow.com/questions/11765301/how-do-i-get-the-unix-timestamp-in-c-as-an-int – enhzflep Mar 20 '21 at 13:56
  • With any calculations related to time, convert to a reasonable format. Once you have the epoch time, calculations are trivial. – William Pursell Mar 20 '21 at 14:40
  • 1
    time_t a; struct tm b; // Fill b with user's date. b.tm_year = 2021; b.tm_mon = 2; a = mktime(&b);. // Transform b in seconds since epoch a += (7 * 24 * 3600); // Add 7 days strftime(...); strftime() converts the date and time information from a given calendar time to a null-terminated multibyte character string str according to format string format. strftime() is the sprintf() function for date and time. Remove the comments to compile the code. – Enrico Migliore Mar 20 '21 at 16:22
  • 1
    Make your life easier - use the epoch -https://www.epochconverter.com/programming/c – Ed Heal Mar 20 '21 at 16:22

1 Answers1

1

You needn't reinvent the wheel. A very good suggestion in the comments is to use the standard functions mktime and strftime, although the given snippet might leave some members of the tm structure uninitialized and distort the result, and although it is for your purpose not necessary to bother with the epoch. When we use

struct tm
{
    …
    int tm_mday;    // day of the month — [1, 31]
    int tm_mon;     // months since January — [0, 11]
    int tm_year;    // years since 1900
    …
}

we can take advantage of the circumstance that the original values of these components are not restricted to the ranges indicated above. On successful completion, the values are forced to the ranges indicated above. This means mktime takes care of overflows into the next month or year. So, your whole program can be reduced to:

#include <stdio.h>
#include <time.h>

int main(int argc, char **argv)
{
    int d, m, y;
    // get date input from user on the command line
    if (argc < 2 || sscanf(argv[1], "%d.%d.%d", &d, &m, &y) < 3) return 1;
    // put that into the time structure, adding 7 days
    struct tm date = { .tm_mday = d+7, .tm_mon = m-1, .tm_year = y-1900 };
    // force to the ranges
    mktime(&date);

    char s[11];
    strftime(s, sizeof s, "%d.%m.%Y", &date);
    puts(s);
}
Armali
  • 18,255
  • 14
  • 57
  • 171