Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > [C++ WinAPI]Как перевести миллисекунды в SYSTEMTIME?


Автор: Alca 15.6.2009, 11:36
Как перевести миллисекунды в SYSTEMTIME?
Код

ULONGLONG  ullMilliSec = 999/*MS*/ + (1000)*59/*SEC*/ + (1000*60)*59/*MIN*/ + (1000*60*60)*23/*HOUR*/ + (1000*60*60*24)*27/*DAY*/;
SYSTEMTIME stST        = {0};

bMilliSecToDateTime(ullMilliSec, stST); 


Код

...\umain.cpp(103) : warning C4307: '*' : integral constant overflow

Не влазит в переменную ullMilliSec столько миллисекунд.... Что делать?

Автор: NiJazz 15.6.2009, 11:57
Код

time_t _t = 0;
::time( &_t );


Получаешь кол-во миллисекунд с 01.01.1970, кажется.
С этой величиной удобнее всего работать, если нужно считать время, прошедшее с некого момента.

Автор: Alca 15.6.2009, 12:28
Мне миллисекунды надо в SYSTEMTIME перегнать, а не считать разницу.
Код

typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
}SYSTEMTIME, *PSYSTEMTIME;

Автор: NiJazz 15.6.2009, 13:26
Смотрим http://support.microsoft.com/kb/167296

Автор: Alca 15.6.2009, 13:35
Спасибо, буду разбираться...

Автор: 586 15.6.2009, 14:20
Цитата(Alca @  15.6.2009,  12:36 Найти цитируемый пост)
Код
ULONGLONG  ullMilliSec = 999/*MS*/ + (1000)*59/*SEC*/ + (1000*60)*59/*MIN*/ + (1000*60*60)*23/*HOUR*/ + (1000*60*60*24)*27/*DAY*/;
SYSTEMTIME stST        = {0};
bMilliSecToDateTime(ullMilliSec, stST); 

Код
...\umain.cpp(103) : warning C4307: '*' : integral constant overflow

Не влазит в переменную ullMilliSec столько миллисекунд.... Что делать? 

Там надо явно указать, что число 64-битное.
Код
ULONGLONG  ullMilliSec = 999/*MS*/ + (1000)*59/*SEC*/ + (1000*60)*59/*MIN*/ + (1000*60*60)*23/*HOUR*/ + (1000ULL*60*60*24)*27/*DAY*/;


Добавлено через 6 минут и 38 секунд
Или конвертировать его:
Код
ULONGLONG  ullMilliSec = 999/*MS*/ + (1000)*59/*SEC*/ + (1000*60)*59/*MIN*/ + (1000*60*60)*23/*HOUR*/ + ((ULONGLONG)1000*60*60*24)*27/*DAY*/;

Автор: Alca 15.6.2009, 15:27
586, спасибо. Ворниг ушел, но результат у меня получаеться не правильный.
Код

ULONGLONG ullMs    = 999;
ULONGLONG ullSec   = (1000ULL) * 59;
ULONGLONG ullMin   = (1000ULL*60) * 59;
ULONGLONG ullHour  = (1000ULL*60*60) * 23;
ULONGLONG ullDay   = (1000ULL*60*60*24) * 27;
ULONGLONG ullMonth = (1000ULL*60*60*24*30) * 11;
ULONGLONG ullYear  = (1000ULL*60*60*24*30*12) * 50;

ULONGLONG ullMilliSec = ullMs + ullSec + ullMin + ullHour + ullDay + ullMonth + ullYear;

Код

BOOL bMSecToDateTime(ULONGLONG ullMilliSec, SYSTEMTIME &stST) { 
    stST.wYear         = ullMilliSec / ((60*60*24*30) * 12);  
    stST.wMonth        = ullMilliSec % ((60*60*24*30) * 12) / ((60*60*24) * 30);  
    stST.wDay          = ullMilliSec % ((60*60*24)    * 30) / ((60*60)    * 24);      

    stST.wHour         = ullMilliSec % ((60*60)       * 24) / ((60)       * 60);        
    stST.wMinute       = ullMilliSec % ((60)          * 60) / ((60)           );
    stST.wSecond       = ullMilliSec % ((60)              ) / ((1)            );
    stST.wMilliseconds = ullMilliSec % 1000;

    return TRUE;
}

Где ошибка?
Должно быть:
Цитата

50 лет 11 мес 27 дн 23 часа 59 мин 59 сек 999 мс

Автор: 586 15.6.2009, 15:50
Код
#include <windows.h>
#include <stdio.h>

BOOL bMSecToDateTime(ULONGLONG ullMilliSec, SYSTEMTIME &stST) {
    stST.wYear = ullMilliSec / ((1000ULL*60*60*24*30) * 12);
    ullMilliSec %= ((1000ULL*60*60*24*30) * 12);

    stST.wMonth = ullMilliSec / ((1000ULL*60*60*24) * 30);
    ullMilliSec %= ((1000ULL*60*60*24) * 30);

    stST.wDay = ullMilliSec / ((1000*60*60) * 24);
    ullMilliSec %= ((1000*60*60) * 24);

    stST.wHour = ullMilliSec / ((1000*60) * 60);
    ullMilliSec %= ((1000*60) * 60);

    stST.wMinute = ullMilliSec / ((1000*60));
    ullMilliSec %= ((1000*60));

    stST.wSecond = ullMilliSec / 1000;
    ullMilliSec %= 1000;

    stST.wMilliseconds = ullMilliSec;
    return TRUE;
}

int main(int argc, char* argv[])
{
    ULONGLONG ullMs    = 999;
    ULONGLONG ullSec   = (1000ULL) * 59;
    ULONGLONG ullMin   = (1000ULL*60) * 59;
    ULONGLONG ullHour  = (1000ULL*60*60) * 23;
    ULONGLONG ullDay   = (1000ULL*60*60*24) * 27;
    ULONGLONG ullMonth = (1000ULL*60*60*24*30) * 11;
    ULONGLONG ullYear  = (1000ULL*60*60*24*30*12) * 50;
    ULONGLONG ullMilliSec = ullMs + ullSec + ullMin + ullHour + ullDay + ullMonth + ullYear;

    SYSTEMTIME st;
    bMSecToDateTime(ullMilliSec, st);
    printf("%u years %u months %u days %u hours %u min %u sec %u ms\n",
        st.wYear,
        st.wMonth,
        st.wDay,
        st.wHour,
        st.wMinute,
        st.wSecond,
        st.wMilliseconds);
    getchar();
    return 0;
}

Автор: korbian 15.6.2009, 15:58
Alca, 
Код

  uint64_t ullMs = 999;
  uint64_t ullSec = (1000ULL) * 59;
  uint64_t ullMin = (1000ULL * 60) * 59;
  uint64_t ullHour = (1000ULL * 60 * 60) * 23;
  uint64_t ullDay = (1000ULL * 60 * 60 * 24) * 27;
  uint64_t ullMonth = (1000ULL * 60 * 60 * 24 * 30) * 11;
  uint64_t ullYear = (1000ULL * 60 * 60 * 24 * 30 * 12) * 50;

  uint64_t ullMilliSec = ullMs + ullSec + ullMin + ullHour + ullDay + ullMonth
      + ullYear;

  uint64_t year = ullMilliSec / (1000ULL * 60 * 60 * 24 * 30 * 12);
  uint64_t tail = ullMilliSec % (1000ULL * 60 * 60 * 24 * 30 * 12);

  uint64_t month = tail / (1000ULL * 60 * 60 * 24 * 30);
  tail = tail % (1000ULL * 60 * 60 * 24 * 30);

  uint64_t day = tail / (1000ULL * 60 * 60 * 24);
  tail = tail % (1000ULL * 60 * 60 * 24);

  uint64_t hour = tail / (1000ULL * 60 * 60);
  tail = tail % (1000ULL * 60 * 60);

  uint64_t min = tail / (1000ULL * 60);
  tail = tail % (1000ULL * 60);

  uint64_t sec = tail / (1000ULL);
  uint64_t ms = tail % (1000ULL) ;

  cout << year << endl;
  cout << month << endl;
  cout << day << endl;
  cout << hour << endl;
  cout << min << endl;
  cout << sec << endl;
  cout << ms << endl;


Добавлено через 32 секунды
smile опоздал

Автор: Alca 15.6.2009, 16:06
Спасибо!!! Вроде пашет. 

Автор: GremlinProg 15.6.2009, 16:07
Перемещено в "С/C++ общие вопросы"

Автор: Alca 15.6.2009, 16:17
А чего с этим ворнингом делать?
Код

warning C4244: '=' : conversion from 'ULONGLONG' to 'WORD', possible loss of data

Кастануть его что ли?

Добавлено через 42 секунды
Поставил всем по кресту.... smile 

Автор: 586 15.6.2009, 17:02
Цитата(Alca @  15.6.2009,  17:17 Найти цитируемый пост)
А чего с этим ворнингом делать?
Код
warning C4244: '=' : conversion from 'ULONGLONG' to 'WORD', possible loss of data

Миллисекунд не может быть более 999;
секунд, минут не может быть более 59;
часов не более 23
дней не более 29 (30 дней в месяце)
месяцев не более 11

Чтобы возникло переполнение, нужно число, более 65535.
Следовательно, ошибки нет, и варнинг можно проигнорить.
Код
#pragma warning (disable:4244)    // conversion from 'ULONGLONG' to 'WORD', possible loss of data
BOOL bMSecToDateTime(ULONGLONG ullMilliSec, SYSTEMTIME &stST) {
    stST.wYear = ullMilliSec / ((1000ULL*60*60*24*30) * 12);
    ullMilliSec %= ((1000ULL*60*60*24*30) * 12);

    stST.wMonth = ullMilliSec / ((1000ULL*60*60*24) * 30);
    ullMilliSec %= ((1000ULL*60*60*24) * 30);

    stST.wDay = ullMilliSec / ((1000*60*60) * 24);
    ullMilliSec %= ((1000*60*60) * 24);

    stST.wHour = ullMilliSec / ((1000*60) * 60);
    ullMilliSec %= ((1000*60) * 60);

    stST.wMinute = ullMilliSec / ((1000*60));
    ullMilliSec %= ((1000*60));

    stST.wSecond = ullMilliSec / 1000;
    ullMilliSec %= 1000;

    stST.wMilliseconds = ullMilliSec;
    return TRUE;
}
#pragma warning (default:4244)

Автор: Alca 15.6.2009, 17:06
586, ты волшебник  smile ! Спасибо, за разъяснения.

Автор: GremlinProg 15.6.2009, 19:44
Цитата(586 @  15.6.2009,  19:02 Найти цитируемый пост)
#pragma warning (disable:4244)

предупреждения прикрывают в крайних случаях, когда нет возможности его обойти

в данном случае, нужно просто явно "обрезать" значение:
Код

word_value = (WORD)long_long_value;

любой, кто будет читать эту конструкцию поймет ее как надо,
в том числе и оптимизатор, который делает вывод, что старшие биты переменной не используются
"плавающие" вычисления, в таком случае, могут быть оптимизированы, если потребуется, например: "длинная" операция 64-битного сложения может быть заменена на "короткую" - 32-битную и т.п.

прикрывая такое предупреждение, оптимизатор этого сделать не сможет, при всем желании и возможностях

Автор: Alca 15.6.2009, 21:19
ясненько, значит закастить

Автор: 586 15.6.2009, 21:50
Цитата(GremlinProg @  15.6.2009,  20:44 Найти цитируемый пост)
прикрывая такое предупреждение, оптимизатор этого сделать не сможет, при всем желании и возможностях

На оптимизатор это никак не влияет. И на машинный код. Компилятор автоматически конвертирует ULONGLONG в WORD, и предупреждает, что старшая часть переменной теряется.
Цитата(GremlinProg @  15.6.2009,  20:44 Найти цитируемый пост)
в данном случае, нужно просто явно "обрезать" значение:
Код
word_value = (WORD)long_long_value;

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

Автор: 586 15.6.2009, 22:09
Правда, на gcc и других компиляторах с блокировкой варнингов будет проблема.
В данном случае нужно приводить типы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)