Could you try using UTC time? because UTC time should be the same even they are in different time zone.
Hi, I even used the below method to convert the time into UTC
vDateTime = vDateTime.ToUniversalTime()
Still same issue, as it's considered as future data in PI.
Just to confirm, did you receive error [-11046] Target Date in Future from your PI Message Log? Detail here https://techsupport.osisoft.com/Troubleshooting/KB/3015OSI8/
It could be possible that you did not apply the localhost.tz file. Could you confirm your PI Data Archive has apply the timezone patch by following this kb https://techsupport.osisoft.com/Troubleshooting/KB/2341OSI8/
Could you show me what time is returning in the AFTime object and the vDateTime object from the interface machine?
1 of 1 people found this helpful
These lines of code:
Dim vDateTime As DateTime = Nothing
vDateTime = CType(''Local Time stamp From Interface Machine', DateTime)
are problematic. First off, a DateTime is a structure and really cannot be set to Nothing. In c#, trying to set it to null creates a compile error. VB.NET is more forgiving and could not set the vDateTime to NOthing but instead should set it to DateTime.MinValue which is 1/1/0001.
The second line has a typo using a single quote to end the string. On closer examination, it has 2 single quotes together at the start of the string to give the illusion of a double quote. From the image of the interface machine, there was no clean time stamp. There were scattered pieces of a Date, a Time, and a Time zone. So I'm really curious about what value you were passing for 'Local Time stamp From Interface Machine' . Can you show us that string? Can you also show us the Kind property of vDateTime after you assigned its value?
Why not just be direct with it? Not just to set it to Now, but use the faster and more direct UtcNow?
Dim vDateTime as DateTime = DateTime.UtcNow
But even beyond that why not just skip DateTime and go right to AFTime:
vTagValue.Timestamp = AFTime.Now
AFTime.Now calls DateTime.UtcNow under the hood.
My earlier suggestion was to just directly use AFTime.Now or DateTime.UtcNow and avoid time strings. It's still the best, most direct way.
If you insist on using time strings, I would recommend using the AFTime(String) constructor. Internally it may call DateTime.Parse() or DateTime.TryParse(). The important thing to remember with AFTime(String) constructor is that if a time string does not contain any timezone information, then the input string will be treated as Local to the client app.
Granted you could use DateTime.Parse() or DateTime.TryParse() yourself, but it does not have the same rule of treating the input string as Local. In that case, the resulting DateTime object would have Kind=Unspecified. If you insist on using time strings and setting them to be DateTime objects first, you should definitely use DateTime.Parse() or DateTime.TryParse() instead of CType(). Then most importantly, since this would have been a Local time string now considered Unspecified, you should immediately call DateTime.SpecifyKind to switch the Kind to Local. Example:
Dim vDateTime As DateTime = DateTime.SpecifyKind(DateTime.Parse(input_time_string), DateTimeKind.Local)
It helps to understand the AFTime(DateTime) constructor. If the input Kind=Local, then it is correctly honored as Local. Otherwise (meaning Kind=Utc OR Unspecified), then the DateTime is considered to be UTC.
You know your code fails because the client time string is considered in the future on the PI Data Archive. But there is a reasoning of why that happens based on the above.
- You create a DateTime object by converting a time string via CType. The resulting DateTime object will have Kind=Unspecified. This would be true even if you used DateTime.Parse.
- You create an AFTime based on that DateTime with Kind=Unspecified. Based on AFTime constructor rules, that time is considered to be UTC.
Hence your code is inputting a Local time string, saying it is Unspecified instead of Local, which sets that local time to be Utc, which now erroneously appears to be a future date. Suggestions for improvement in order of preference:
- Use AFTime.Now to get the current client time
- Use DateTime.UtcNow to get the current client time
- Use New AFTime(String) to convert local time string to AFTime.
- Use DateTime.Parse or DateTime.TryParse to convert local time string to DateTime AND immediately wrap that inside a DateTime.SpecifyKind.