Преобразование метки времени unix в ГГГГ-ММ-ДД ЧЧ:ММ:СС

У меня есть метка времени Unix, из которой мне нужно получить отдельные значения года, месяца, дня, часа, минуты и секунды. Я никогда не был очень хорош в математике, поэтому мне было интересно, не могли бы вы, ребята, немного мне помочь :)

Приходится все делать самому (нет функций time.h). Язык С.


person Baggins    schedule 14.08.2009    source источник
comment
Какой язык? Вам разрешено использовать библиотеки SDK?   -  person Stefan Kendall    schedule 15.08.2009
comment
Вопрос помечен как C.   -  person Amber    schedule 15.08.2009


Ответы (5)


Отказ от ответственности: следующий код не учитывает високосные годы или високосные секунды [время Unix не учитывает високосные секунды. Во всяком случае, они переоценены. -Ред.]. Так же я не проверял, так что могут быть баги. Это может пнуть вашу кошку и оскорбить вашу мать. Хорошего дня.

Давайте попробуем немного псевдокода (на самом деле Python):

# Define some constants here...

# You'll have to figure these out.  Don't forget about February (leap years)...
secondsPerMonth = [ SECONDS_IN_JANUARY, SECONDS_IN_FEBRUARY, ... ]

def formatTime(secondsSinceEpoch):
    # / is integer division in this case.
    # Account for leap years when you get around to it :)
    year = 1970 + secondsSinceEpoch / SECONDS_IN_YEAR
    acc = secondsSinceEpoch - year * SECONDS_IN_YEAR

    for month in range(12):
        if secondsPerMonth[month] < acc:
            acc -= month
            month += 1

    month += 1

    # Again, / is integer division.
    days = acc / SECONDS_PER_DAY
    acc -= days * SECONDS_PER_DAY

    hours = acc / SECONDS_PER_HOUR
    acc -= hours * SECONDS_PER_HOUR

    minutes = acc / SECONDS_PER_MINUTE
    acc -= minutes * SECONDS_PER_MINUTE

    seconds = acc

    return "%d-%d-%d %d:%d%d" % (year, month, day, hours, minutes, seconds)

Если я накосячил, пожалуйста, дайте мне знать. Выполнение этого в C не должно быть слишком сложным.

person Andrew Keeton    schedule 14.08.2009
comment
Спасибо, это как раз то, что мне было нужно :) - person Baggins; 15.08.2009
comment
Я не заметил упоминания о високосных годах в приведенном выше. Стандартные функции обработки даты C очень далеки от тривиальной реализации для правильной реализации - попытка сделать это самостоятельно, как правило, не является хорошей идеей. - person ; 15.08.2009
comment
Я отредактирую ответ, чтобы было более очевидно, что это не полное решение, а просто отправная точка. Я понимаю, что изобретать велосипед обычно плохая идея, но я думаю, что мы прошли эту часть. - person Andrew Keeton; 15.08.2009
comment
Я понимаю, что это не полное решение, и я буду продолжать в том же духе. - person Baggins; 15.08.2009
comment
Ну удачи - это чертовски сложно. Хорошей книгой в этой области является The Standard C Library PJ Plauger, посвященная реализации таких библиотечных функций. - person ; 15.08.2009
comment
Есть ли какая-то причина, по которой вы делаете acc - минуты * SECONDS_PER_MINUTE вместо того, чтобы просто делать модуль? - person Joren; 22.09.2009

Вы действительно не хотите делать это вручную. Вы можете написать какой-нибудь простой код, который предполагает, что годы, месяцы, дни, часы, минуты и секунды имеют одинаковую длину (12 месяцев, 28, 30 или 31 день, 24 часа, 60 минут и 60 секунд). с неправильным ответом.

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

Я предлагаю вам взглянуть на код glibc и посмотреть, как strftime работает.


Изменить: во времени UNIX не используется дополнительная секунда.

person Kevin Panko    schedule 14.08.2009
comment
На самом деле я работаю над платформой, которая поддерживает только C и поставляется с несколькими очень простыми библиотеками. - person Baggins; 15.08.2009
comment
(не домашняя работа, я использую метку времени, чтобы сделать ее более экономичной для хранения) - person Baggins; 15.08.2009
comment
Вы знаете, где я могу найти функцию, которая может сделать преобразование для меня? - person Baggins; 15.08.2009
comment
Значит, ваша платформа не UNIX? В таком случае, почему вы используете метку времени UNIX? - person ; 15.08.2009
comment
какую метку времени я должен использовать? - person Baggins; 15.08.2009
comment
Для компактного хранения time_t очень хорош, не надо придумывать еще один. time.h является частью стандартной библиотеки C, поэтому у вас даже нет настоящего C. Просто скопируйте strftime() и все его зависимости из glibc. - person ZZ Coder; 15.08.2009

Этот формат часто называют ISO 8601, и поиск по нему может вам помочь.

person Kevin L.    schedule 14.08.2009

Вы должны были выполнить поиск - я разместил полный ответ на этот вопрос >здесь только что на днях (по крайней мере, для UTC - чтобы настроить для других часовых поясов, просто добавьте или вычтите смещение часового пояса в секундах из unixtime, прежде чем вызывать функцию).

person caf    schedule 15.08.2009

Вам не нужно заниматься математикой. Это может быть легко обработано в C следующим образом:

char *ISO_Time (
    time_t                  time
)

{
    static char             mStr[128];
    struct tm              *gmt;

    gmt = gmtime (&time);

    strftime (mStr, sizeof(mStr), "%Y-%m-%dT%H:%M:%SZ", gmt);

    return mStr;
}

Так как у вас не совсем время ISO, вам просто нужно изменить одну строку,

strftime (mStr, sizeof(mStr), "%Y-%m-%d %H:%M:%S", gmt);
person ZZ Coder    schedule 14.08.2009
comment
В вопросе не было времени.h - person Kevin Panko; 15.08.2009
comment
ой. Не понял, что я использовал time.h. Затем просто скопируйте strftime(). Это довольно сложно. Однозначно не стоит переписывать. - person ZZ Coder; 15.08.2009