更改今天的日期,向前推进一个月并设置系统时间。

5
我需要一个函数的代码示例,该函数以tDateTime和整数为输入,并在将tDateTime增加(int)个月后使用setlocaltime设置系统时间。时间应保持不变。
伪代码示例:
SetNewTime(NOW,2);

我遇到的问题非常令人沮丧。我无法使用incmonth或类似函数来处理tDateTime类型,只能使用tDate等其他类型。

5个回答

5
下面是一份完整的命令行程序,适用于我。在Delphi 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.

Bruce,你的代码真的很干净,但是Kogus的代码正确地维护了时间。非常感谢你们两个! - Bruce the Hoon
这很公平。我漏掉了一些重要的东西。 - Bruce McGee

3

IncMonth应该与TDateTime一起使用:

function IncMonth ( const StartDate  : TDateTime {; NumberOfMonths  : Integer = 1} ) : TDateTime;

记住,TDate 实际上只是 TDateTime 的一种约定,您忽略其小数部分。

1

根据您的伪代码:

procedure SetNewTime(aDateTime: TDateTime; aMonths: Integer);
var
  lSystemTime: TSystemTime;
begin
  DateTimeToSystemTime(aDateTime, lSystemTime);
  Inc(lSystemTime.wMonth, aMonths);
  setSystemTime(lSystemTime);
end;

Bruce,我真的很喜欢这里的简洁性,但是我在时间方面运气不佳。虽然日期按预期增加和减少,但是当我这样做时,一天中的时间会出现问题... 有什么想法吗? - Bruce the Hoon

1

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;

0

没有足够的信息来提供您问题的明确答案。

考虑一下,如果未来的某个月份中不存在当前月份的日期会发生什么。比如,1月31日+1个月。(一年中有7个月有31天,其余月份天数较少。)如果增加年份并且起始日期是闰年的2月29日,则会遇到同样的问题。因此,不能有一个通用的IncMonth或IncYear函数可以在所有日期上一致地工作。

对于任何感兴趣的人,我强烈推荐Julian Bucknall's article,该文章介绍了这种类型计算中固有的复杂性以及如何计算两个日期之间的月数和天数。

以下是唯一可能不会在通用日期计算中引入异常的通用日期增量函数。但是,它只能通过将责任转移回程序员身上来实现,前提是程序员具有特定应用程序的确切要求。

IncDay - 增加或减少若干天。
IncWeek - 增加或减少若干周。

但如果您必须使用内置函数,那么请确保它们执行您想要的操作。请查看DateUtils和SysUtils单元。拥有这些函数的源代码是Delphi最酷的方面之一。话虽如此,这里是内置函数的完整列表:

增加天数 - 增加或减少若干天数。
增加星期数 - 增加或减少若干星期数。
增加月数 - 增加或减少若干月数。
增加年数 - 增加或减少若干年数。

关于您问题的第二部分,如何使用TDatetime设置系统日期和时间,以下代码 shamelessly stolen from another post 一旦您拥有所需值的TDatetime,将会完成工作:
procedure SetSystemDateTime(aDateTime: TDateTime);
var
  lSystemTime: TSystemTime;
  lTimeZone: TTimeZoneInformation;
 begin
  GetTimeZoneInformation(lTimeZone);
  aDateTime := aDateTime + (lTimeZone.Bias / 1440);
  DateTimeToSystemTime(aDateTime, lSystemTime);
  setSystemTime(lSystemTime);
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接