private static DateTime ExtractDateTime(IoffeVesselDualNavData navData)
        {
            string dateStr = navData.DateGPS.ToString();
            string timeStr = navData.curtime.ToString("D4");

            int sec = Convert.ToInt32(timeStr.Substring(timeStr.Length - 2));

            timeStr = timeStr.Substring(0, timeStr.Length - 2);
            int min = Convert.ToInt32(timeStr.Substring(timeStr.Length - 2));

            timeStr = timeStr.Substring(0, timeStr.Length - 2);
            int hour = (timeStr.Length > 0) ? (Convert.ToInt32(timeStr)) : (0);

            int year = 2000 + Convert.ToInt32(dateStr.Substring(dateStr.Length - 2, 2));

            dateStr = dateStr.Substring(0, dateStr.Length - 2);
            int month = Convert.ToInt32(dateStr.Substring(dateStr.Length - 2, 2));

            dateStr = dateStr.Substring(0, dateStr.Length - 2);
            int day = Convert.ToInt32(dateStr);

            DateTime dt = new DateTime(year, month, day, hour, min, sec, DateTimeKind.Utc);

            return(dt);
        }
        public static Tuple <DateTime, DateTime> GetNavFileDateTimeMargins(string InputFilename)
        {
            int  bytesCountPerObj = Marshal.SizeOf(typeof(IoffeVesselDualNavData));
            long fileLength       = (new FileInfo(InputFilename)).Length;

            if (fileLength < (4 + bytesCountPerObj))
            {
                return(null);
            }


            BinaryReader reader = new BinaryReader(File.Open(InputFilename, FileMode.Open, FileAccess.Read, FileShare.Read));

            char[] dualmode = reader.ReadChars(4);
            if (new string(dualmode) != "Dual")
            {
                // неправильный файл навигации - данные не в том формате
                return(null);
            }

            byte[]   buf1st    = reader.ReadBytes(bytesCountPerObj);
            GCHandle handle1st = GCHandle.Alloc(buf1st, GCHandleType.Pinned);
            IoffeVesselDualNavData record1st =
                (IoffeVesselDualNavData)
                Marshal.PtrToStructure(handle1st.AddrOfPinnedObject(), typeof(IoffeVesselDualNavData));
            DateTime dt1 = ExtractDateTime(record1st);

            reader.BaseStream.Seek(-bytesCountPerObj, SeekOrigin.End);
            byte[]   buf2nd    = reader.ReadBytes(bytesCountPerObj);
            GCHandle handle2nd = GCHandle.Alloc(buf2nd, GCHandleType.Pinned);
            IoffeVesselDualNavData record2nd =
                (IoffeVesselDualNavData)
                Marshal.PtrToStructure(handle2nd.AddrOfPinnedObject(), typeof(IoffeVesselDualNavData));
            DateTime dt2 = ExtractDateTime(record2nd);

            reader.Close();

            return(new Tuple <DateTime, DateTime>(dt1, dt2));
        }
        public static List <IoffeVesselDualNavDataConverted> ReadNavFile(string InputFilename) //, bool readOnlyThe1stRecord = false)
        {
            int bytesCountPerObj = Marshal.SizeOf(typeof(IoffeVesselDualNavData));

            if ((new FileInfo(InputFilename)).Length < (4 + bytesCountPerObj))
            {
                return(null);
            }
            BinaryReader reader = new BinaryReader(File.Open(InputFilename, FileMode.Open, FileAccess.Read, FileShare.Read));

            char[] dualmode = reader.ReadChars(4);
            if (new string(dualmode) != "Dual")
            {
                // неправильный файл навигации - данные не в том формате
                return(null);
            }
            reader.Close();

            byte[] fileData = File.ReadAllBytes(InputFilename);

            reader = new BinaryReader(new MemoryStream(fileData));
            reader.ReadChars(4);

            List <IoffeVesselDualNavData> lFileNavData = new List <IoffeVesselDualNavData>();

            int structCount = Convert.ToInt32((fileData.Count() - 4) / bytesCountPerObj);

            if (structCount == 0)
            {
                return(null);
            }
            int readStructs = 0;

            while (true)
            {
                //Stream stream = reader.BaseStream;
                long currPosition = reader.BaseStream.Position;
                try
                {
                    //char[] possibleDualModeSign = reader.ReadChars(4);
                    byte[] read4bytes           = reader.ReadBytes(4);
                    string possibleDualModeSign = System.Text.Encoding.Default.GetString(read4bytes);
                    if (possibleDualModeSign.ToLower() != "dual")
                    {
                        // вернуть позицию на 4 назад
                        //reader.BaseStream.Seek(-4, SeekOrigin.Current);
                        reader.BaseStream.Seek(currPosition, SeekOrigin.Begin);
                    }
                }
                catch (Exception ex)
                {
                    ;
                }



                byte[] readBuffer = new byte[bytesCountPerObj];
                readBuffer = reader.ReadBytes(bytesCountPerObj);
                GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
                IoffeVesselDualNavData curRecord =
                    (IoffeVesselDualNavData)
                    Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(IoffeVesselDualNavData));
                readStructs++;
                lFileNavData.Add(curRecord);
                //if ((readStructs >= structCount) || (readOnlyThe1stRecord))
                if (readStructs >= structCount)
                {
                    break;
                }
            }



            List <IoffeVesselDualNavDataConverted> lRetList = lFileNavData.ConvertAll(navData =>
            {
                IoffeVesselDualNavDataConverted retNavData = new IoffeVesselDualNavDataConverted();

                #region // -> ExtractDateTime()
                //string dateStr = navData.DateGPS.ToString();
                //string timeStr = navData.curtime.ToString("D4");
                //DateTime dt;
                //if (navData.curtime >= 2400)
                //{
                //    int daysToAdd = 0;
                //    while (navData.curtime >= 2400)
                //    {
                //        navData.curtime -= 2400;
                //        daysToAdd ++;
                //    }
                //    timeStr = (navData.curtime).ToString("D4");
                //    dt = new DateTime(2000 + Convert.ToInt32(dateStr.Substring(dateStr.Length - 2, 2)),
                //        Convert.ToInt32(dateStr.Substring(dateStr.Length - 4, 2)),
                //        Convert.ToInt32(dateStr.Substring(0, dateStr.Length - 4)),
                //        Convert.ToInt32(timeStr.Substring(0, 2)),
                //        Convert.ToInt32(timeStr.Substring(2, 2)),
                //        0);
                //    dt = dt.AddDays(daysToAdd);
                //}
                //else
                //{
                //    dt = new DateTime(2000 + Convert.ToInt32(dateStr.Substring(dateStr.Length - 2, 2)),
                //        Convert.ToInt32(dateStr.Substring(dateStr.Length - 4, 2)),
                //        Convert.ToInt32(dateStr.Substring(0, dateStr.Length - 4)),
                //        Convert.ToInt32(timeStr.Substring(0, 2)),
                //        Convert.ToInt32(timeStr.Substring(2, 2)),
                //        0);
                //}
                #endregion // -> ExtractDateTime()

                retNavData.dateTime = ExtractDateTime(navData);
                GPSdata curGPS      = new GPSdata()
                {
                    GPSstring            = "",
                    lat                  = (double)navData.Lat,
                    latHemisphere        = "" + navData.SimLat,
                    lon                  = (double)navData.Lon,
                    lonHemisphere        = "" + navData.SimLon,
                    dateTimeUTC          = retNavData.dateTime,
                    validGPSdata         = true,
                    IOFFEdataHeadingTrue = navData.trueHead,
                    IOFFEdataHeadingGyro = navData.Gyro,
                    IOFFEdataSpeedKnots  = navData.Speed,
                    IOFFEdataDepth       = navData.Depth,
                    dataSource           = GPSdatasources.IOFFEvesselDataServer
                };
                retNavData.gps    = curGPS;
                retNavData.Course = navData.Course;
                return(retNavData);
            });


            return(lRetList);
        }