我试图找到一种计算方法,将 TDateTime 值 40653.6830593 转换为年、月、日、小时、分钟和秒。
当然,我确信这是可能的,但我的大脑似乎没有能力编写一个公式来从该双精度中提取这些值。
我正在使用 Satellite Forms,一种类似 vb 的语言,但不要指望我需要任何特定的 .NET 库来执行此操作,对吗?它应该只是一个数字计算......对吗?
谢谢您的帮助!最真诚的。
乔
我试图找到一种计算方法,将 TDateTime 值 40653.6830593 转换为年、月、日、小时、分钟和秒。
当然,我确信这是可能的,但我的大脑似乎没有能力编写一个公式来从该双精度中提取这些值。
我正在使用 Satellite Forms,一种类似 vb 的语言,但不要指望我需要任何特定的 .NET 库来执行此操作,对吗?它应该只是一个数字计算......对吗?
谢谢您的帮助!最真诚的。
乔
根据您的“德尔福”标签...
在德尔福
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 下发布,没有废话)
,您可以在以下位置找到: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;
旧版 VB 或 VBA(甚至 Excel)会将日期视为自 1899 年 12 月 30 日以来的天数,我相信德尔福也是如此。因此,在旧版 VB/VBA 中,您可以编写
Dim myDate as Date
myDate = myDate + 40653.68303593
获取 2011 年 4 月 20 日下午 4:23:36。在 VB.NET 中,情况有所不同,因为 DateTime 结构默认为 0001 年 1 月 1 日。
Dim myDate As New DateTime(1899, 12, 30)
myDate = myDate.AddDays(40653.68303593)
另一个用户已经发布了一个德尔福的答案。
无论如何,基本前提是您要添加天数,小数部分代表时间。所以在这个例子中,自 1899 年 12 月 30 日以来已经过去了 40653 天,还有 0.683... 部分天。
提取小时数:
记住 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;
希望有帮助