9 Replies Latest reply on Feb 7, 2019 1:18 PM by TimCarmichael

    How to start analysis at 6AM for different timezones?

    Roger Palmen

      Hi All,

      Just making a round to see if there are any options that i've overlooked for this challenge. I have a central PI/AF Server where i need to generate EventFrames for each day for each production site. The server is in the US and runs on US regional settings & local timezone. The sites are located across the globe, and thereby in different timezones with different DST rules. How to determine at any given time that it is 6AM at a specific site?

       

      Idea that works, but i don't like:

      • Create local tags using e.g. a Performance Equation '*'. Pro: well, it works. Con: It assumes you have control over the local server(s), any local issues with time lagging could put you one ot two minutes off, not sure how PE deals with local regional settings nor how this is translated across the systems in different timezones, and last but not least, it's a PE...

       

      Idea i do like:

       

      Any other ideas? I prefer options that are self-contained, and thus touch as few systems as possible and have as few as possible assumptions / requirements on the systems it's run on.

        • Re: How to start analysis at 6AM for different timezones?
          Rick Davin

          Hi Roger,

           

          I like the custom DR option too, but then again I am a big fan of AF SDK and quite guilty of the saying "If all you have is a hammer, then eventually everything else starts to look like nail."  But there are lots of details to work out if you choose the DR route.

           

          These analyses will have to be periodically scheduled to run every hour.  Or at least it would be easier.  Otherwise you will need to have lots of extra code for your DR to implement AFEventSource in order for an analysis to be event triggered from your DR.  Besides, just because the DR converts to a different time zone, doesn't mean the DR was triggered by some other data event.  Rather the DR is based on a wall clock somewhere, and produces a value when requested.  That is a pull, not a push, which means Periodic not Event triggered.

           

          Elaborating on things you already know, but for others to read.  Your AF Server is centrally located, and presumably this is the same server where all the analyses will execute.  The problem to overcome here is that any trigger time for analyses will be local to the AF Server, not a remote site.  Attempting to schedule with time zone offsets will not work year round due to DST transitions, again in different parts of the globe.

           

          What do you want your DR to return?  A DateTime object?  Keep in mind that it typically returns with its Kind property set to Utc or Local, but for different remote sites you would want Kind to be Unspecified.

           

          What if the DR returned an ISO 8601 string?  The problem here is parsing that string to a DateTime or AFTime object inside an analysis, and then you are back to where we were in the previous paragraph.

           

          Another option would be to have the DR return just the time portion, perhaps as a TimeSpan object.  Or maybe just return an integer representing the Hour in the remote local time.  Then your trigger just checks for 6.  This would make the conditional much easier.  Keep in mind that a remote site in Australia could return 6 but it would be 6:00 the next day in relation to a US based server.

            • Re: How to start analysis at 6AM for different timezones?
              Roger Palmen

              Hi Rick,

              Thanks for your thoughts! It indeed helps to add some more context to the problem.

               

              Indeed i would schedule the analysis to run every 15 minutes (oddities: Half Hour and 45-Minute Time Zones , so that should be good enough without being a drain on resources).

              The custom DR would return a DateTime object, Kind=Unspecified. That way i can then use standard analytics functions to pull out e.g. hours and minutes to determine if my production day started (which may be a different set of rules). I prefer that above ISO8601 strings or anythen else as i a DateTime would provide the most functionality. There might be some pitfalls, but that's why one would build and execute tests, so i think that's manegable.

               

              Only thing to tell users is for them not to start days, shifts, etc. in the middle of a DST shift... Not all problems can be solved!

                • Re: How to start analysis at 6AM for different timezones?
                  Rick Davin

                  Hi Roger,

                   

                  I've been thinking more about this.  You are smart enough to know what to test and how to test.  I don't foresee an issue with a DR returning a DateTime object as the Value property, even if the Kind is Unspecified.  What does make me curious is whether the Hour() function works on an AFTime or a DateTime object internally.  If it works off only an AFTime, then the DateTime Value would be implicitly cast to AFTime, and since had Kind==Unspecified, it would then be treated as Utc, which could throw off the calculation.

                  1 of 1 people found this helpful
                    • Re: How to start analysis at 6AM for different timezones?
                      Roger Palmen

                      Well, now to find some time between the stuffed turkey and the champagne to build and execute a test as proof of the pudding!

                      • Re: How to start analysis at 6AM for different timezones?
                        Roger Palmen

                        Finally had the priority to dig into this. Simply i take the time context provided to the DataReference, and use that to Convert the time:

                         

                        targetZone = TimeZoneInfo.FindSystemTimeZoneById(strTargetTimezone);
                        outputTime = TimeZoneInfo.ConvertTime(inputTime.UtcTime, targetZone);
                        result.Value = outputTime;
                        

                         

                        Not finished yet with testing behaviour, but some preliminary conclusions:

                        • all AFTime constructors when casted into a DateTime result in .Kind=Unspecified
                        • when the time is casted back in the last line, this is assumed to be UTC as you indicated, and shows in a DateTime attribute moved back to the client timezone.
                        • When i use the Hour function in analytics however, the Hour is interpreted differently and i get a different result.

                         

                        Example:

                        • Local timezone: UTC+1
                        • Current local time: 11:22:33
                        • Target Timezone: Greenwich Standard Time (so meaning result should be 10:22:33)
                        • Result in debugger before passing back to AF: 10:22:33, Kind=Unspecified
                        • Result as shown in PSE, datetime attribute: 11:22:33
                        • Result (Hour) as returned by the Hour() function: 10

                         

                        So your gut feeling that the implicit casting would cause issues turned out to be right! Now to experiment to find a way to return a result that is reliably cast inside AF.

                          • Re: How to start analysis at 6AM for different timezones?
                            Roger Palmen

                            Finally had the time to finish this. Essentially, i take the time from the timecontext provided, and move the time to a different timezone using TimezoneInfo.ConvertTime(). That outputs a time in datetimekind=unspecified, leading to different results in PSE and Analytics. Setting the datetimeKind to UTC ensures both PSE and Analytics make the correct assumptions on the datetime received. Configuration input is the .NET standard timezone name.

                             

                            Code snippet:

                                        //Set result value
                                        targetZone = TimeZoneInfo.FindSystemTimeZoneById(strTargetTimezone);
                                        //ConvertTime assumes first parameter = UTC if kind is unspecified (which it is...)
                                        DateTime testKind = inputTime;
                                        convertTime = TimeZoneInfo.ConvertTime(inputTime.UtcTime, targetZone); //convertTime.Kind = Unspecified
                                        outputTime = DateTime.SpecifyKind(convertTime.ToUniversalTime(), DateTimeKind.Utc);
                                        result.Value = outputTime; //outputTime.Kind = Unspecified, and this assumed to be UTC. When displayed in cast back to localtime, time is 
                            
                            1 of 1 people found this helpful
                          • Re: How to start analysis at 6AM for different timezones?
                            Roger Palmen

                            Thanks again Rick for this essential pointer!

                          • Re: How to start analysis at 6AM for different timezones?
                            TimCarmichael

                            Just now reading the thread...

                            In regards to the half hour and 45 minute time zones, being from Canada and have Newfoundland be 30 minutes off from Atlantic time, the running joke was:

                               the world will end at 3:00 PM Atlantic Standard Time, 2:30 PM in Newfoundland.