How can I get the difference in minutes between two dates and hours?

109 views Asked by At

The date format is dd-mm-yyyy (it's the format here in Portugal), and the hour is hh:mm. My code is this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct DateTime {
    int day, month, year, hour, minute;
};

// Function to convert date and time to minutes since midnight
int minutes_since_midnight(struct DateTime dt) {
    return dt.hour * 60 + dt.minute;
}

// Function to calculate time difference
int calculate_time_difference(char date_in[], char time_in[], char date_out[], char time_out[]) {
    struct DateTime dt1, dt2;
    sscanf(date_in, "%d-%d-%d", &dt1.day, &dt1.month, &dt1.year);
    sscanf(time_in, "%d:%d", &dt1.hour, &dt1.minute);
    sscanf(date_out, "%d-%d-%d", &dt2.day, &dt2.month, &dt2.year);
    sscanf(time_out, "%d:%d", &dt2.hour, &dt2.minute);

    // Convert date and time to minutes since midnight
    int minutes1 = minutes_since_midnight(dt1);
    int minutes2 = minutes_since_midnight(dt2);

    // Calculate total difference in minutes
    int time_difference = abs(minutes2 - minutes1);

    // Calculate day difference in minutes
    int day_difference = dt2.day - dt1.day;

    // If the date of departure is before the date of arrival, adjust the day difference
    if (day_difference < 0) {
        // Add a full day of minutes
        day_difference += 1;
        // Add the remaining hours of the departure day
        time_difference += (24 - dt1.hour) * 60 + (60 - dt1.minute);
        // Add the hours of the arrival day
        time_difference += dt2.hour * 60 + dt2.minute;
    } else {
        // If the date of departure is after the date of arrival, just add the remaining minutes
        time_difference += day_difference * 24 * 60;
    }

    return time_difference;
}

int main() {
    int time_diff = calculate_time_difference("01-01-2024", "19:05", "02-01-2024", "9:05");
    printf("Time difference->%i\n", time_diff);
    return 0;
}

As you can see from the example in main, in the case where input 1 = "01-01-2024", "19:05" and input 2 = "02-01-2024", "9:05" the time difference in minutes should be 840 (14 hours * 60 minutes). The code when I run it says: Time difference->2040. How can I fix this?

Ignore leap years for this example.

2

There are 2 answers

10
selbie On

Assuming no date comes before Jan 1, 1970 (standard epoch time). This should suffice. And if you do have pre-1970 dates, change the int year = 1970 statement below to have an initial value of 1.

The code below basically counts up the number of seconds from 1/1/1970 at midnight accounting for leap years as it goes.

Below assumes a basic understanding that:

  • Leap years have 366 days. Non leap-years have 365 days
  • Leap years usually occur on years divisible by 4, but not on years divisible by 100 unless also divisible by 400 (the year 2000 is a leap year, but the year 2100 will not).
  • That the DateTime struct will never have negative numbers, months less than 1 or greater than 12. Hours are assumed to be between 0-23 (military time). Minutes are a value between 0-59.
  • Months are assumed to be numbered between 1-12
  • Same time zone for comparing differences.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>

struct DateTime {
    int day, month, year, hour, minute;
};

const int SECONDS_IN_DAY = 86400;

int isLeapYear(int year) {
    if (year % 4) return 0;
    if (year % 400 == 0) return 1;
    if (year % 100 == 0) return 0;
    return 1;
}

int getDaysInYear(int year) {
    return isLeapYear(year) ? 366 : 365;
}

int64_t seconds_since_epoch(const struct DateTime* dt) {
    size_t days_in_month[13] = { 0, 31,28,31,30,31,30,31,31,30,31,30,31 };
    int year = 1970;
    int month = 1;
    int day = 1;
    int64_t total = 0;

    while (year < dt->year) {
        total += getDaysInYear(year) * SECONDS_IN_DAY;
        year++;
    }

    if (isLeapYear(year)) {
        days_in_month[2] = 29;
    }

    while (month < dt->month) {
        total += days_in_month[month] * SECONDS_IN_DAY;
        month++;
    }

    total += (dt->day - day) * SECONDS_IN_DAY;
    total += 60 * 60 * dt->hour; // hours to seconds
    total += 60 * dt->minute;    // minutes to seconds
    return total;
}

// Function to calculate time difference
int calculate_time_difference(char date_in[], char time_in[], char date_out[], char time_out[]) {
    struct DateTime dt1, dt2;
    sscanf(date_in, "%d-%d-%d", &dt1.day, &dt1.month, &dt1.year);
    sscanf(time_in, "%d:%d", &dt1.hour, &dt1.minute);
    sscanf(date_out, "%d-%d-%d", &dt2.day, &dt2.month, &dt2.year);
    sscanf(time_out, "%d:%d", &dt2.hour, &dt2.minute);

    // Convert date and time to seconds since epoch
    int64_t seconds1 = seconds_since_epoch(&dt1);
    int64_t seconds2 = seconds_since_epoch(&dt2);

    auto difference_in_seconds = abs(seconds1 - seconds2);
    int difference_in_minutes = difference_in_seconds / 60;
    return difference_in_minutes;
}

int main() {
    int time_diff = calculate_time_difference("01-01-2024", "19:05", "02-01-2024", "9:05");
    printf("Time difference->%i\n", time_diff);
    return 0;
}
3
chux - Reinstate Monica On

A "C" approach could use functions from <time.h>.

OP comments, but not in the question, "I cannot, this is a challenge for my software engineering degree , and I cannot use libraries any other than those I'm using". Well you can use those functions to check your work.

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

// Return error flag
bool calculate_time_difference_ref(double *diff_min, //
    const char date_in[], const char time_in[], //
    const char date_out[], const char time_out[]) {
  struct tm dt1 = { .tm_isdst = -1 };
  struct tm dt2 = { .tm_isdst = -1 };
  if (sscanf(date_in,  "%d-%d-%d", &dt1.tm_mday, &dt1.tm_mon, &dt1.tm_year) != 3) return true;
  if (sscanf(time_in,  "%d:%d", &dt1.tm_hour, &dt1.tm_min) != 2) return true;
  if (sscanf(date_out, "%d-%d-%d", &dt2.tm_mday, &dt2.tm_mon, &dt2.tm_year) != 3) return true;
  if (sscanf(time_out, "%d:%d", &dt2.tm_hour, &dt2.tm_min) != 2) return true;

  time_t t_in = mktime(&dt1);
  time_t t_out = mktime(&dt2);
  if (t_in == -1 || t_out == -1) return true;
  *diff_min = difftime(t_in, t_out)/60.0;  // Difference in minutes
  return false;
}

Note the above takes into account daylight savings time.

Use struct tm dt1 = { .tm_isdst = 0 }; to assume standard time.