14 Replies Latest reply on Sep 11, 2018 6:13 PM by Roger Palmen

    How to handle localized datetimes in PI Vision custom symbols?

    Roger Palmen

      I'm having some issues in my custom symbols. I receive some timestamps through the regular dataupdates from PI Vision, and as expected these are in the local datetime format. However passing these back into a PI Web API call the format is incorrecly parsed back and the calls fail.

       

      How to get this under control? How can i tell PI Vision to give me the data in a prescribed format?

       

      Does this post do the trick: custom date format in coresight

        • Re: How to handle localized datetimes in PI Vision custom symbols?
          Jerome Lefebvre

          I've used the moment.js library to do that:

          https://momentjs.com/

          2 of 2 people found this helpful
            • Re: How to handle localized datetimes in PI Vision custom symbols?
              Roger Palmen

              Thanks, that is quite a helpful library. I looked at globalize.js before, but that was difficult to manage in my opinition. Way to big, but also very comprehensive.

               

              I did not read through the docs yet, but does it pickup the same local settings that PI Vision uses to give me a localized datetime string?

              • Re: How to handle localized datetimes in PI Vision custom symbols?
                Roger Palmen

                I switched to moment.js to do the parsing, but i had difficulties detecting the browser language.

                I use the Quick Language Switcher extension in Chrome, and that nicely changes the date and time formats shown in PI Vision itself. But unfortunately trying to get those settings using navigator.language || navigator.userlanguage does not work as i get en-US even if i switch to e.g. nl or de settings...

                 

                But digging around in the PiVisualization.datetimeformatter.js i found PIVisualization.CurrentCulture to be used for localization of the datetime strings providing the last piece of the puzzle!

                 

                So the following code works great!:

                                //get locale setting as used by PI Vision
                                var locale = PIVisualization.CurrentCulture;
                                moment.locale(locale)
                                //determine format from language setting
                                var format = moment.localeData().longDateFormat('L') + moment.localeData().longDateFormat('LTS');
                                //Parse timestamp into moment
                                var aMoment = moment(data.Time, format);
                                //Return ISO timestamp
                                var tsISO = aMoment.toISOString();;
                
                2 of 2 people found this helpful
              • Re: How to handle localized datetimes in PI Vision custom symbols?
                Jerome Lefebvre

                hmm. That is a good question. Looking at my code again, I'm hardcoding the time format that I except from PI Vision. PI Vision does return timestamps according to a local formatting. For example, on a Japanese local, to properly grab the start time of a display I do the following:

                var timeFormat = "YYYY/MM/DDTHH:mm:ss.SSSZ"; 

                moment(timeProvider.getServerStartTime(), timeFormat); // warning: timeProvider is an undocumented API

                But, I am now thinking this might fail in a non-Japanese browser..

                 

                I will have to test this more next week to see if there is anything else that can be done.

                1 of 1 people found this helpful
                • Re: How to handle localized datetimes in PI Vision custom symbols?
                  Jerome Lefebvre

                  Actually, it is easier than that. The Date JavaScript object will correctly read the timestamps returned from PI Vision.

                  var time = new Date(data.Time);

                  scope.time = time.toISOString();

                   

                  And here is the result

                  2 of 2 people found this helpful
                  • Re: How to handle localized datetimes in PI Vision custom symbols?
                    Asle Frantzen

                    Roger and Jerome Lefebvre,

                     

                    I needed better control of date handling in my custom symbol, and most posts in misc. forums pointed to moment.js, so the choice seemed simple.

                    I implemented this but had problems immediately, and after some time I went to the Issues tracker in GibHub and created a thread. (Details there)

                     

                    I only tested this in my custom symbol before creating that thread. But I proceeded to create a simple html file with the same, simple javascript to test what I had problems with, and now it seems that something within the PIVision web app may interfer with the moment implementation.

                     

                    Basically, this works:

                    moment().format();
                    

                     

                    But this does not work:

                    var a = moment();
                    a.format(); //TypeError: a.format is not a function
                    

                     

                    Anyone seen this sort of issue? Or may know what the problem could be?

                    If the problem was an override, which was suggested on GibHub, I would expect to be directed to the overridden function while debugging. But I'm only presented with the error message...

                     

                    Thanks!

                      • Re: How to handle localized datetimes in PI Vision custom symbols?
                        Roger Palmen

                        Hmm, really odd. Not having these issues within PIV2017R2 & Chrome. The way the moment lib is loaded does not seem to be the key difference as the other method seems to work.

                        I don't really use the moment format function it turns out. You could always try to get the JS date out of the moment, and cast that into a localeString

                         

                         

                        Some of my other code snippets using moment:

                                //get locale setting as used by PI Vision
                                var locale = PIVisualization.CurrentCulture;
                                moment.locale(locale);
                                //determine format from language setting
                                var datetimeformat = moment.localeData().longDateFormat('L') + " " + moment.localeData().longDateFormat('LTS') + ".SSS";
                                //Get user locale settings
                                var thousandSeparator = (1111).toLocaleString(locale).replace(/1/g, '');
                                var decimalSeparator = (1.1).toLocaleString(locale).replace(/1/g, '');
                        
                                    //update refresh time
                                    lastGraphUpdate = moment();
                        
                        
                             chartConfig.momentNow = moment(item.Time, datetimeformat); // Parse timestamp into moment
                             chartConfig.now = chartConfig.momentNow.toDate(); //Convert to JS date
                        
                        getDataStreamURL += "?starttime=" + chartConfig.momentBOD.toISOString();