3 byte array-for time format {Hour}{Minute}{Second} - c

I am reading system time(Register: TM11), and I want to get minute data from system time.
system time is in this data format = 3 bytes:{Hour}{Minute}{Second}
I am not sure, how to extract "minute" data, using array format, C code as below.
In my C code below, i use read_register function for reading system time, and use pointer (byte*)&systime[1]) to extract "minute". -not sure this is correct way to do so.
let's say, time now is 07:48:29 AM then, TM11 will show 07,48,29
I want to extract "48", which is minute, from TM11.
time interval: 15 minute.
Time Passed = 48 % 15 = 3 minute.
Putting this calculation in the C,
byte systime[2];
//declare "systime" variable as 3 byte array and to store TM11 //
byte time_interval = 15; //time interval is 15 minute
read_register (TM11,(byte*)&systime[1]);
//let's say read data value of TM11 is, 07:48:29 AM
//"read_register"function is to read the value of TM11 register
//(byte*)&systime[1] =try to point "minute" in TM11 register, systime[1]=48
//I am not sure whether hour will store in systime[0], minute will store in systime[1],//
elaps_time = systime[1] % time_interval;
//elapsed time calculation = 48 % 15 = 3

Related

GMT subtraction on MATLAB

I'm currently working on a small project on handling time difference on MATLAB. I have two input files; Time_in and Time_out. The two files contain arrays of time in the format e.g 2315 (GMT - Hours and Minute)
I've read both Time_in' and 'Time_out on MATLAB but I don't know how to perform the subtraction. Also, I want the corresponding answers to be in minutes domain only e.g (2hrs 30mins = 150minutes)
this is one of several possible solutions:
First, you should convert your time strings to a MATLAB serial date number. If you've done this, you can do your calculation as you want:
% input time as string
time_in = '2115';
time_out = '2345';
% read the input time as datenum
dTime_in = datenum(time_in,'HHMM');
dTime_out = datenum(time_out,'HHMM');
% subtract to get the time difference
timeDiff = abs(dTime_out - dTime_in);
% Get the minutes of the time difference
timeout = timeDiff * 24 * 60;
Furthermore, to calculate the time differences correctly you also should put some information about the date in your time vector, in order to calculate the correct time around midnight.
If you need further information about the function datenum you should read the following part of the MATLAB documentation:
https://de.mathworks.com/help/matlab/ref/datenum.html
Any questions?
In a recent version of MATLAB, you could use textscan together with datetime and duration data types to do this.
% read the first file
fh1 = fopen('Time_in');
d1 = textscan(fh1, '%{HHmm}D');
fclose(fh1);
fh2 = fopen('Time_out');
d2 = textscan(fh2, '%{HHmm}D');
fclose(fh2);
Note the format specifier '%{HHmm}D' tells MATLAB to read the 4-digit string into a datetime array.
d1 and d2 are now cell arrays where the only element is a datetime vector. You can subtract these, and then use the minutes function to find the number of minutes.
result = minutes(d2{1} - d1{1})

Adding 0 at starting of int value in c

I am in WinCE7 and to get the current time, I am using GetLocalTime(&systemTime);. This function gives the value of current time. Now if the milliseconds is 81, it displays it as 81 due to which the error occurs when I subtract two time values. For ex: time1 : 12:34:13:851 & time2: 12:34:14:81. Now I need to subtract seconds and milliseconds. So using sprintf, I am extracting seconds and milliseconds and putting them in time1 & time2 :
sprintf(time1,"%d.%d",systemTime.wSeconds,systemTime.wMilliseconds)
sprintf(time2,"%d.%d",systemTime.wSeconds,systemTime.wMilliseconds)
I am converting time1 & time2 into float using atof.Now time1 is 13.851 and time2 is 14.81. The milliseconds of time2 is actually 081 but it displays 81 so while subtracting it consider it as 810 which gives wrong values.
time2--> 14.810 14.081
time1--> 13.851 13.851
-------- ---------
result 0.959(wrong) 0.23(correct)
So to remove this error I thought of counting the digits of milliseconds and if it is 2 then add 0 at starting. So I did:
double digits = (floor (log10 (abs (milliseconds))) + 1); //calculate digits
if(digits == 2) //if milliseconds contains 2 digits, we need to add 0 at starting
{
sprintf(newMS,"0%d",milliseconds); //adding 0 to milliseconds
finalMilliseconds = atoi(newMS); //newMS is in char so converting it into integer and storing the value in finalMilliseconds
}
The problem occurs here. Lets say milliseconds = 18, so newMS = 018 but finalMilliseconds is again 18.
Please suggest any other way of conversion or any other way of adding 0 at starting
According to the documentation of SYSTEMTIME from MSDN:
It is not recommended that you add and subtract values from the
SYSTEMTIME structure to obtain relative times. Instead, you should
Convert the SYSTEMTIME structure to a FILETIME structure.
Copy the resulting FILETIME structure to a ULARGE_INTEGER structure.
Use normal 64-bit arithmetic on the ULARGE_INTEGER value.
The example here will give you some idea on how to get started.
It seems to me the simplest solution is to borrow what you need.
You already have integers. If you're subtracting two systemTime values, t2 from t1, say,
if( t1.wMilliseconds < t2.wMilliseconds ) {
t1.wMilliseconds += 1000;
t1.wSeconds--;
}
Or, just perform the subtraction. If the result's wMlliseconds is negative, adjust as above.
Take care to ensure t1 > t2, though. You don't want -1.25 = 0.0 - 0.75.
Instead of putzing with strings, if you want a float, make one:
double time1 = t1.wSeconds + 0.001 * t1.wMilliseconds;
C does the conversion for you. It's faster, more direct, and less error-prone than going through strings.
Another way of dealing with these marvels of lost leading or trailing zeroes (found in time and longlat), is to right pad the string with say four zeroes .i.e your newMS+"0000", and take the leftmost four characters.
You then have a number (as text) ranging from "0000" to "9990".
Put a "1" in front of it, then you can easily and unambiguously convert to an integer between 10000 and 19990.
Then you can add and subtract as you like.
Clumsy? Yes indeed :) But I have had to do weird tricks like this when GPS longitude readings go from 11.59(funny numbers) to 12.00

algorithm for finding date in sorted array of dates

here is my problem.
I have a sorted array of dates that is stored in a circular buffer. I have a pointer to last date in buffer. There is a possibility that some dates are missing. Client requires a range of dates. If low limit date is missing, program should return first closest date that is higher then required one and vice versa for upper limit date.
Here is an example:
Dates in circular buffer (int[18]):
1,2,3,4,5,11,12,13,14,15,21,22,23,24,25,26,27,28
and if client wants from 8 to 23,
program should return 11,12,13,14,15,21,22,23.
I tried like this :
Notes:
- number between two stars is current date, and diff is number of steps to go to find 8.
- pointer can not be less then 0 or higher then 17.
{1,2,3,4,5,11,12,13,14,15,21,22,23,24,25,26,27,*28*}, diff = -20
{*1*,2,3,4,5,11,12,13,14,15,21,22,23,24,25,26,27,28}, diff = +7
{1,2,3,4,5,11,12,*13*,14,15,21,22,23,24,25,26,27,28}, diff = -5
{1,2,*3*,4,5,11,12,13,14,15,21,22,23,24,25,26,27,28}, diff = +5 -> (5/2)+1=+3<br />
(if I detect that I will just go x steps forward and x steps backward I split x in half)
{1,2,3,4,5,*11*,12,13,14,15,21,22,23,24,25,26,27,28}, diff = -3 -> (-3/2)-1 = -2
{1,2,3,*4*,5,11,12,13,14,15,21,22,23,24,25,26,27,28}, diff = 4
{1,2,3,4,5,11,12,*13*,14,15,21,22,23,24,25,26,27,28}, diff = -5
{1,2,*3*,4,5,11,12,13,14,15,21,22,23,24,25,26,27,28}, diff = +5 -> (5/2)+1=+3
If we continue like this we will get 13,3,11,4 over and over again.
Notes:
- It is only coincidence that we get 11 here. When I use some real examples, with more dates,this algorithm jumps over some other 4 (or 3) numbers.
- Dates are stored in EEPROM of uC, so reading dates take a while, and I need to find date as quick as it possible (with minimum reads).
Please help.
Set p1 to be the start of the buffer, p2 to be the end. X is what you're looking for.
If the date of p1Date is after X, return p1. If p2Date is before X return p2.
Look at the midpoint between p1 and p2, m. If mDate is after X then p1=m else p2=m.
Repeat until p1=p2.

How to accept time from the user and store them into an array in matlab?

I want to accept (say)3 time elements (for example 8:30, 8:20 & 8:00) from user and store it in an array using 'datenum'. How can i achieve that? Please help.
Assuming that you just want to prompt the user given the current day and year and you only want the current time (hours and minutes - seconds is 0), you can do the following:
dateNumArray = []; %// Store datenums here
%// Enter a blank line to quit this loop
while true
timestr = input('Enter a time: ', 's');
if (isempty(timestr))
break;
end
%// Split the string up at the ':'
%//splitStr = strsplit(timestr, ':'); %// For MATLAB R2012 and up
splitStr = regexp(timestr, ':', 'split');
%// Read in the current date as a vector
%// Format of: [Year, Month, Day, Hour, Minute, Second]
timeRead = clock;
%// Replace hours and minutes with user prompt
%// Zero the seconds
timeRead(4:6) = [str2num(splitStr{1}) str2num(splitStr{2}) 0];
%// Convert to datenum format
dateNumArray = [dateNumArray datenum(timeRead)];
end
What the above code does is that we will keep looping for user input, where the time is expected to be in HH:MM format. Note that I did not perform error checking, so it is expected that HH is between 0-23 while MM is between 0-59. You keep putting in numbers by pushing in ENTER or RETURN for each entry. It parses this as a string, splits the string up at the : character, and converts each part before and after the : character into a number. We then get the current time when each hour and minute was recorded using the clock command. This is in a 6 element vector where the year, the month, the day, the hour, the minute and the second are recorded. We simply replace the hour and minute with what we read in from the user, and zero the seconds. We finally use this vector and append this to a dateNumArray variable where each time the user writes in a time, we will append a datenum number into this array.
When you call this, here is an example scenario:
Enter a time: 8:30
Enter a time: 8:45
Enter a time: 8:00
Enter a time:
Here's the example output from above:
format bank %// Show whole numbers and little precision
dateNumArray
format %// Reset format
dateNumArray =
735778.35 735778.36 735778.33

What are some good ways to compress data across time?

I have an array of objects with time and value property. Looks something like this.
UPDATE: dataset with epoch times rather than time strings
[{datetime:1383661634, value: 43},{datetime:1383661856, value: 40}, {datetime:1383662133, value: 23}, {datetime:1383662944, value: 23}]
The array is far larger than this. Possibly a 6 digit length. I intend to build a graph to represent this array. Due to obvious reasons, I cannot use every bit of the data to build this graph (value vs time); so I need to normalize it across time.
So here's the main problem - There is no trend in the timestamp for these objects; so I need to dynamically choose slots of time in which I either average out the values or show counts of objects in that slot.
How can I calculate slots that user friendly. i.e per minute, hour, day, eight hours or so. I am looking at having a maximum of 25 slots done out of the array, which I show up on the graph.
I hope this helps get my point through.
You can convert the date/time into epoch and use numpy.histogram to get the ranges:
import random, numpy
l = [ random.randint(0, 1000) for x in range(1000) ]
num_items_bins, bin_ranges = numpy.histogram(l, 25)
print num_items_bins
print bin_ranges
Gives:
[34 38 42 41 43 50 34 29 37 46 31 47 43 29 30 42 38 52 42 44 42 42 51 34 39]
[ 1. 40.96 80.92 120.88 160.84 200.8 240.76 280.72
320.68 360.64 400.6 440.56 480.52 520.48 560.44 600.4
640.36 680.32 720.28 760.24 800.2 840.16 880.12 920.08
960.04 1000. ]
Hard to say without knowing the nature of your values, compressing values for display is a matter of what you can afford to discard and what you can't. Some ideas though:
histogram
candlestick chart
Is this JSON and the DateTimes transmitted as text?
Why not transmit the Date as a long (Int64), and use a method to convert to/from DateTime? Depending on which language you could use these implementations:
DateTime to Long in C#
Date to long using Unix timestamp in Java
That alone would save you a considerable amount of space, since strings are 16-bits per character and the long TimeStamp would be just 64 bits.

Resources