TDateTime для преобразования строки коротких дат в вспомогательные формы «VB-clone»

#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;
  

Надеюсь, это поможет