GPS在Windows Mobile CE 5.2上返回不正确的时间戳

本文关键字:返回 不正确 时间戳 Windows Mobile CE GPS | 更新日期: 2023-09-27 18:04:38

我有一台运行CE OS 5.2的摩托罗拉MC65设备。我想获得设备的有效时间;我的印象是,既然我从卫星接收到这些数据,它就会知道这个位置的正确时间……

我收到了正确的日期,但是时间差了3个小时……我是东部时区,设备有正确的时区设置,设备上的时间现在是11:56am(我知道它关闭了),GPS返回4:15PM…

这是我目前的代码,通过GPS获得时间,我利用GPS中间驱动程序从微软(https://msdn.microsoft.com/en-us/library/bb202128.aspx):

public DateTime GetGPSTime()
    {
        Boolean satsInView = false;
        Gps g = new Gps();
        g.DeviceStateChanged += new DeviceStateChangedEventHandler(g_DeviceStateChanged);
        g.Open();
        Thread.Sleep(4000);  
        if (g.Opened)
        {
            if (deviceState.ServiceState == GpsServiceState.On)
            {
                GpsPosition pos = g.GetPosition(TimeSpan.Zero); //No Delay in time
                if (pos != null)
                {
                    //First check that we have sats visible for good GPS signal.
                    if (pos.SatellitesInViewCountValid)
                    {
                        if (pos.SatellitesInViewCount >= 1)
                            satsInView = true;
                        else
                            satsInView = false;
                    }
                    if (pos.TimeValid && satsInView)
                    {
                        g.Close();
                        g.DeviceStateChanged -= g_DeviceStateChanged;
                        return pos.Time; //Returned time obtained from GPS Obj
                    }
                }
                g.Close();
                g.DeviceStateChanged -= g_DeviceStateChanged;
                return Helper.GetSystemTimeToNow(); //If GPS obj is null, return current system time.
            }
        }
        g.Close();
        g.DeviceStateChanged -= g_DeviceStateChanged;
        return Helper.GetSystemTimeToNow(); //If GPS obj is null, return current system time.
    }

另外,这里是官方微软中级GPS代码示例的方法。这个方法由上面的代码GpsPosition pos = g.GetPosition(TimeSpan.Zero);

调用
 /// <summary>
        /// Get the position reported by the GPS receiver that is no older than
        /// the maxAge passed in
        /// </summary>
        /// <param name="maxAge">Max age of the gps position data that you want back. 
        /// If there is no data within the required age, null is returned.  
        /// if maxAge == TimeSpan.Zero, then the age of the data is ignored</param>
        /// <returns>GpsPosition class with all the position details</returns>
        public GpsPosition GetPosition(TimeSpan maxAge)
        {
            GpsPosition gpsPosition = null;
            if (Opened)
            {
                // allocate the necessary memory on the native side.  We have a class (GpsPosition) that 
                // has the same memory layout as its native counterpart
                IntPtr ptr = Utils.LocalAlloc(Marshal.SizeOf(typeof(GpsPosition)));
                // fill in the required fields 
                gpsPosition = new GpsPosition();
                gpsPosition.dwVersion = 1;
                gpsPosition.dwSize = Marshal.SizeOf(typeof(GpsPosition));
                // Marshal our data to the native pointer we allocated.
                Marshal.StructureToPtr(gpsPosition, ptr, false);
                // call native method passing in our native buffer
                int result = GPSGetPosition(gpsHandle, ptr, 500000, 0);
                if (result == 0)
                {
                    // native call succeeded, marshal native data to our managed data
                    gpsPosition = (GpsPosition)Marshal.PtrToStructure(ptr, typeof(GpsPosition));
                    if (maxAge != TimeSpan.Zero)
                    {
                        // check to see if the data is recent enough.
                        if (!gpsPosition.TimeValid || DateTime.Now - maxAge > gpsPosition.Time)
                        {
                            gpsPosition = null;
                        }
                    }
                }
                else if (result == 87) // ERROR_INVALID_PARAMETER)
                {
                    // 
                    // TEMPORARY HACK
                    // 
                    //  http://blogs.msdn.com/cenet/archive/2007/12/06/gpsid-problem-workaround-on-recent-wm6-release.aspx
                    // 
                    Utils.LocalFree(ptr);
                    // allocate the necessary memory on the native side.  We have a class (GpsPosition) that 
                    // has the same memory layout as its native counterpart
                    ptr = Utils.LocalAlloc(376);
                    // fill in the required fields 
                    gpsPosition = new GpsPosition();
                    gpsPosition.dwVersion = 1;
                    gpsPosition.dwSize = 376;
                    // Marshal our data to the native pointer we allocated.
                    Marshal.StructureToPtr(gpsPosition, ptr, false);
                    // call native method passing in our native buffer
                    result = GPSGetPosition(gpsHandle, ptr, 500000, 0);
                    if (result == 0)
                    {
                        // native call succeeded, marshal native data to our managed data
                        gpsPosition = (GpsPosition)Marshal.PtrToStructure(ptr, typeof(GpsPosition));
                        if (maxAge != TimeSpan.Zero)
                        {
                            // check to see if the data is recent enough.
                            if (!gpsPosition.TimeValid || DateTime.Now - maxAge > gpsPosition.Time)
                            {
                                gpsPosition = null;
                            }
                        }
                    }
                }
                // free our native memory
                Utils.LocalFree(ptr);
            }
            return gpsPosition;          
        }

GPS在Windows Mobile CE 5.2上返回不正确的时间戳

GPS时间应该是好的,如果GPS位置。validField表示时间是有效的。

GPS时间总是UTC。设置系统时间是唯一的方法,系统时间也总是UTC。由于将系统时间从夏令时时间范围内设置到夏令时时间范围外(反之亦然)有一个奇怪的现象,因此系统时间应该始终设置两次!详情请看我的博客…

    private void SetTimeToGPS(DateTime UTCtime)
    {
        if (m_SetTime)
        {
            // Get the local time zone and a base Coordinated Universal 
            // Time (UTC).
            TimeZone localZone = TimeZone.CurrentTimeZone;
            DateTime baseUTC = UTCtime; // new DateTime(2000, 1, 1);
            System.Diagnostics.Debug.WriteLine("'nLocal time: {0}'n",
                localZone.StandardName);
            // Calculate the local time and UTC offset.
            DateTime localTime = localZone.ToLocalTime(baseUTC);
            TimeSpan localOffset =
                localZone.GetUtcOffset(localTime);
            System.Diagnostics.Debug.WriteLine(string.Format("{0,-20:yyyy-MM-dd HH:mm}" +
                "{1,-20:yyyy-MM-dd HH:mm}{2,-12}{3}",
                baseUTC, localTime, localOffset,
                localZone.IsDaylightSavingTime(localTime)));
            //adjust the clock
            //localTime += localOffset;
            PInvokeLibrary.SystemTimeLib.SetTime(localTime);
            m_SetTime = false;
        }
    }

代码是我的GpsSample8演示在https://github.com/hjgode/win-mobile-code/blob/master/gps8/Gps8/GPS_Sample8/GPSForm1.cs

当用时间测试时,请注意从GPS (UTC)获得的时间,以及在将SystemTime设置为GPS时间两次后设备对SystemTime和LocalTime的显示。

顺便说一句:美国东部时间比UTC晚5个小时,而不是3个小时。应用偏移量后,是否应用夏令时(取决于一年中的哪一天)