#delphi #tdatetime #satelliteforms
#delphi #tdatetime #satelliteforms
Вопрос:
Я пытаюсь найти вычисление, которое преобразует значение TDateTime 40653.6830593 в год, месяц, день, час, минуту и секунду.
Я уверен, что это, конечно, возможно, но, похоже, у моего мозга недостаточно сил, чтобы написать формулу, которая извлечет эти значения из этого double.
Я использую вспомогательные формы, язык, подобный vb, но не ожидаю, что мне понадобится что-то конкретное.СЕТЕВЫЕ библиотеки для этого, верно? Это должно быть просто числовое вычисление… верно?
Спасибо за помощь! С уважением.
Джо
Комментарии:
1. Для проверки, равен ли ваш предполагаемый вывод для этого значения 20.04.11, 16:23:36 вечера?
2. Есть ли у этого «vb-подобного» языка название?
3. Чтобы извлечь часы, помните, что 1.0 = 24 часа, таким образом, часы: = этаж (0.6830593* 24) мод 24, минуты: = этаж (0.6830593*24*60 ) мод 60, секунды: = минуты:= этаж(0.6830593*24*60*60 ) мод 60
Ответ №1:
На основе вашего тега ‘Delphi’…
В Delphi
implementation
uses DateUtils;
....
var
MyDate: TDateTime;
...other vars...
begin
MyDate:= double(40653.6830593);
MyYear:= YearOf(MyDate);
MyMonth:= MonthOf(MyDate);
MyDay:= DayOf(MyDate);
MyHour:= HourOf(MyDate);
MyMinute:= ... ah well you get the idea.
Кстати: VB или Delphi, что это?
Если вы хотите создать свой собственный
Из модуля sysutils (выпущен под двойной лицензией GPL2 / Borland No nonsense)
Который вы можете найти по адресу: http://www.koders.com/delphi/fidF6715D3FD1D4A92BA7F29F96643D8E9D11C1089F.aspx?s=hook
function DecodeDateFully(const DateTime: TDateTime; var Year, Month, Day, DOW: Word): Boolean;
const
D1 = 365;
D4 = D1 * 4 1;
D100 = D4 * 25 - 1;
D400 = D100 * 4 1;
var
Y, M, D, I: Word;
T: Integer;
DayTable: PDayTable;
begin
T := DateTimeToTimeStamp(DateTime).Date;
if T <= 0 then
begin
Year := 0;
Month := 0;
Day := 0;
DOW := 0;
Result := False;
end else
begin
DOW := T mod 7 1;
Dec(T);
Y := 1;
while T >= D400 do
begin
Dec(T, D400);
Inc(Y, 400);
end;
DivMod(T, D100, I, D);
if I = 4 then
begin
Dec(I);
Inc(D, D100);
end;
Inc(Y, I * 100);
DivMod(D, D4, I, D);
Inc(Y, I * 4);
DivMod(D, D1, I, D);
if I = 4 then
begin
Dec(I);
Inc(D, D1);
end;
Inc(Y, I);
Result := IsLeapYear(Y);
DayTable := @MonthDays[Result];
M := 1;
while True do
begin
I := DayTable^[M];
if D < I then Break;
Dec(D, I);
Inc(M);
end;
Year := Y;
Month := M;
Day := D 1;
end;
end;
function IsLeapYear(Year: Word): Boolean;
begin
Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;
function TryEncodeDate(Year, Month, Day: Word; out Date: TDateTime): Boolean;
var
I: Integer;
DayTable: PDayTable;
begin
Result := False;
DayTable := @MonthDays[IsLeapYear(Year)];
if (Year >= 1) and (Year <= 9999) and (Month >= 1) and (Month <= 12) and
(Day >= 1) and (Day <= DayTable^[Month]) then
begin
for I := 1 to Month - 1 do Inc(Day, DayTable^[I]);
I := Year - 1;
Date := I * 365 I div 4 - I div 100 I div 400 Day - DateDelta;
Result := True;
end;
end;
Комментарии:
1. -1. Я не понимаю, как это полезно. В вопросе четко указано, что используемый язык является «VB-подобным» языком, а не Delphi. Тег Delphi присутствует, потому что вопрос о типе данных Delphi. Ответ с использованием библиотечных функций, специфичных для Delphi, не сильно помогает тому, кто использует другой язык. Может быть, вы могли бы вместо этого описать, как
DecodeDate
работает, поскольку именно это используют все эти функции. (И функции являютсяYearOf
,MonthOf
и т.д., а не простоYear
,Month
, ….)2. @Rob включил код для DecodeDate, EncodeDate и isLeapYear, а также ссылку. К сожалению, OP не указал этот таинственный язык, который он использует, потому что материал, который он пытается сделать, вероятно, уже выполнен в стандартной библиотеке для этого языка / IDE.
3. Если это полезно, переведите приведенный выше код на любой «vb подобный» язык, который у вас есть. Крайне бесполезно не указывать фактический язык, но это проблема операционной системы.
4. Вау! Это место очень полезно.. спасибо за ответы. Мне следовало вернуться раньше, чтобы добавить больше информации. Загадочный «VB-подобный» язык, который я использую, — это язык сценариев, поставляемый в комплекте с инструментом RAD для мобильных приложений, называемым Satellite Forms. Синтаксис очень похож на vb (Len, InStr, Mod и т.д.). Я ищу способ превратить double в его компонент year, month, day, hour, minute и second. Оттуда я смогу сгенерировать shortdatestring.
Ответ №2:
Устаревший VB или VBA (даже Excel) будет обрабатывать дату как количество дней, прошедших с 30.12.1899, и я полагаю, что то же самое верно для Delphi. Таким образом, в устаревшем VB / VBA вы могли бы написать
Dim myDate as Date
myDate = myDate 40653.68303593
Чтобы получить 20 апреля 2011, 16:23:36 вечера. В VB.NET это отличается, поскольку структура DateTime по умолчанию равна 1 января 0001.
Dim myDate As New DateTime(1899, 12, 30)
myDate = myDate.AddDays(40653.68303593)
Другой пользователь уже опубликовал ответ на Delphi.
В любом случае, основная предпосылка заключается в том, что вы добавляете количество дней, причем десятичная часть представляет время. Итак, в этом примере с 30.12.1899 прошло 40653 полных дня и 0,683 … неполных дня.
Комментарии:
1. стоит упомянуть, какая фракция является особенной
Ответ №3:
Для извлечения часов:
помните, что 1.0 = 1 день = 24 часа, таким образом
DayPart:= double(MyDateTime) - Floor(double(MyDateTime));
//there is a function for fraction, but I forgot the name,
//never use that stuff.
//if we want to round 0.9999999999 up from 23:59:59 to 24:00:00, do this:
if (RoundTimeUpByHalfASecond = true) then DayPart:= DayPart (1/(24*60*60*2));
hours:= floor(DayPart*24);
minutes:= floor(DayPart*24*60) mod 60;
seconds:= minutes:= floor(DayPart*24*60*60) mod 60;
Надеюсь, это поможет