Difficulties with numeric date offset in luxon

707 views Asked by At

Environment: Win 10 Pro, Chrome 85, luxon 1.25.0

What I am trying to achieve eventually is this: in an ASP.Net/c# application show to the user continuously the amount of time until a session time out will occur. Because server and client may be in different time zones I need the UTC offset of each. The client's offset is easy to get. To find the server's offset (with reference to the code snippet below): the server code puts the page last loaded time into lblLastLoaded. Object dto receives the parsed date parts, including dto.offset which, I gather, is supposed to be expressed in minutes. The subsequent call to luxon.DateTime.fromObject(dto) fails: pst is left undefined. When I do not set dto.offset (by commenting out 4 lines in the code below) pst gets the server time successfully, but without the offset; it appears that luxon uses the offset of my local system which is -7 hours.

    <script>
        function r4onload() {
            // Get server time:
            var st = document.getElementById('lblLastLoaded').innerHTML;
            //             Date       Time     Offset
            // st has form YYYY/MM/dd HH:mm:ss -HH:mm
            //                       1         2
            //             012345678901234567890123456
            // For Example 2020/09/29 10:31:56 -07:00
            let dto = {};
            dto.year = Number(st.substring(0, 4));
            dto.month = Number(st.substring(5, 7));
            dto.day = Number(st.substring(8, 10));
            dto.hour = Number(st.substring(11, 13));
            dto.minute = Number(st.substring(14, 16));
            var offsetHour = Number(st.substring(20, 23)); //                        works if these 4 lines are commented out
            var offsetMinutes = Number(st.substring(24, 26)); //                     works if these 4 lines are commented out
            dto.offset = offsetHour * 60 + Math.sign(offsetHour) * offsetMinutes; // works if these 4 lines are commented out
            // dto.offset is correctly calculated to -420 minutes //                 works if these 4 lines are commented out
            var pst = luxon.DateTime.fromObject(dto);
            // pst is undefined at this point -- why??
            // If I do not include anything about offset above (comment out the 4 lines 
            //    containing offsetHours, offsetMinutes, and dto.Offset, then pst comes out like this:
            //    2020-09-29T10:31:00.00000-07:00
            //    i.e., luxon used the offset -07:00 of my local system, not the one contained in variable st.
            document.getElementById('Parsed').innerHTML = pst;
            r4startTime();
        }
        function r4startTime() {
            var dt = luxon.DateTime.local();
            var h = dt.hour;
            var m = dt.minute;
            var s = dt.second;
            m = r4checkTime(m);
            s = r4checkTime(s);
            document.getElementById('CurrTime').innerHTML =
                h + ":" + m + ":" + s;
          var t = setTimeout(r4startTime, 2000);
        }
        function r4checkTime(i) {
          if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
          return i;
        }
    </script>

A complete Visual Studio 2017 project DemoLuxon with the above code snippet in file Site.Master is here: https://1drv.ms/u/s!AvoFL8QrGVaTsQvbaB8-Zh7GdloV?e=ODjZW5

If the above approach is awkward, I would be grateful for suggestions of more elegant ways of determining the client/server offset difference.

1

There are 1 answers

0
r4r4 On

I devised a workaround as follows below, but the original problem has not been answered:

    <script>
        function r4onload() {
            var st = document.getElementById('lblLastLoaded').innerHTML;
            //             Date       Time     Offset
            // st has form YYYY/MM/dd HH:mm:ss -HH:mm
            //                       1         2
            //             012345678901234567890123456
            // For Example 2020/09/29 10:31:56 -07:00
            // Transform to ISO format:
            st = st.substring(0, 4) + '-' + st.substring(5, 7) + '-' + st.substring(8, 10)
                + 'T' + st.substring(11, 19) + ".000" + st.substring(20);
            document.getElementById('Xformed').innerHTML = st;
            var pst = luxon.DateTime.fromISO(st, { setZone: true });
            document.getElementById('Parsed').innerHTML = pst;
            r4startTime();
        }
        function r4startTime() {
            var dt = luxon.DateTime.local();
            var h = dt.hour;
            var m = dt.minute;
            var s = dt.second;
            m = r4checkTime(m);
            s = r4checkTime(s);
            document.getElementById('CurrTime').innerHTML =
                h + ":" + m + ":" + s;
          var t = setTimeout(r4startTime, 2000);
        }
        function r4checkTime(i) {
          if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
          return i;
        }
    </script>

i.e., put the date-time first into ISO format and then use luxon.DateTime.fromISO. Variable pst gets the correct date-time value including the offset. The problem with luxon.DateTime.fromObject with an offset remains unresolved.