I have a requirement to obtain number of days passed since creation date. This number would need to minus the weekends. I have only some functions : JulianDay, JulianWeek, JulianYear to get Julian date values, I also have Today which returns the date of today, time stamp which returns date and time. I have manage to get the difference of today-creation date by using: JulianDay(today)-JulianDay(creation date) but I still can't wrap my head around subtracting the weekends
3 に答える
質問で引用した関数が何をするのか完全にはわかりませんが、基本的な日付演算を行って、2 つの特定の日付間の日数を判断することに慣れているようです。難しいのは、週末に何日差し引くかを考え出すことです。
これは、次の 2 つの機能で実現できると思います。
- 2 つの日付を指定して、その間の日数を返します。これを呼び出す
DAYS(date-1, date-2)
- 日付を指定すると、曜日を返します (1 = 月曜日 ... 7 = 日曜日)。これを呼び出す
DAY-OF-WEEK(date)
これらの機能を使用すると、次のことができます。
- 日付範囲の完全な週を計算します。
WEEKS = DAYS(date-1, date2) mod 7
- 完全な週の一部ではなく、日を計算します。
DAYS-LEFT = DAYS(date-1, date-2) - (WEEKS * 7)
- 最終日が何曜日にあたるかを判別します。
LAST-DAY = DAY-OF-WEEK(date-2)
次のように、部分的な週からの数を調整DAYS-LEFT
します。
if DAYS-LEFT > 0 then
case LAST-DAY
when 6 then /* Saturday */
DAYS-LEFT = DAYS-LEFT - 1
when 7 then /* Sunday */
if DAYS-LEFT = 1 then
DAYS-LEFT = 0
else
DAYS-LEFT = DAYS-LEFT - 2
end-if
when other /* Monday through Friday */
case DAYS-LEFT - LAST-DAY
when > 1 then
DAYS-LEFT = DAYS-LEFT - 2
when = 1 then
DAYS-LEFT = DAYS-LEFT - 1
when other
DAYS-LEFT = DAYS-LEFT /* no adjustment */
end-case
end-case
end-if
DAYS-EXCLUDING-WEEKENDS = DAYS(date-1, date-2) - (WEEKS * 2) + DAYS-LEFT
関数を持っているか、作成できると思いますDAYS(date-1, date-2)
。次のビットは、特定の日付が何曜日にあたるかを判断することです。これを行うアルゴリズムは、ツェラーの合同と呼ばれます。ウィキペディアはそれをうまく説明しているので、ここでアルゴリズムを繰り返すことはしません。
これでうまくいくことを願っています...
関数JulianDay(y,m,d)
は各日付のシリアル番号を返します。議論のために、2456478 をJulianDay(2013,7,4)
返すとしましょう。翌日は 2456479、次に 2456480 などになります。そして、2 日間の差がdiffであるとしましょう。
それぞれが 5 つの平日を含むdiffの完全な週の数はdiff // 7
(整数除算であるため、切り捨てられます) です。したがって、diffが 25 の場合は、 25 // 7 = 3
1 週間に 1 週間プラス 1diff % 7 = 4
日が追加されます。丸 3 週間には 15 の平日が含まれます。開始する曜日は問いません。したがって、平日がどのようになるかを確認するには、余分な 4 日間を考慮する必要があります。
関数が返す数値はJulianDay
、曜日を計算するためにモジュロ 7 を取ることができます。私のJulianDay
関数では、モジュロ 5 は土曜日を表し、モジュロ 6 は日曜日を表します。余分な 4 日間は、期間の開始時の 4 日間または終了時の 4 日間のいずれかであると見なすことができます。他のすべての日は、それぞれ 5 つの平日がある連続する 1 週間の一部であるため、問題ではありません。最初の 4 日間を選択するとします。次に、JulianDay
初日の をモジュロ 7 で取り、次に初日のJulianDay
を 1 でモジュロ 7 を足し、次にJulianDay
初日の を足して 2 をモジュロ 7 で取り、次にJulianDay
初日の を足して 3 をモジュロ 7 で取り、そのうちの何回が平日であるかを決定します。 、それを完全な週の平日の数に追加します。
必要なのはJulianDay
関数だけです。
このコードは、あなたが望むことをするはずです:
Date fromDate = new Date(System.currentTimeMillis()-(30L*24*60*60*1000)); // 30 days ago
Date toDate = new Date(System.currentTimeMillis()); // now
Calendar cal = Calendar.getInstance();
cal.setTime(fromDate);
int countDays = 0;
while (toDate.compareTo(cal.getTime()) > 0) {
if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY)
countDays++;
cal.add(Calendar.DATE, 1);
}
System.out.println(countDays);