|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
silicondale
Joined: 15 Mar 2007 Posts: 245 Location: Matlock, Derbyshire, UK
|
Posted: Sun Jul 29, 2018 8:57 am Post subject: Conversion from Unix timestamp (epoch) to human date/time |
|
|
I have a Unix timestamp (in fact many thousands of them) in a set of data files extracted from a robot. The format is up to 19 digits -
1529496076126711606
I need to extract the time in hours, minutes, seconds, microseconds
https://www.epochconverter.com/ will convert individual timestamps or batches, and gives details of the standard functions for various languages, but not the formula that I need to use or any link to Fortran functions that will do this. Can anybody help please?
I'm not interested in the date part (which I guess is the hard part of the computation) but not sure if the epoch string can be split neatly into data and time components. If it can, then extracting hh-mm-ss.ssssss ought to be simple.
If it helps, I know the date already, can do a back-conversion using https://www.epochconverter.com/ and subtract the date from the epoch value so that all I have left is the time. _________________ (Steve Henley) |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Sun Jul 29, 2018 3:26 pm Post subject: |
|
|
Unix timestamps as used in Unix time utilities are in units of seconds (see, e.g., http://www.cplusplus.com/reference/ctime/time_t/ ), so if your time values are in microseconds you need to make a little modification before using standard C library functions related to time. Until Year 2038 (?), Unix time values can be represented in 32 bit integers (unit: 1 second). If you have time stamps in milliseconds, that would give 13 digits, so I don't understand your "19 digits".
Here is one solution: write a short C function to convert the standard Unix time (in seconds) to hh:mm:ss, discarding the mm:dd:yyyy part, file tt.c:
Code: | extern "C" {
#include <time.h>
void LOCTIME(time_t *tt, int *hmsM){
struct tm *ts;
ts = localtime(tt);
hmsM[0]=ts->tm_hour;
hmsM[1]=ts->tm_min;
hmsM[2]=ts->tm_sec;
}
} |
You can compile this with SCC (if you use another C compiler, you would not need the extern "C"{}).
The following FTN95 program uses this function.
Code: | program disptval
implicit none
integer, parameter :: li = selected_int_kind(18)
integer hs(4)
integer(li) :: tvms = 1529496076126711606_li
integer :: tv
tv=tvms/1000
hs(4)=tvms-tv*1000_li
call loctime(tv,hs)
write(*,10)hs
10 format(2x,I2,':',I2,':',I2,'.',I3)
end program
|
CAUTION: You have to check that the input numbers are within suitable range. Otherwise, arithmetic with signed operands can give you strange (i.e., incorrect) results. |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 245 Location: Matlock, Derbyshire, UK
|
Posted: Sun Jul 29, 2018 5:10 pm Post subject: |
|
|
Many thanks for the quick and helpful reply! I wrote microseconds (hence 3 more digits) but 19 digits probably means it's actually nanoseconds!
I certainly don't need all that precision, though we have cameras that are working with very fast shutter speeds, so we may need to go to more than millisecond precision.
The data files I have already definitely have 19 digits. The first few digits clearly correspond with normal Unix timestamps, so I guess the last few simply tack some extra precision on to the seconds value. _________________ (Steve Henley) |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Jul 30, 2018 7:40 am Post subject: |
|
|
Just a guess !!
The unix date/time stamp is a continuous number (10 characters), so the last 9 characters could simply be nano seconds.
The format could just be the combination of 2 numbers
10 char : 1529496076 seconds since 1/1/1970 + ( 20/06/2018 12:01:16)
9 char : 126711606 nanoseconds.
The DOS file system date time is a different approach. It uses separate packets of bytes for each number for date (ymd) and time (hms) in 2 x 16 byte.
It records year, month, day and hour, minute and second/2 :
day = yyyyyyymmmmddddd ( year since 1980 )
time = hhhhhmmmmmmsssss ( unsigned )
This dos format is not continuous and so values can not be easily combined using addition/subtraction ( such as in changing time zones )
The DOS date will go -ve in 2044, while Unix date in late 2037. |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 245 Location: Matlock, Derbyshire, UK
|
Posted: Mon Jul 30, 2018 8:59 am Post subject: |
|
|
Good suggestion, John. That should simplify things. Of course the full 19 digits exceed the precision of any FTN95 variable types, so I'm importing these data (from a CSV file, itself converted from a binary ROSBAG file) as character strings. Certainly would save a lot of effort if I can neatly split the number as you suggest.
I was aware of the year 2038 problem in Unix, but fortunately that is way beyond the horizon of this project, which ends next year. Hadn't realised there would also be a problem with DOS dates in 2044. I also read that Japan is going to have its own millennium-bug problem next year when emperor Akihito abdicates, as their official calendar is based on the dates of their emperor's reign - and most of their software has been written since Akihito became emperor in 1989. _________________ (Steve Henley) |
|
Back to top |
|
|
John-Silver
Joined: 30 Jul 2013 Posts: 1520 Location: Aerospace Valley
|
Posted: Tue Jul 31, 2018 3:36 am Post subject: |
|
|
This is a useful site to see in action John C's hint that the last 9 digits are nanoseconds (the 10th digit changing in realtime every second).
Just go to 'Current Unix Epoch Time in milliseconds and set it running
https://www.freeformatter.com/epoch-timestamp-to-date-converter.html
The date for any timestamp can be calculated here:
https://www.freeformatter.com/epoch-timestamp-to-date-converter.html
You can tyype in Steve's example timestamp (1st 13 digits only) i.e. 1529496076126(711606) and get:- 20/06/2018, 14:01:16
There's also what's claimed to be a 'batch converter' here:-
http://unixtimestamp.50x.eu/
which, typing in Steve's full 19 digit timestamp at top of post gives:-
Sun, 29 Jul 1223162917 04:46:46 +0000sense for the year, so it appears not to be working correctly.
Anyway, isn't it possible simply to treat the 2 parts of the number seperately by reading as 2 strings (first 10 digits, then last 9 digits) then 'reading the date/time(to nearest second) from the first string and processing, then the nanoseconds from the second 9 digit 'string' and storing seperately as the nanoseconds component ? That would avoid the possibility of exceeding the max integer limit mentiond earlier with 19 digits.
... and then pray there are no Japanese calendar based dates in there, which I learned in passing somewhere could cause all sorts of problems when the emperor pops his clogs _________________ ''Computers (HAL and MARVIN excepted) are incredibly rigid. They question nothing. Especially input data.Human beings are incredibly trusting of computers and don't check input data. Together cocking up even the simplest calculation ... " |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 245 Location: Matlock, Derbyshire, UK
|
Posted: Tue Jul 31, 2018 11:08 am Post subject: |
|
|
Thanks, John. Useful websites. I think first pass, will split the number 10 / 9 digits and see how it goes!
btw I understand that the emperor has already said he intends to abdicate next April - so the Japanese have a short deadline for solving their calendar problem ! _________________ (Steve Henley) |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 245 Location: Matlock, Derbyshire, UK
|
Posted: Wed Aug 01, 2018 3:57 pm Post subject: |
|
|
Found a site with Fortran code that claims to do the job without need for any C / C++ coding.
http://computer-programming-forum.com/49-fortran/503feefc2f94f7b1.htm
Source code from Herman Knobl, #7/11 comments.
You don't need the fstat function if you're supplying an existing timestamp from another source, which is exactly what I am doing.
Preliminary tests seem to be OK. _________________ (Steve Henley) |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|