2012-05-12 134 views
4

我需要计算现在文件的最后修改日期/时间ie. something like this之间的时间(格式良好的),只能在我的情况下,该差异可在几天,几个月甚至几年。德尔福的时间间隔?

我尝试这样做:

var 
    TimeDiff : Double; 
begin 
    TimeDiff := Now - FileAgeEx('C:\my-file.txt'); 
    if (TimeDiff >= 1) then 
     Caption := FormatDateTime('dd hh:nn:ss', TimeDiff) 
    else 
     Caption := FormatDateTime('hh:nn:ss', TimeDiff); 
end; 

但(1)它不工作,(2)我想一个更好的格式。

最终我的目标是有这样的事情:

  • 时间DIFF <1天==>显示这样的:12:00:01
  • 时间DIFF> =1天==>显示此:25天,12:00:01
  • 时间DIFF> =1年==>显示此:2年,3个月,10天,12:00:01

任何人都知道我该怎么做?

谢谢!

回答

10

主要问题似乎是获取文件的上次修改时间。我使用下面的代码:

function LastWriteTime(const FileName: string): TFileTime; 
var 
    AttributeData: TWin32FileAttributeData; 
begin 
    if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @AttributeData) then 
    RaiseLastOSError; 
    Result := AttributeData.ftLastWriteTime; 
end; 

function UTCFileTimeToSystemTime(const FileTime: TFileTime): TSystemTime; 
//returns equivalent time in current locality, taking account of daylight saving 
var 
    LocalFileTime: Windows.TFileTime; 
begin 
    Windows.FileTimeToLocalFileTime(FileTime, LocalFileTime); 
    Windows.FileTimeToSystemTime(LocalFileTime, Result); 
end; 

function UTCFileTimeToDateTime(const FileTime: TFileTime): TDateTime; 
begin 
    Result := SystemTimeToDateTime(UTCFileTimeToSystemTime(FileTime)); 
end; 

你叫LastWriteTime获得文件时间格式的最后修改时间。然后拨打UTCFileTimeToDateTime转换为TDateTime,说明机器当前的当地时区。然后,您可以将该值与Now进行比较。

至于格式,你已经知道如何做到这一点。你的基本方法将起作用,你只需要充实细节。


在评论你说

FormatDateTime('dd hh:nn:ss', 2.9); 

显示时,你会期望一个2当天1。问题是这个函数格式化日期而不是时间间隔。值2.9不被视为已用时间,而是被视为绝对日期/时间,在德尔福时代后的2.9天。我将使用TruncFrac分别获取天数和部分天数,并从那里开始工作。

Days := Trunc(TimeDiff); 
Time := Frac(TimeDiff); 

下面的代码,直接从我的代码库中提取,可能会给你一些指针。请注意,它的输入是以秒为单位的,但它应该将您设置在正确的路径上。

function CorrectPlural(const s: string; Count: Integer): string; 
begin 
    Result := IntToStr(Count) + ' ' + s; 
    if Count<>1 then begin 
    Result := Result + 's'; 
    end; 
end; 

function HumanReadableTime(Time: Double): string; 
//Time is in seconds 
const 
    SecondsPerMinute = 60; 
    SecondsPerHour = 60*SecondsPerMinute; 
    SecondsPerDay = 24*SecondsPerHour; 
    SecondsPerWeek = 7*SecondsPerDay; 
    SecondsPerYear = 365*SecondsPerDay; 

var 
    Years, Weeks, Days, Hours, Minutes, Seconds: Int64; 

begin 
    Try 
    Years := Trunc(Time/SecondsPerYear); 
    Time := Time - Years*SecondsPerYear; 
    Weeks := Trunc(Time/SecondsPerWeek); 
    Time := Time - Weeks*SecondsPerWeek; 
    Days := Trunc(Time/SecondsPerDay); 
    Time := Time - Days*SecondsPerDay; 
    Hours := Trunc(Time/SecondsPerHour); 
    Time := Time - Hours*SecondsPerHour; 
    Minutes := Trunc(Time/SecondsPerMinute); 
    Time := Time - Minutes*SecondsPerMinute; 
    Seconds := Trunc(Time); 

    if Years>5000 then begin 
     Result := IntToStr(Round(Years/1000))+' millennia'; 
    end else if Years>500 then begin 
     Result := IntToStr(Round(Years/100))+' centuries'; 
    end else if Years>0 then begin 
     Result := CorrectPlural('year', Years) + ' ' + CorrectPlural('week', Weeks); 
    end else if Weeks>0 then begin 
     Result := CorrectPlural('week', Weeks) + ' ' + CorrectPlural('day', Days); 
    end else if Days>0 then begin 
     Result := CorrectPlural('day', Days) + ' ' + CorrectPlural('hour', Hours); 
    end else if Hours>0 then begin 
     Result := CorrectPlural('hour', Hours) + ' ' + CorrectPlural('minute', Minutes); 
    end else if Minutes>0 then begin 
     Result := CorrectPlural('minute', Minutes); 
    end else begin 
     Result := CorrectPlural('second', Seconds); 
    end; 
    Except 
    Result := 'an eternity'; 
    End; 
end; 
+0

+1尤其适用于考虑夏令时。 – 2012-05-12 15:09:06

+0

谢谢!但是还是有些问题......'FormatDateTime('dd hh:nn:ss',TimeDiff);'其中TimeDiff ='2.9487917361'(距离文件上次修改和现在差不多3天)给了我01 22:46:15 ' – TheDude

+1

我希望我的最新更新有所帮助。 –