user1741137
user1741137

Reputation: 5058

utc seconds since midnight to datetime

I'm getting radar data as "tracks" and the track data indicates the number of UTC seconds since the last midnight, apparently. This is not the number of seconds since the 1st of jan 1970.

Now I want to convert that to date time, knowing that the clock on the computer could be slightly out of sync with the clock on the radar. I'll assume the radar's seconds are the reference, not the computer's. I want to convert these seconds to a full date time. Things seem to be a little tricky around midnight.

Any suggestions? I've got some ideas, but I don't want to miss anything.

I'm working with C++ Qt.

Upvotes: 6

Views: 2884

Answers (3)

zynovij
zynovij

Reputation: 195

I had the exact same problem but I'm using C#. My implementation is included here if anyone needs the solution in C#. This does not incorporate any clock drift.

DateTime UTCTime = DateTime.UtcNow.Date.AddSeconds(secondSinceMidnight);

Upvotes: -1

Joseph Quinsey
Joseph Quinsey

Reputation: 9962

//  Function to extend truncated time, given the wall time and period, all
//  in units of seconds.
//
//  Example: Suppose the truncated period was one hour, and you were
//  given a truncated time of 25 minutes after the hour. Then:
//
//  o Actual time of 07:40:00 results in 07:25:00 (07:40 + -15)
//  o Actual time of 07:10:00 results in 07:25:00 (07:10 + +15)
//  o Actual time of 07:56:00 results in 08:25:00 (07:56 + +29)

double extendTruncatedTime(double trunc, double wall, int period) {
   return wall + remainder(trunc - wall, period);
}

#define extendTruncatedTime24(t) extendTruncatedTime(t, time(0), 24 * 60 * 60)

Some commentary:

  • The units of wall are seconds, but its base can be arbitrary. In Unix, it typically starts at 1970.

  • Leap seconds are not relevant here.

  • You need #include <math.h> for remainder().

  • The period in extendTruncatedTime() is almost always twenty-four hours, 24 * 60 * 60, as per the OP's request. That is, given the time of day, it extends it by adding the year, month, and day of month, based on the 'wall' time.

  • The only exception I know to the previous statement is, since you mention radar, is in the Asterix CAT 1 data item I001/141, where the period is 512 seconds, and for which extendTruncatedTime() as given doesn't quite work.

  • And there is another important case which extendTruncatedTime() doesn't cover. Suppose you are given a truncated time consisting of the day of month, hour, and minute. How can you fill in the year and the month?

The following code snippet adds the year and month to a time derived from a DDHHMM format:

time_t extendTruncatedTimeDDHHMM(time_t trunc, time_t wall) {
   struct tm retval = *gmtime_r(&trunc, &retval);
   struct tm now    = *gmtime_r(&wall,  &now);
   retval.tm_year = now.tm_year;
   retval.tm_mon  = now.tm_mon;
   retval.tm_mon += now.tm_mday - retval.tm_mday >  15; // 15 = half-month
   retval.tm_mon -= now.tm_mday - retval.tm_mday < -15;
   return timegm(&retval);
}

As written, this doesn't handle erroneous inputs. For example, if today is July 4th, then the non-nonsensical 310000 will be quietly converted to July 1st. (This may be a feature, not a bug.)

Upvotes: 1

count0
count0

Reputation: 2621

If you can link against another lib, i'd suggest to use boost::date_time.

It seems you want to take current date in seconds from midnight (epoch) then add the radar time to it, then convert the sum back to a date time, and transform it into a string.

Using boost will help you in:

  • getting the right local time
  • calculating the date back
  • incorporating the drift into the calculation
  • taking leap seconds into account

since you'll have concept like time intervals and durations at your disposal. You can use something like (from the boost examples):

ptime t4(date(2002,May,31), hours(20)); //4 hours b/f midnight NY time
ptime t5 = us_eastern::local_to_utc(t4);
std::cout << to_simple_string(t4) << " in New York is " 
          << to_simple_string(t5) << " UTC time "
          << std::endl;

If you want to calculate the drift by hand you can do time math easily similar to constructs like this:

 ptime t2 = t1 - hours(5)- minutes(4)- seconds(2)- millisec(1);

Upvotes: 0

Related Questions