How to correctly convert Unix time to FILETIME used by Win32 - unix-timestamp

Microsoft offers the following function in its support article :
// NOTE: this function is INCORRECT!
void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
ll = Int32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
However, if the Unix time "t" refers to the dates after the year 2038, this function produces an incorrect result. How to make it work properly after the year 2038?

The problem is the use of the Int32x32To64 function, because it truncates its arguments to 32-bits each. If the unix time exceeds 32 bits (as it happens for the dates after the year 2038), it produces an incorrect result. To correct the problem, use 64-bit multiplication instead of the Int32x32To64 function:
void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
ll = t * 10000000I64 + 116444736000000000I64;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
Hope this saves time someone.

Related

CAPL - Converting 4 raw bytes into floating point

CAPL - Vector.
I receive message ID 0x110 which holds current information:
0x3E6978D5 -> 0.228
Currently I can read the data and save into Enviroment Variable to show in Panel using:
putValue(slow_current, this.long(4));
But I don't know how to convert the HEX 4 bytes into float variable, since I cannot use address or casting (float* x = (float *)&vBuffer;)
How to make this conversion in CAPL script? Thanks.
Typically your dbc-file shall contain conversion info from raw value (in your case 4B long) to physical value in form of factor and offset definition:
So your physical value of current shall be calculated as follows:
phys_val = (raw_value * factor) + offset
Note: if you define negative offset then you actually subtracting it in equation above.
But it seems you don't have dbc-file so you need to figure out factor and offset by yourself (if you have 2 example raw values and know their physical equivalent then it shall be as easy as finding linear equation parameters -> y = ax + b).
CAPL shall look like this:
variables
{
float current_phys;
/* adjust below values to your needs */
float factor = 0.001
dword offset = -1000
}
on message 0x110
{
current_phys = (this.long(4) * factor) + offset;
write(current_phys);
}
Alternate solution if you don't want to force transform the value:
You define a sysvar type float(double) and use that sysvar in the panel
(link to it), instead of the envVar
or you change the type of envVar to float(double).
The translation into float will be done automatically
.
Caveat: usually this trick requires that the input number is also 8 bytes as the defined CAPL float range 8 bytes. But you have this by message payload length constraint= 8bytes.
Does not look good, but works:
received msg: 0x3E6978D5
putValue(float4byte,interpretAdFloat(this.long(4)));
float4byte = 0.23
i just reused Vinícius Oliveira solution to avoid creating environment variable. it worked
float floatvalue;
floatvalue = interpretAsFloat(HexValue);
input (HexValue) = 0x3fe20e3a
output(floatvalue() = 1.76606

How to display datetime() value up to milliseconds

I have two questions:
In the following MATLAB code x is a date time value of the format "datetime(Y,M,D,H,MI,S,MS)". The display(x) command displays '00:00:00'. However the 'if condition' displays 'Well received!' which means the real value of x is greater than 0 as opposed to '00:00:00' displayed by the display(x) command. Please suggest how I could display the full value of x up to milliseconds or microseconds.
How can I save '0000,00,00,00,00,00,200' as a date time value?
send = datetime(2016,08,31,06,01,00,00);
receive=datetime(2016,08,31,06,01,00,100);
x=receive-send;
display(x);
if (x>0)
disp('Well received!')
else
disp('Late!')
end
The solution of your first question is, that you might convert your datetime-variable to a formatted string:
disp(datestr(x,'HH:MM:SS:FFF'));
This gives you the output 00:00:00:100, because F is the symbolic identifier for milliseconds.
Furthermore it seems, datetime doesn't support milliseconds. In this case you should use the MATLAB serial date number:
http://de.mathworks.com/help/matlab/ref/datenum.html
The variable x created in your example is a duration object. You can specify the display of milliseconds (as well as smaller decimal fractions of seconds) by setting the Format property.
>> x.Format = 'hh:mm:ss.SSS';
>> display(x);
x = 00:00:00.100
This is presumably also what you want when you ask about saving '0000,00,00,00,00,00,200' as a date time value. It's not really a date and time but a duration, and can be created using the duration constructor.
>> duration(00,00,00,200,'Format','hh:mm:ss.SSS')
ans =
00:00:00.200
Most operations acting on these duration objects will work as expected, such as comparison with the > operator:
>> x > duration(00,00,00,200)
ans =
0

How to convert string to integer in JES

I am trying to do an assignment in JES a student jython program. I need to convert our student number taken as a string input variable to pass through our function i.e.
def assignment(stringID) and convert it into integers. The exact instructions are:
Step 1
Define an array called id which will store your 7 digit number as integers (the numbers you set in the array does not matter, it will be over written with your student number in the next step).
Step 2 Your student number has been passed in to your function as a String. You must separate the digits and assign them to your array id. This can do this manually line by line or using a loop. You will need to type cast each character from stringID to an integer before storing it in id.
I have tried so many different ways using the int and float functions but I am really stuck.
Thanks in advance!
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
I had to do some jython scripting for a websphere server. It must be a really old version of python it didn't have the ** operator or the len() function. I had to use an exception to find the end of a string.
Anyways I hope this saves someone else some time
def pow(x, y):
total = 1;
if (y > 0):
rng = y
else:
rng = -1 * y
print ("range", rng)
for itt in range (rng):
total *= x
if (y < 0):
total = 1.0 / float(total)
return total
#This will return an int if the percision restricts it from parsing decimal places
def parseNum(string, percision):
decIndex = string.index(".")
total = 0
print("decIndex: ", decIndex)
index = 0
string = string[0:decIndex] + string[decIndex + 1:]
try:
while string[index]:
if (ord(string[index]) >= ord("0") and ord(string[index]) <= ord("9")):
times = pow(10, decIndex - index - 1)
val = ord(string[index]) - ord("0")
print(times, " X ", val)
if (times < percision):
break
total += times * val
index += 1
except:
print "broke out"
return total
Warning! - make sure the string is a number. The function will not fail but you will get strange and almost assuredly, useless output.

binary to decimal in objective-c

I want to convert the decimal number 27 into binary such a way that , first the digit 2 is converted and its binary value is placed in an array and then the digit 7 is converted and its binary number is placed in that array. what should I do?
thanks in advance
That's called binary-coded decimal. It's easiest to work right-to-left. Take the value modulo 10 (% operator in C/C++/ObjC) and put it in the array. Then integer-divide the value by 10 (/ operator in C/C++/ObjC). Continue until your value is zero. Then reverse the array if you need most-significant digit first.
If I understand your question correctly, you want to go from 27 to an array that looks like {0010, 0111}.
If you understand how base systems work (specifically the decimal system), this should be simple.
First, you find the remainder of your number when divided by 10. Your number 27 in this case would result with 7.
Then you integer divide your number by 10 and store it back in that variable. Your number 27 would result in 2.
How many times do you do this?
You do this until you have no more digits.
How many digits can you have?
Well, if you think about the number 100, it has 3 digits because the number needs to remember that one 10^2 exists in the number. On the other hand, 99 does not.
The answer to the previous question is 1 + floor of Log base 10 of the input number.
Log of 100 is 2, plus 1 is 3, which equals number of digits.
Log of 99 is a little less than 2, but flooring it is 1, plus 1 is 2.
In java it is like this:
int input = 27;
int number = 0;
int numDigits = Math.floor(Log(10, input)) + 1;
int[] digitArray = new int [numDigits];
for (int i = 0; i < numDigits; i++) {
number = input % 10;
digitArray[numDigits - i - 1] = number;
input = input / 10;
}
return digitArray;
Java doesn't have a Log function that is portable for any base (it has it for base e), but it is trivial to make a function for it.
double Log( double base, double value ) {
return Math.log(value)/Math.log(base);
}
Good luck.

MATLAB result is inappropriate

I'm new in MATLAB, i cannot get the answer in the format that i want.
I have a basic function call, but every execution of the program gives the result in the following format :
357341279027200000/23794118819840001
It's supposed to be in decimal, for example for same execution : 15.0181.
I could not figure out why this is happening ? Can you help me, thank you !!
Type format long on the command prompt or in your script.
If that doesnt work because the value is too large, try using vpa
Note that it's just visual, internally the value computed is precise.
>d = 357341279027200000/23794118819840001
d =
15.0181
>> d * 23794118819840001 == 357341279027200000
ans =
1
>> 15.0181 * 23794118819840001 == 357341279027200000
ans =
0
Are you sure that you are not using format rat (rational). This is the reason why you may be having fractional values. If you want decimals, try format long or format long g (Long g provides the optimal length and accuracy as a decimal, up to 10 places.)