Home > Software engineering >  Coming dates in C
Coming dates in C

Time:01-06

I have the following code, with which I get today's date. I would like to know if from this code I can obtain the date 6 and 12 months later. Or how can I get these dates?

Thank you!

#include <iostream>
#include <ctime>

using namespace std;

int main() {
    time_t hoy = time(0);
    char* fecha = ctime(&hoy);
    
    cout << "La fecha es: " << fecha << endl;
}

I try to make a program with which the user planned the fertilization period of certain plants, among other things, that is why I try to make the program print the date of the next 6 and 12 months, from today (well, from the day in which the user registers a plant). So far I have not succeeded. :(

CodePudding user response:

Since it seems that you only need a rough approximation of the future date for your use-case, you can probably get by with simply assuming that every month has about 30.4 days in it, and calculating a number of seconds into the future based on that. You can then use ctime() to generate a new date-string for that future time:

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

int main(int argc, const char ** argv)
{
   const time_t now = time(NULL);

   // Assuming every month has ~30.4 days; that's not really true
   // but it's close enough for plant fertilization purposes, I think
   const time_t ROUGHLY_ONE_MONTH_IN_SECONDS = (30*24*60*60)   (10*60*60);

   for (int i=0; i<=12; i  )
   {
      const time_t then = (now (i*ROUGHLY_ONE_MONTH_IN_SECONDS));
      printf("In %i months, the approximate date/time will be:  %s", i, ctime(&then));
   }

   return 0;
}

Note that for an exact answer you'd need to take the varying lengths of months into account, plus leap years and God-only-knows-what-else, and in that case you'd probably be better off using a modern date/time library instead.

CodePudding user response:

I would use struct tm and convert your time_t using gmtime.

Then you can add 6 or 12 to tm_mon (don't forget to handle the overflow by adding 1 to tm_year), and convert back to time_t with mktime

CodePudding user response:

If you want 6 months from a given date, counting months and not days,

#include <stdint.h>
#include <stdio.h>

time_t add_months( time_t from_date, uint32_t months ) {
    // Split date
    struct tm date;
    gmtime_r( &from_date, &date );

    // Save original date
    struct tm org = date;

    // Add months/years
    uint32_t years = months/12;
    months = months % 12;
    date.tm_year  = years;
    date.tm_mon  = months;

    // Correct for year wrap
    if ( date.tm_mon>11 ) { 
        date.tm_mon -= 12;
        date.tm_year  = 1;
    }

    // Convert back to time_t
    time_t dt = mktime( &date );

    // Check for end of month wrap
    if ( date.tm_mday != org.tm_mday ) {
        dt -= date.tm_mday * 86400;
    }
    return dt;
}

int main() {
    time_t now = time(nullptr);
    time_t later = add_months( now, 6 );

    struct tm nowtm;
    struct tm latertm;
    gmtime_r( &now, &nowtm );
    gmtime_r( &later, &latertm );
    printf( "Now: %s\n", asctime(&nowtm));
    printf( "Later: %s\n", asctime(&latertm));
}

Result:

Program stdout
Now: Thu Jan  6 01:47:07 2022
Later: Wed Jul  6 01:47:07 2022

Godbolt: https://godbolt.org/z/dP1c4W5Ed

CodePudding user response:

Try Boost date time library? Easy to use,doesnot have to learn time conversions or anything else,focus on what you want to do.

#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>

int
main(int argc, char* argv[])
{

    using namespace boost::gregorian;

    try {
        //Read ISO Standard(CCYYMMDD) and output ISO Extended
        std::string ud("20011009"); //2001-Oct-09
        date d1(from_undelimited_string(ud));
        std::cout << "date is="<<to_iso_extended_string(d1) << std::endl;
        {
            boost::gregorian::months monthObj(6);
            date d2(d1   monthObj);
            std::cout << "date  6 month later is=" << to_iso_extended_string(d2) << std::endl;
        }
        {
            boost::gregorian::months monthObj(12);
            date d2(d1   monthObj);
            std::cout << "date  12 month later is=" << to_iso_extended_string(d2) << std::endl;
        }
    }
    catch (std::exception& e) {
        std::cout << "  Exception: " << e.what() << std::endl;
    }


    return 0;
}

CodePudding user response:

Some ideas: time_t represents the total number of seconds from Jan 1, 1970 UTC. Could just add the total number of seconds to offset it? Possibly cast to a long int?

  •  Tags:  
  • Related