Date and Time Subtraction

Well, PAC can only store 1 dimension table, and 1 data type. So yes, it is separate table.
Yes, first and 2nd column is string.
Yes, I can parse.
Do you have something like this in mind:
function (subroutine in this case) that takes two argument mm/dd/yyyy, and returns an interger.
Is this essentially what Mary’s codes does?

Thank you.

Yes, I’m aware, just verifying that it wasn’t a comma separated string in a single table.

I would parse out the month, day and year and put them into an integer table in the date/time format as specified in the PAC Control command help for the GetDateTime command. Convert this value to an int64 NTP timestamp using the DateTimeToNtpTimestamp command. Do the same with the current time. Subtract the two int64 values that the Ntp command generates and divide the result by the constant (2^32 * 86400 = 371,085,174,374,400). That should get you the difference in days.

If you can store the NTP timestamp when the work order is generated in an int64 table, that would make things simpler.

Thank you.
Sounds like the best plan.
I will develop this, and update this thread.

Regards,

@Beno Let me take this opportunity to ask.

About the solution Mary coded and Philip advised, can Codesys do these things?

How about writing to a txt file. PAC does it, can Codesys do it too?

@philip I cannot find command that gets NTP timestamp directly.
Do we usually do two steps for this: GetDateTime and DateTimeToNtpTimestamp?

Yes that is correct.

I am new to creating subroutine, is it possible to create subroutine, to call it and return current int64 NTP_TimeStamp data. This way, I do not have to use an Integer32_Table on my current strategy.

Yes, you can call GetDateTime in a subroutine using a local int32 table, and then pass that to the DateTimeToNtpTimestamp to get the int64 timestamp.

A subroutine doesn’t “return” anything, it can only act on the parameters passed to it, in your case you would pass in the int64 variable that you want the timestamp to be stored in.

Thank you philip, you are faster that support. :slight_smile:

I have 9 running charts that I want to get NTP_TimeStamp.
So I need to create 9 integer_table with 8 elements. and 9 integer64 variables.
I would run GetDateTime and followed by DateTimeToNtpTimestamp, on each charts.

I plan to use subroutine, so that, I save myself creating 9 integer_table.
Believing that, calling a subroutine will create its own instance.
But I learned that calling the same subroutine simultaneously is not a good practice.

Sounds reasonable.

:roll_eyes: Who told you that?

Doesn’t matter who told me, any experience on this?
Realizing what you said means, main purpose of subroutine will be defeated.
And it is also state on manual, that subroutine will be displayed on the command list, just like other commands - in that context you can treat subroutine like other commands…
(I now believe this is the case. And tested. Works just fine. :slight_smile: )

Cool. :sunglasses: Thank you.

Yes, you can call them from multiple charts as much as you like. Works fine, do it all the time.

1 Like

NTP Timestamp returning Negative value?

Thank you Ben for pointing out.
I multiply NTP returned by -1. (I do not know if this is right thing.)

Now is weird, latest NTP data is smaller.

NTP is unsigned,
therefore all bits are data.

PAC control is signed,
therefore treats the MSB as sign, 0 for positve and 1 for negative.

How do we tell PAC to ignore MSB?
Am I going in the right direction here?

I think its good now, I used BitClear to 63rd position:

// Get NTP Timestamp and store to [0]
nsChart = GetDateTime(nt_DateTime);
nsChart = DateTimeToNtpTimestamp(nt_DateTime, n64_temp);
//nt64_NtpReference[0] = n64_temp * -1;
nt64_NtpReference[0] = BitClear(n64_temp,63);

It is working now. :slight_smile:

Don’t do this. You don’t need to. You’ll end up with the opposite problem in about 17 years. Just take the difference of the two numbers, it will be fine.

How are you converting to minutes? The timestamp values are not in units of minutes, the most significant 32 bits are seconds, and the least significant bits are fractions of a second.

If you want to get the difference in minutes then divide the difference of the two timestamps by 2^32 * 60 - Calculate out this constant (literal) and put an i64 suffix on it, don’t use the Power function as it doesn’t support 64 bit integers.

Thank you Philip, I followed your computation.

So far it worked.

// Get NTP Timestamp and store to [0]
nsChart = GetDateTime(nt_DateTime);
nsChart = DateTimeToNtpTimestamp(nt_DateTime, n64_temp);
nt64_NtpReference[0] = BitClear(n64_temp,63);

DelaySec(310);

// Get NTP Timestamp and store to [1]
nsChart = GetDateTime(nt_DateTime);
nsChart = DateTimeToNtpTimestamp(nt_DateTime, n64_temp);
nt64_NtpReference[1] = BitClear(n64_temp,63);

// subtract NTP Timestamp
n64_DiffInMin = nt64_NtpReference[1] - nt64_NtpReference[0];

//convert to min
n64_DiffInMin = ((n64_DiffInMin * 144) / (Power(2,32) * 8640));

DelayMsec(10000);

image

Well, you sort of did.

Don’t clear bit 64 or multiply by -1, this will cause you grief in about 17 years.
I also said not to use Power with 64 bit numbers, but the documentation on this is wrong (@GrayChurch.Opto22) - in testing it seems to support returning a 64 bit integer, so that is okay. I would change it to a constant anyways and don’t forget the i64 suffix on any constants you are using with 64 bit numbers.

Slight modifications below. Should work until around 2104ish and could work beyond that if you care to test for it (overflow from 7FFFFFFFFFFFFFFF to 8000000000000000).

// Get NTP Timestamp and store to [0]
nsChart = GetDateTime(nt_DateTime);
nsChart = DateTimeToNtpTimestamp(nt_DateTime, n64_temp);
nt64_NtpReference[0] = n64_temp;

DelaySec(310);

// Get NTP Timestamp and store to [1]
nsChart = GetDateTime(nt_DateTime);
nsChart = DateTimeToNtpTimestamp(nt_DateTime, n64_temp);
nt64_NtpReference[1] = n64_temp;

// subtract NTP Timestamp
n64_DiffInMin = nt64_NtpReference[1] - nt64_NtpReference[0];

//convert to min
n64_DiffInMin = n64_DiffInMin / 257,698,037,760i64;

DelayMsec(10000);
1 Like

Thanks for the review, will modify and get back.