VIDEOCHAT  ::   FAQ  ::   Поиск  ::   Регистрация  ::   Вход

Элементарная задачка для программиста

Раздел для разработчиков для обсуждения программных и аппаратных продуктов и их реализации.

Модераторы: april22, Zavr2008

tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Элементарная задачка для программиста

Сообщение tma »

Всем привет.
Потратил несколько часов и не смог решить, хреновый из меня программист. ;(
Нужно Cisco vsa time format: "18:27:28.032 UTC Wed Dec 9 1998" преобразовать в unix time с учетом таймзоны на Си (под Unix).
Функция strptime не подходит -- она не понимает миллисекунды.
Вот еще образцы: "21:04:33.433 MSK Sat Nov 05 2011" и "21:04:33.433 +0300 Sat Nov 05 2011".

Кто может выручить?
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Спасибо, нашел вариантик по ссылке.
Хотя это я уже вчера все прошел. Не выходит именно таймзона. ;(
Получаю в MSK, выход в UTC, а время в результате тоже самое, что и в MSK. :cry:
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Уточню свой вопрос - нужно по аббревиатуре таймзоны определить смещение в секундах от UTC используя tzdata. Как?
Перерыл уже все, что только возможно.
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Если б это было так просто...

Представим, что у меня есть дата до перехода на зимнее время и через 1 час еще одна запись.
Время у них будет одинаковое, а таймзона разная. Мне нужно обе даты перевести в UTC.

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

Время же приходит в разных таймзонах, нужно по аббревиатуре перевести его в смещение в секундах...
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

ddkprog писал(а): парсишь какое там от GMT смещение, переводишь это смещение в unixtime stamp и плюсуешь к тому времени что уже получил
Я получил MSK. Какое у MSK смещение? В прошлом году это было UTC+3, в этом году уже UTC+4.
Ну ладно MSK -- я про него знаю, а какая-нибудь Ангола? Я даже не знаю как называется их таймзона, не говоря уже о смещении
и переходе на летнее время.
ddkprog писал(а): ты хочешь парсить время с учетом уже базы tz
ну глянь в man time man localtime
что там по tz_name
Это константа, зовется __tz_name для BSD - tz_zone, в структуре tm.
Проблема в том, что туда ничего не записать.
Есть tzset, которая устанавливает внутренние переменные tzname, timezone, daylight на основе переменной окружения TZ.
Но TZ имеет свой собственный формат, просто MSK туда не записать.

Хранить же где-то соответствие MSK смещению +0300 при наличии tzdata глупо, плюс нужно загружать туда все обновления и т.д.

tm_isdst совершенно не то -- это флаг, есть ли переход на летнее/зимнее время.
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Cisco присылает как +0300 (самый простой вариант), так и MSK. Но чтобы понять, что означает MSK, нужно где-то хранить эту информацию...
Я думал использовать для этого tzdata -- зачем изобретать велосипед?
А вот еще возможные варианты:

Код: Выделить всё

18:27:28.032 UTC Wed Dec 9 1998
21:04:33.433 +0300 Sat Nov 05 2011
21:04:33.433 MSK Sat Nov 05 2011
21:04:33.433 EST5EDT Sat Nov 05 2011
Про EST2EDT не уверен -- это tzset элементарно обрабатывает.
С UTC/GMT тоже все просто, но с остальным...

Задача минимум -- преобразовать полученную дату в UnixTime. С миллисекундами разобраться легко.
На даты в прошлом можно забить, но не хотелось бы.
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Вот примерный код:

Код: Выделить всё

#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

const char *abmon[] =   {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

int main(void)
{
    struct tm tm;
    struct tm ut;
    time_t curtime;
    int i, len, hour, min, sec, usec, mday, year;
    char wday[3], mon[3], tz[10];
    char in[255]="21:04:33.433 MSK Sat Nov 05 2011";

    sscanf( in, "%d:%d:%d.%d %s %s %s %d %d", &hour, &min, &sec, &usec, &tz, &wday, &mon, &mday, &year );
    tm.tm_hour = hour;
    tm.tm_min = min;
    tm.tm_sec = sec;

    tm.tm_mday = mday;
    tm.tm_year = year - 1900;

    for (i = 0; i < 12; i++) {
        len = strlen(abmon[i]);
        if (strncasecmp(abmon[i], mon, len) == 0)
            break;
    }

    tm.tm_mon = i;
    tm.tm_isdst = -1;

    setenv("TZ",tz,1);

    curtime = mktime( &tm );
    //curtime = mktime( &tm ) + usec / 1000;

    tzset();
    printf("timezone = %d, daylight = %d, tzname[0]/tzname[1] = %s/%s\n", timezone, daylight, tzname[0], tzname[1] );

    printf("UnixTime: %d\n", curtime);

    printf( "in:   %s / %s\n", in, asctime( &tm ) );

    gmtime_r( &curtime, &ut );

    strftime(buf, sizeof(buf), "%H:%M:%S %Z %a %b %d %Y", &ut);
    printf("Output: %s\n", buf);

    unsetenv("TZ");
    exit(EXIT_SUCCESS);
}
Результат:

Код: Выделить всё

timezone = 0, daylight = 0, tzname[0]/tzname[1] = MSK/
UnixTime: 1320527073
in:   21:04:33.433 MSK Sat Nov 05 2011 / Sat Nov  5 21:04:33 2011

Output: 21:04:33 GMT Sat Nov 05 2011
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Если подсунуть строчку:

Код: Выделить всё

21:04:33.433 Europe/Moscow Sat Nov 05 2011
То в TZ записывается Europe/Moscow и все отрабатывает корректно.
Может хранить где-нибудь таблицу соответствия MSK=Europe/Moscow?
Хотя тоже не выход -- это программа на Си, а не БД...
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

MSK есть, но хранится она в tzdata в файле Europe/Moscow.
В TZ можно указать как путь к файлу (как полный так и относительный), а можно в формате TZ.
Проблема в том, что я получаю от Cisco именно MSK (или +0300 к примеру) и дальше хоть волком вой.
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
tma
Сообщения: 1809
Зарегистрирован: 18 сен 2010, 20:50
Контактная информация:

Re: Элементарная задачка для программиста

Сообщение tma »

Я не могу настраивать cisco всех возможных клиентов или требовать, чтобы все они работали в UTC.
Увы, единственный вариант это научиться понимать таймзону. Построить таблицу соответствия можно (по той же tzdata),
но ее либо придется в памяти держать (а таймзоны далеко не все нужны), либо каждый раз парсить файл, что не лучше.
tzfile грузит в память структуру zoneinfo, но только определенного, а какой подсунуть? Пока одни вопросы...
SkyTel OU - облачная АТС, DID, SIP-транк с посекундной тарификаицей, мобильная связь
http://skytel24.com | Эстония: +372.333.55.10 | Россия: +7(495)4019900
Ответить
© 2008 — 2024 Asterisk.ru
Digium, Asterisk and AsteriskNOW are registered trademarks of Digium, Inc.
Design and development by PostMet-Netzwerk GmbH