入力として tDateTime と整数を取り、その tDateTime を (int) か月進めた後、setlocaltime を使用してシステム時刻を設定する関数のコード サンプルが欲しいです。時間は変わらないはずです。
擬似コードの例
SetNewTime(NOW,2);
私が直面している問題は、かなり苛立たしいものです。incmonth などを tDateTime で使用することはできません。tDate のみなどです。
以下は、私にとって機能する完全なコマンドライン プログラムです。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.
IncMonthはTDateTimeで動作するはずです:
function IncMonth ( const StartDate : TDateTime {; NumberOfMonths : Integer = 1} ) : TDateTime;
TDateは実際には単なるTDateTimeであり、慣例により、端数を無視することに注意してください。
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;
あなたの疑似コードに基づいて:
procedure SetNewTime(aDateTime: TDateTime; aMonths: Integer);
var
lSystemTime: TSystemTime;
begin
DateTimeToSystemTime(aDateTime, lSystemTime);
Inc(lSystemTime.wMonth, aMonths);
setSystemTime(lSystemTime);
end;
あなたの質問に決定的な回答を提供するのに十分な情報がありません。
現在の月の日が将来の月に存在しない場合にどうするかを考えてください。たとえば、1 月 31 日 + 1 か月とします。(1 年の 7 か月は 31 日で、残りはそれより少ないです。) 年をインクリメントし、開始日がうるう年の 2 月 29 日である場合も、同じ問題が発生します。したがって、すべての日付で一貫して機能する普遍的な IncMonth または IncYear 関数は存在しません。
興味のある方には、2 つの日付間の月数と日数を計算する方法に関する、この種の計算に内在する複雑さに関するJulian Bucknall の記事を心からお勧めします。
以下は、一般的な日付計算に異常を導入しない唯一の可能な一般的な日付インクリメント関数です。しかし、これを達成するには、おそらく自分がプログラミングしている特定のアプリケーションの正確な要件を持っていると思われるプログラマーに責任を戻します。
IncDay - 日数を加算または減算します。
IncWeek - 週数を加算または減算します。
ただし、組み込み関数を使用する必要がある場合は、少なくとも、それらが目的どおりに機能することを確認してください。DateUtils および SysUtils ユニットを見てください。これらの関数のソース コードがあることは、Delphi の最も優れた点の 1 つです。そうは言っても、組み込み関数の完全なリストは次のとおりです。
IncDay - 日数を加算または減算します。
IncWeek - 週数を加算または減算します。
IncMonth - 月数を加算または減算します。
IncYear - 年数を加算または減算します。
質問の 2 番目の部分である、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;