Подскажите пожалуйста как в Delphi дату и время посчиать в секундах.
Например есть переменная типа ДатаВремя и мне нужно значение этой переменной записать в секундах в другую переменную типа Integer.
хм... а как дату в секунды перевести? от какого момента секунды отщитывать будем? от рождества христова?
[Ответ]
zeroserg 23:59 14.10.2006
имхо, интегера не хватит
зыЖ а математику кто отменял, на басме всё помнож и будет тебе счастие
[Ответ]
THT 13:58 15.10.2006
05.00.0000 12:30:35 посчитать в секундах
т.е 35 + 30*60 + 12*60*60 + 5*24*60*60.
Как это реализовать в Delphi?
[Ответ]
ASSA 17:16 15.10.2006
Тип DateTime вроде как является даблом. целая часть- дни. дробная -доля суток. 0,5 это 12 часов дня. дальше сам дойдешь?
все на основе си-билдера. в дельфях по-моему то же самое.
[Ответ]
aerin 11:59 16.10.2006
В MSDN в описании функции RtlTimeToSecondsSince1970, доступной только начиная с 2000Prof и XP, есть описание алгоритма этих вычислений:
There is no single equivalent public function. To perform this task using public functions, use the following steps:
1. Call SystemTimeToFileTime to copy the system time to a FILETIME structure. Call GetSystemTime to get the current system time to pass to SystemTimeToFileTime.
2. Copy the contents of the FILETIME structure to a ULARGE_INTEGER structure.
3. Initialize a SYSTEMTIME structure with the date and time of the first second of January 1, 1970.
4. Call SystemTimeToFileTime, passing the SYSTEMTIME structure initialized in Step 3 to the call.
5. Copy the contents of the FILETIME structure returned by SystemTimeToFileTime in Step 4 to a second ULARGE_INTEGER. The copied value should be greater than or equal to the value copied in Step 2.
6. Subtract the 64-bit value in the ULARGE_INTEGER structure initialized in Step 2 from the 64-bit value of the ULARGE_INTEGER structure initialized in Step 5.
А для глупых нельзя как-нибудь попроще и поконкретнее.
[Ответ]
aerin 13:27 16.10.2006
THT
Например? Что не устраивает в алгоритме от MS?
[Ответ]
ХАРЧО 09:29 20.10.2006
Мне так кажется, что нужно просто применить функцию:
function DateTimeToFileDate(DateTime: TDateTime): Integer;
[Ответ]
aerin 10:12 20.10.2006
ХАРЧО
Я не знаю, что делает функция DateTimeToFileDate, но, судя по названию, у меня складывается впечатление, что это обертка над SystemTimeToFileTime, странно только, что у вас она возвращает Integer, а в win32 файловое время принято отсчитывать от 01.01.1601(UTC) с 100-наносекундным интервалом.
Но не суть, расскажите как, пользуясь вашей замечательной функцией вы решите задачу про "05.00.0000 12:30:35", поставленную автором в посте #4?
[Ответ]
ХАРЧО 10:33 20.10.2006
aerin, любите WinAPI? Чтож похвально. Но в этом случае вопрос можно решить и чисто дельфивскими путями (которые, естественно опираюстся на WinAPI, но имеют, имхо, несколько болле удобный интерфейс).
Про вопрос #4 скажу следующее: попробуйте функцию:
function StrToDateTime(const S: string; const FormatSettings: TFormatSettings): TDateTime;
Таким образом вы из строки получите тип TDateTime, как это спрашивалось в вопросе #1. А затем вышеуказанным путем.
P.S. Я далек от мысли, что изложенный мной способ наиболее простой и быстрый, это всего лишь мое мнение....
[Ответ]
gloomdemon 11:30 20.10.2006
aerin,
видимо Вы не особо знакомы с delphi, просто тогда ,ы знали что в делфи на каждый чих не надо лезть в мсдн и искать решение, там в большинстве случаем уже всё под рукой. То что предложил ХАРЧО верно.
Всё будет очень просто DateTimeToFileDate(StrToDateTime('5.05.2006 7:42:11')); Это касательно поста #1.
Как написано в хелпе DateTimeToFileDate преобразует TDateTime object to an OS timestamp. А то что там 4 байта возращается, ну так это не только проблема Delphi, time_t в linux тоже 4 байта =) Для времени в промежутке 1980 - 2099 (это в делфи хелп так, по други источникам до 2190)хватает, а там ещё одна "проблема 2000"
ime_t time(time_t *tloc);
DESCRIPTION
The time() function returns the value of time in seconds
since 00:00:00 UTC, January 1, 1970.
А касательно поста #4 то наверное дату 05.00.0000 надо от 0000 года и отсчитывать, таких функций ещё наверное нет [Ответ]
ХАРЧО 11:37 20.10.2006
Ой, бл@! Я облажался! Как отсчитывать от
Сообщение от THT:
05.00.0000
нулевого года меня еще в ПТУ не научили....
[Ответ]
gloomdemon 11:50 20.10.2006
ХАРЧО, да ни чё. Если брать алгоритм из мсдн то вообще в минуса уйдёшь. Будет модная дата =)
ЗЫ
А вообще самое модное это на js:
<script language="JavaScript"><!--
var aDate = 925241310748; // miliseconds Since 1970;
theDate = new Date(aDate);
dd = theDate.getDate();
mm = theDate.getMonth()+1; // 0 based
yy = theDate.getYear();
if (yy < 1000) yy +=1900; // Y2K fix
gloomdemon, весело! Можно на форму кинуть компонент TWebBrowser, в нем открыть этот немного модифицированный код, чтобы он вызывал одно из событий компонента и смело передавать это в Int64.
ЯплакалЪ!
[Ответ]
aerin 13:26 20.10.2006
Сообщение от :
__int64 i64GetSecsFromDate( SYSTEMTIME* sm )
{
__int64 temp = 0; // итоговое количество секунд
// Список дней в первых одиннадцати месяцах:
int months[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
// Вычисляем число секунд, содержащихся в числе полных лет:
temp += 60 * 60 * 24 * ( 365 * (__int64)sm->wYear + (__int64)(sm->wYear / 4 ) );
// Добавляем секунды прошедших в текущем году месяцев:
for( int i = 0; i < (sm->wMonth - 1); i++ )
{
temp += 60 * 60 * 24 * (__int64)months[i];
}
ЗЫ. Результат вызова на датах после 1970 года совпадает с результатом вызова RtlTimeToSecondsSince1970, что подтверждает правильность алгоритма.
ЗЫЫ. На отрицательных датах будет работать неверно.
ЗЫЫЫ. На Delphi, извините, религия и руководство писать не позволяют.
ЗЫЫЫЫ. Если надо, могу доработать и для отрицательных дат.
[Ответ]
aerin 14:51 20.10.2006
Тут меня поправили в двух местах:
1. Если целевой год високосный, то нужно изменить для этого года продолжительность февраля с 28 до 29 дней.
2. После реформы 1582 года високосными из годов, делящихся на 100, стали считаться только те из них, которые к тому же делились на 400.
Таким образом окончательная версия функции принимает вид:
Сообщение от :
__int64 i64GetSecsFromDate( SYSTEMTIME* sm )
{
__int64 temp = 0; // итоговое количество секунд
// Список дней в первых одиннадцати месяцах:
int months[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
// Исправление для високосных лет после 1582 года.
// ( т.н. реформа календаря Григория XIII )
int subLeapYears = 0;
int addLeapYears = 0;
if( 1600 < sm->wYear )
{
subLeapYears = ( sm->wYear - 1600 ) / 100;
addLeapYears = subLeapYears / 4;
// Исправление для дат после 28.02 в високосном году:
if( 0 == sm->wYear % 100 )
{
if( 0 == sm->wYear % 400 )
{
months[1] = 29;
}
}
else
{
if( 0 == sm->wYear % 4 )
months[1] = 29;
}
}
else
{
// Исправление для дат после 28.02 в високосном году:
if( 0 == sm->wYear % 4 )
months[1] = 29;
}
// Вычисляем число секунд, содержащихся в числе полных лет:
temp += 60 * 60 * 24 * ( 365 * (__int64)sm->wYear + (__int64)(sm->wYear / 4) -
subLeapYears + addLeapYears );
// Добавляем секунды прошедших в текщем году месяцев:
for( int i = 0; i < (sm->wMonth - 1); i++ )
{
temp += 60 * 60 * 24 * (__int64)months[i];
}
aerin, эх и чего люди не придумают что бы boost использовать раз религия на делфи не позволяет.
/* This example demonstrates the use of the time zone database and
* local time to calculate the number of seconds since the UTC
* time_t epoch 1970-01-01 00:00:00. Note that the selected timezone
* could be any timezone supported in the time zone database file which
* can be modified and updated as needed by the user.
*
* To solve this problem the following steps are required:
* 1) Get a timezone from the tz database for the local time
* 2) Construct a local time using the timezone
* 3) Construct a posix_time:time for the time_t epoch time
* 4) Convert the local_time to utc and subtract the epoch time
*
*/
int main()
{
using namespace boost::gregorian;
using namespace boost::local_time;
using namespace boost:osix_time;
tz_database tz_db;
try {
tz_db.load_from_file("../data/date_time_zonespec.csv");
}catch(data_not_accessible dna) {
std::cerr << "Error with time zone data file: " << dna.what() << std::endl;
exit(EXIT_FAILURE);
}catch(bad_field_count bfc) {
std::cerr << "Error with time zone data file: " << bfc.what() << std::endl;
exit(EXIT_FAILURE);
}
time_zone_ptr nyc_tz = tz_db.time_zone_from_region("America/New_York");
date in_date(2004,10,04);
time_duration td(12,14,32);
// construct with local time value
// create not-a-date-time if invalid (eg: in dst transition)
local_date_time nyc_time(in_date,
td,
nyc_tz,
local_date_time::NOT_DATE_TIME_ON_ERROR);
gloomdemon
But my example demonstres how to calculate the number of seconds sinse 0.0.0 00:00:00 by one iteration. Андестенд?
[Ответ]
mikе 17:40 20.10.2006
Сообщение от :
unit unix_utils;
interface
implementation
const
// Sets UnixStartDate to TDateTime of 01/01/1970
UnixStartDate: TDateTime = 25569.0;
function DateTimeToUnix(ConvDate: TDateTime): Longint;
begin
//example: DateTimeToUnix(now);
Result := Round((ConvDate - UnixStartDate) * 86400);
end;
function UnixToDateTime(USec: Longint): TDateTime;
begin
//Example: UnixToDateTime(1003187418);
Result := (Usec / 86400) + UnixStartDate;
end;
end.
mikе
Те же яйца. А до 1970 года? См. пост №4.
[Ответ]
mikе 17:52 20.10.2006
выдаст отрицательный. в РНР, к примеру, сие замечательно работает (правда, только под никсами — под виндой не катит) [Ответ]
gloomdemon 18:25 20.10.2006
Сообщение от aerin:
But my example demonstres how to calculate the number of seconds sinse 0.0.0 00:00:00 by one iteration. Андестенд?
Use power Luke!
time_duration diff = nyc_time.utc_time() - time_t_epoch; --> time_duration diff = nyc_time.utc_time();
А вообще прикольно =) Кто на асме напишет?
[Ответ]
ХАРЧО 18:28 20.10.2006
Ух как вас всех торкнуло-то, двоих в C/C++ заносит, видел пост с кодами на JavaScript, один человек с юниксовыми timestamp'aми работать изволит, еще кого-то на асм потянуло.... Аффтар темы уже давно над нами тихо посмеивается, скажет: "Давайте, ребята, старайтесь, напишите искуственный интелект для решения моей задачи...". По-моему мы уже решили поставленную задачу... Закрывайте тему, а то флеймить начну...
[Ответ]