Solved

Convert time_t to DATE

Posted on 2004-08-17
9
2,020 Views
Last Modified: 2008-03-06
Hi,

I am using VC++ 6 and I have an ATL service in which I need to convert a time represented as seconds since Jan 1, 1970 into a DATE type for storage in a _variant_t. What is the easiest way to make this conversion?

Thanks,
Zaphod.
0
Comment
Question by:Z_Beeblebrox
  • 6
  • 3
9 Comments
 
LVL 7

Author Comment

by:Z_Beeblebrox
ID: 11821327
Note that I am not using MFC, so I don't think I can use COleDateTime.

Zaphod.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11821352
Try that

    DATE time_t_To_DATE(time_t t)
    {
         COleDateTime   cdt( t );
         return (DATE)cdt;
    }

Regards, Alex

0
 
LVL 7

Author Comment

by:Z_Beeblebrox
ID: 11821422
Can I use that code in a non-MFC application? I tried including afxdisp.h but that gave me the error:

#error :  WINDOWS.H already included.  MFC apps must not #include <windows.h>

Zaphod.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11821494
>> Can I use that code in a non-MFC application?

I wouldn't do that as you would have to link against MFC libraries.

DATE is a double value that has the number of days since December, 30 1899  left of the decimal point and the fractional part is the hour values.

I'll check MFC sources if there is an easy way to convert these data types.

Regards, Alex
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11821748
Ok, one step forwards, two backwards ... ;-)

const COleDateTime& COleDateTime::operator=(const time_t& timeSrc)
{
      // Convert time_t to struct tm
      tm *ptm = localtime(&timeSrc);

      if (ptm != NULL)
      {
            m_status = _AfxOleDateFromTm((WORD)(ptm->tm_year + 1900),
                  (WORD)(ptm->tm_mon + 1), (WORD)ptm->tm_mday,
                  (WORD)ptm->tm_hour, (WORD)ptm->tm_min,
                  (WORD)ptm->tm_sec, m_dt) ? valid : invalid;
      }
      else
      {
            // Local time must have failed (timsSrc before 1/1/70 12am)
            SetStatus(invalid);
            ASSERT(FALSE);
      }

      return *this;
}

And that:

AFX_STATIC BOOL AFXAPI _AfxOleDateFromTm(WORD wYear, WORD wMonth, WORD wDay,
      WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest)
{
      // Validate year and month (ignore day of week and milliseconds)
      if (wYear > 9999 || wMonth < 1 || wMonth > 12)
            return FALSE;

      //  Check for leap year and set the number of days in the month
      BOOL bLeapYear = ((wYear & 3) == 0) &&
            ((wYear % 100) != 0 || (wYear % 400) == 0);

      int nDaysInMonth =
            _afxMonthDays[wMonth] - _afxMonthDays[wMonth-1] +
            ((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);

      // Finish validating the date
      if (wDay < 1 || wDay > nDaysInMonth ||
            wHour > 23 || wMinute > 59 ||
            wSecond > 59)
      {
            return FALSE;
      }

      // Cache the date in days and time in fractional days
      long nDate;
      double dblTime;

      //It is a valid date; make Jan 1, 1AD be 1
      nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
            _afxMonthDays[wMonth-1] + wDay;

      //  If leap year and it's before March, subtract 1:
      if (wMonth <= 2 && bLeapYear)
            --nDate;

      //  Offset so that 12/30/1899 is 0
      nDate -= 693959L;

      dblTime = (((long)wHour * 3600L) +  // hrs in seconds
            ((long)wMinute * 60L) +  // mins in seconds
            ((long)wSecond)) / 86400.;

      dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);

      return TRUE;
}

Regards, Alex

0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 125 total points
ID: 11821999
Ok, that compiles and should be correct...


#include <time.h>

// You can omit the following if you have some includes that do already define that
#define NULL 0
typedef int  BOOL;
typedef unsigned short WORD;
typedef double DATE;

DATE time_t_To_DATE(time_t timeSrc)
{    
     static int monthDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
     // Convert time_t to struct tm
     tm* ptm = localtime(&timeSrc);

     if (ptm != NULL)
     {
        WORD wYear   = (WORD)(ptm->tm_year + 1900);
        WORD wMonth  = (WORD)(ptm->tm_mon + 1);
        WORD wDay    = (WORD)ptm->tm_mday;
        WORD wHour   = (WORD)ptm->tm_hour;
        WORD wMinute = (WORD)ptm->tm_min;
        WORD wSecond = (WORD)ptm->tm_sec;
        DATE dtDest;          
         // Validate year and month (ignore day of week and milliseconds)
         if (wYear > 9999 || wMonth < 1 || wMonth > 12)
              return 0.0;

         //  Check for leap year and set the number of days in the month
         BOOL bLeapYear = ((wYear & 3) == 0) &&
              ((wYear % 100) != 0 || (wYear % 400) == 0);

         int nDaysInMonth =
              monthDays[wMonth] - monthDays[wMonth-1] +
              ((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);

         // Finish validating the date
         if (wDay < 1 || wDay > nDaysInMonth ||
              wHour > 23 || wMinute > 59 ||
              wSecond > 59)
         {
              return 0.0;
         }

         // Cache the date in days and time in fractional days
         long nDate;
         double dblTime;

         //It is a valid date; make Jan 1, 1AD be 1
         nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
              monthDays[wMonth-1] + wDay;

         //  If leap year and it's before March, subtract 1:
         if (wMonth <= 2 && bLeapYear)
              --nDate;

         //  Offset so that 12/30/1899 is 0
         nDate -= 693959L;

         dblTime = (((long)wHour * 3600L) +  // hrs in seconds
              ((long)wMinute * 60L) +  // mins in seconds
              ((long)wSecond)) / 86400.;

         dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);
         return dtDest;
     }
     else
     {
         return 0.0;
     }
}

Voilà, no MFC

Regards, Alex
0
 
LVL 7

Author Comment

by:Z_Beeblebrox
ID: 11822474
Wow, that's quite a bit of code. If there is no built in function to do this (in the absence of MFC) would it not be easier to take the tm structure you obtained at the beginning and then manually populate a SYTEMTIME structure, which can then be passed into the SystemTimeToVariantTime function? This would be quite a bit simpler and easier to read. Of course, this approach didn't occur to me until I saw your code.

Zaphod.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11822561
If it works, it is good.

I assume they use the same code as above - stolen from the same AFX source ;-)

Regards, Alex


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11822865
If you know that time_t is valid you could use that function:

DATE time_t_To_DATE(time_t timeSrc)
{    
    static int monthDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
    // Convert time_t to struct tm
    tm* ptm = localtime(&timeSrc);
   
    int year   = (ptm->tm_year + 1900);
    int month  = (ptm->tm_mon + 1);
    int day    = ptm->tm_mday;
    int hour   = ptm->tm_hour;
    int minute = ptm->tm_min;
    int second = ptm->tm_sec;
    //  Check for leap year and set the number of days in the month
    BOOL bLeapYear = ((year & 3) == 0 && 
                      ((year % 100) != 0 || (year % 400) == 0));
   
    int nDaysInMonth = monthDays[month] - monthDays[month-1] +
        ((bLeapYear && day == 29 && month == 2) ? 1 : 0);
   
    // Cache the date in days and time in fractional days
    // Offset so that 12/30/1899 is 0
    long nDate= year*365L + year/4 - year/100 + year/400 +
                monthDays[month-1] + day - 693959L;  
   
    //  If leap year and it's before March, subtract 1:
    if (month <= 2 && bLeapYear)
        --nDate;
    return (double) nDate + (((long)hour * 3600L) +  // hrs in seconds
        ((long)minute * 60L) +  // mins in seconds
        ((long)second)) / 86400.;
}

But, the SystemTimeToVariantTime is a very good idea (though not from me).

Regards, Alex
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
maze travler 6 51
Want to delete all my personal data 13 137
The dreaded error 1935 with VC++ 2008 Redistributable 12 88
FMX StringGrid1->Canvas->FillRect Problem 3 127
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now