Example #1
0
        public DateTime?GetDate(string name, KdbxSerializationParameters parameters, bool required = false)
        {
            string dtString = GetString(name, required);

            if (String.IsNullOrEmpty(dtString))
            {
                return(null);
            }

            // KeePass interop weirdness - they trim the UTC timezone specifier off, then parse,
            // then convert to local time. When serializing they convert back to UTC and add the "Z".
            // Can't say why, but mimicing the behavior to avoid bugs.
            if (dtString.EndsWith("Z"))
            {
                dtString = dtString.Substring(0, dtString.Length - 1);
            }

            DateTime dt;

            if (DateTime.TryParse(dtString, out dt))
            {
                dt = dt.ToLocalTime();
                return(dt);
            }
            else if (parameters.UseBase64DateTimeEncoding)
            {
                // Try to parse the DateTime as a base64 string
                IBuffer data = CryptographicBuffer.DecodeFromBase64String(dtString);
                if (data.Length == 8)
                {
                    long elapsedSeconds = (long)ByteHelper.BufferToLittleEndianUInt64(data.ToArray(), 0);
                    return(new DateTime(elapsedSeconds * TimeSpan.TicksPerSecond, DateTimeKind.Utc));
                }
            }

            // This used to be a parse failure, but due to the strangeness of parsing dates, and because KeePass only considers
            // this an assertion failure with a fallback, we will also fallback.
            DebugHelper.Assert(false, $"Investigate why this DateTime failed to parse: {dtString}");
            return(DateTime.Now);
        }