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时间应该是好的,如果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个小时。应用偏移量后,是否应用夏令时(取决于一年中的哪一天)