Jump to content

Lossless Seconds To Date/Time


Recommended Posts

Hey guys!

I have a problem that is giving me a headache.  Kudos to anyone with any suggestions.  I have a small subvi that needs to do the following:

input = (UINT64) nanoseconds since the start of the LabVIEW time epoch

output = (cluster) timestamp expressed as: (INT16) Julian day,  (UINT32) milliseconds since start of the day,  (UINT16) microseconds since start of the day.

 

Now, I could indeed just use the LabVIEW seconds to Date/Time VI.  However, this VI gets very lossy near the fractional second regime.  (It is using a DBL after all.)  I've tried to correct for this by doing the sub-second math myself.  See my current attempt:
 

2018-06-05_20-22-27.png

 

However, this solution still has a bad edge case.  Try the following inputs:

1528210282999999871

1528210282999999872

This shows that the "seconds" output of the LabVIEW seconds to Date/time function rolls over unexpectedly (I assume due to the lossy-ness of the function.)

 

Does anyone have any suggestions?  I could write this seconds to Date/time code from scratch myself, but I'm unfamiliar with the annoying calculation for determining number of days since the start of the LabVIEW epoch.

 

Thoughts?  Suggestions?  Thanks!

LV timestamp to SUN timestamp.vi

Edited by bjustice
Link to comment

You could probably get better results by using the quotient function you have down below as your double value, rather than doing a floating point multiply.

You can also just continue with the pattern you have followed for subsecond values divide seconds by days, days by years, and find the offset from 1904. The hard part is handling things like leap seconds.

You could try to use the seconds to date time after converting to a standard timestamp using one of these methods:

1.

The fpga timekeeper has a nanosecond to labview time conversion: https://forums.ni.com/t5/Sync-Labs/NI-TimeSync-FPGA-Timekeeper-Getting-Started/gpm-p/3543895

under /timekeeper/utilities

2.

Move the bits around and type cast yourself. Timestamp format is defined here: http://www.ni.com/tutorial/7900/en/

{
   (i64) seconds since the epoch 01/01/1904 00:00:00.00 UTC (using the Gregorian calendar and ignoring leap seconds),
   (u64) positive fractions of a second
}

Your time in ns/1E9 gives the first value

remainder of the above divide *(2^64)/(1E9) is what you need for the second value if I'm reading the document correctly, or multiplying by ~18446744074. 

you put these in a two-element cluster in the order above, and then type cast to a timestamp.

Edited by smithd
  • Like 1
Link to comment

You guys all rock!

Ok, so, for future readers, here are my lessons learned here:

  1. As you would expect, converting a U64 to a DBL yields loss of precision on the fractional seconds (near millisecond/microsecond regime).  As such, feeding the "Seconds to Date/Time Function" a DBL input will result in loss of precision on the fractional seconds output
  2. The LabVIEW "timestamp" data structure consume 16 bytes of memory, and can maintain precision at the nanosecond regime so long as I typecast the structure correctly.  (Cool!  I always assumed that the timestamp structure was a DBL under the hood.)
  3. The Seconds to Date/Time function can accept either a UINT64 or a TIMESTAMP as an input.  This yields a lossless (less lossy?) calculation.  It might even be possible that the UINT64 input option is a completely lossless calculation since there is no floating point math involved (maybe...)

 

After a bunch of unit testing and poking, I've decided to implement @infinitenothing's solution with one small tweak.  screenshot:

2018-06-10_18-50-18.png

The small tweak here is that I convert the remainder directly to microseconds as opposed to converting to seconds and then adding to the output of the Date/Time function.  This yields slightly better data.

 

Thanks again everyone.  I was banging my head against a wall for a few hours last week on this.

 

Link to comment

One extra tidbit: The Timestamp fractional part is AFIK actually limited to the most relevant 32 bits of the 64 bit unsigned integer. For your situation that should not matter at all as you still get a resolution of about 0.1 ns that way.

 

Also while the Timestamp allows a range of +- 263  or +-10E19 seconds (equals ~3*10E12 or 3 trillion years) from the LabVIEW time epoch, with a resolution of ~0.1ns, 99.9% is not even theoretical useful since calendars as we know it only exist for about 5*10E3 years. It's pretty unlikely that the Julian or Gregorian calendar will still be used in 1000 years from now.

Edited by rolfk
  • Like 1
Link to comment
56 minutes ago, ShaunR said:

We should start using the Deci calendar immediately :)

I find that a bit unwieldy, but could go for the 60 weeks year, with 6 days per week and no designated weekend, but rather a 4 day work shift. It would also solve some of the traffic problems at least to some extend as only 2 third of the population would at any moment be in the work related traffic jams, and 1 third in the usually on different times and different locations occuring weekend traffic jams.

And the first Deci calendar was the French Republican calendar, but it was very impractical and hard to memorise, with every day of the year having its own name. Napoleon abolished it quickly after taking over power, and not just because it was not his own idea :-).

Edited by rolfk
Link to comment
29 minutes ago, rolfk said:

I find that a bit unwieldy, but could go for the 60 weeks year, with 6 days per week and no designated weekend, but rather a 4 day work shift. It would also solve some of the traffic problems at least to some extend as only 2 third of the population would at any moment be in the work related traffic jams, and 1 third in the usually on different times and different locations occuring weekend traffic jams.

And the first Deci calendar was the French Republican calendar, but it was very impractical and hard to memorise, with every day of the year having its own name. Napoleon abolished it quickly after taking over power, and not just because it was not his own idea :-).

But I was promised in the 1980s that we would all be working 2 day weeks by now because of the automation. That would be a better way to solve the traffic problem ;)

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.