我想要一个函数的代码示例,该函数将 tDateTime 和整数作为输入,并在将该 tDateTime 提前 (int) 月后使用 setlocaltime 设置系统时间。时间应保持不变。
伪代码示例
SetNewTime(NOW,2);
我遇到的问题相当令人沮丧。 我不能将 incmonth 或类似内容与 tDateTime 一起使用,只能使用 tDate 等。
下面是一个完整的命令行程序,对我有用。 在德尔福 5 和 2007 年进行了测试。 为什么你说IncMonth不适用于TDateTime?
program OneMonth;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
Messages;
procedure SetLocalSystemTime(settotime: TDateTime);
var
SystemTime : TSystemTime;
begin
DateTimeToSystemTime(settotime,SystemTime);
SetLocalTime(SystemTime);
//tell windows that the time changed
PostMessage(HWND_BROADCAST,WM_TIMECHANGE,0,0);
end;
begin
try
SetLocalSystemTime(IncMonth(Now,1));
except on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
IncMonth 应该使用 TDateTime:
function IncMonth ( const StartDate : TDateTime {; NumberOfMonths : Integer = 1} ) : TDateTime;
请记住,TDate 实际上只是一个 TDateTime,按照惯例,您会忽略分数。
基于你的伪代码:
procedure SetNewTime(aDateTime: TDateTime; aMonths: Integer);
var
lSystemTime: TSystemTime;
begin
DateTimeToSystemTime(aDateTime, lSystemTime);
Inc(lSystemTime.wMonth, aMonths);
setSystemTime(lSystemTime);
end;
setSystemTime使用UTC时间,因此您必须根据时区进行调整。 偏差是计算机时区与 UTC 不同的分钟数。 这样可以正确调整系统上的日期:
procedure SetNewTime(aDateTime: TDateTime; aMonths: Integer);
var
lSystemTime: TSystemTime;
lTimeZone: TTimeZoneInformation;
begin
GetTimeZoneInformation(lTimeZone);
aDateTime := aDateTime + (lTimeZone.Bias / 1440);
DateTimeToSystemTime(aDateTime, lSystemTime);
Inc(lSystemTime.wMonth, aMonths);
setSystemTime(lSystemTime);
end;
信息为您的问题提供明确的答案。
考虑一下如果当月的日期在将来的月份不存在,您希望发生什么。比如说,1 月 31 日 + 1 个月。(一年中有 7 个月有 31 天,其余月份更少。 如果递增年份并且起始日期是闰年的 2 月 29 日,则会遇到同样的问题。 因此,不可能有一个通用的IncMonth或IncYear函数可以在所有日期一致地工作。
对于任何感兴趣的人,我衷心推荐朱利安·巴克纳尔(Julian Bucknall)关于此类计算固有的复杂性的文章关于如何计算两个日期之间的月数和天数。
以下是唯一可能不会在通用日期数学中引入异常的通用日期增量函数。 但它只能通过将责任转移回程序员来实现这一点,程序员可能具有他/她正在编程的特定应用程序的确切要求。
IncDay - 添加或减去天数。
IncWeek - 添加或减去周数。
但是,如果您必须使用内置函数,那么至少要确保它们执行您希望它们执行的操作。 看看 DateUtils 和 SysUtils 单元。 拥有这些函数的源代码是 Delphi 最酷的方面之一。 话虽如此,以下是内置函数的完整列表:
IncDay - 添加或减去天数。
IncWeek - 添加或减去周数。
IncMonth - 添加或减去月份数。
IncYear - 添加或减去年份数。
至于问题的第二部分,如何使用 TDatetime 设置系统日期和时间,一旦您拥有具有所需值的 TDatetime,以下从另一篇文章中无耻地窃取的代码将完成这项工作:
procedure SetSystemDateTime(aDateTime: TDateTime);
var
lSystemTime: TSystemTime;
lTimeZone: TTimeZoneInformation;
begin
GetTimeZoneInformation(lTimeZone);
aDateTime := aDateTime + (lTimeZone.Bias / 1440);
DateTimeToSystemTime(aDateTime, lSystemTime);
setSystemTime(lSystemTime);
end;