Запрос SQLite, который преобразует дату/время эпохи Unix и работает с DST в C#

Я запрашиваю и извлекаю данные из базы данных SQLite3 на С#, которая хранит дату/время в эпоху Unix.

Некоторые хранятся как количество секунд с 01.01.1970

А некоторые хранятся как количество секунд с 01.01.2001

Все в порядке, так как мой запрос может определить разницу и применить правильное преобразование даты/времени.

Однако я не могу понять, как я могу сделать это, чтобы включить летнее время.

Есть ли способ, которым я могу различать летнее время?
Также есть ли способ получить часовой пояс от времени эпохи Unix?

Запрос, который я использую, приведен ниже, любая помощь в этом была бы отличной.

string query = "SELECT case when date<978307200 then datetime(date + 978307200,'unixepoch') else datetime(date,'unixepoch') end
AS [DATE / TIME]
FROM message
ORDER BY ROWID";

person Daniel    schedule 12.04.2012    source источник


Ответы (1)


Если время, хранящееся в базе данных, указано в формате UTC, тогда вы должны обрабатывать свое время примерно так:

namespace TimeProcessing
{
    using System;
    using System.Diagnostics;
    using System.Globalization;

    class Program
    {
        static void Main(string[] args)
        {
            double timeStamp = 1000000000; // here you read real UNIX timespamp

            // get UTC time
            DateTime utc = ConvertFromUnixTimestamp(timeStamp);
            Console.WriteLine("UTC time is: {0}", utc.ToString("o", CultureInfo.CurrentCulture));


            // get local time
            DateTime local = TimeZone.CurrentTimeZone.ToLocalTime(utc);
            Console.WriteLine("Local time is: {0}", local.ToString("o", CultureInfo.CurrentCulture));

            if(Debugger.IsAttached)
            {
                Console.WriteLine("Press any key to exit..");
                Console.ReadKey();
            }
        }

        // here you implement your timestamp processing algorithm
        public static DateTime ConvertFromUnixTimestamp(double timestamp)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            return origin.AddSeconds(timestamp);
        }
    }
}

все изменения DTS будут применены автоматически. Если вам нужно преобразовать время в другой часовой пояс (не местный), алгоритм будет таким же, но вам нужно использовать TimeZoneInfo для создания часового пояса, в который вы хотите преобразовать время UTC.

person Petr Abdulin    schedule 12.04.2012
comment
под различием между DST я имею в виду запрос, указывающий разницу между тем, когда следует или не следует применять DST - person Daniel; 12.04.2012
comment
И все же я не понимаю, что вы пытаетесь сказать. Тем не менее, решение такое же. Используйте время UTC, а затем преобразуйте его в местное, если это необходимо. - person Petr Abdulin; 12.04.2012
comment
База данных, из которой я читаю, не имеет никакого контроля над тем, как что-то хранится. Таким образом, он сохраняет даты, как это было настроено. Когда я читаю их с помощью оператора SELECT в своем вопросе, он возвращает правильные даты и время в формате UTC, принятые для всех времен, в которых было летнее время, поэтому на один час вперед. Например, они отображаются как 2012/03/26 01:09:32 вместо 2012/03/26 02:09:32. - person Daniel; 12.04.2012
comment
Дата в базе данных хранится как UTC? - person Petr Abdulin; 12.04.2012
comment
@ Даниэль, ты должен указать это в своем вопросе, это важно. Смотрите мой обновленный ответ. - person Petr Abdulin; 13.04.2012