スタック・オーバーフロー Asked by Kow1210 on February 12, 2021
C#で時間のかかった一部を判定したいのですが…
例えば
var start = TimeSpan.Parse("19:00");//ここは変動する
var end = TimeSpan.Parse("3:00"); //次の日の3時 ここも変動する
start と end の間に 22:00~5:00がある場合、何時間なのかを知りたいのです。
よろしくお願いします。
単純に 終了時間が 開始時間より小さい場合には 1日加算して計算します。
TimeSpan は + - < > 等の演算子がオーバーロードされて定義されているので
時間としての加減算ができます。
var start = TimeSpan.Parse("19:00");//ここは変動する
var end = TimeSpan.Parse("3:00"); //次の日の3時 ここも変動する
if (end < start) {
end = end.Add(TimeSpan.FromDays(1));
// end += TimeSpan.FromDays(1); でもよい
}
TimeSpan diff = end - start;
Console.WriteLine(diff.ToString(@".hh:mm"));
start と end の間に 22:00~5:00がある場合、何時間なのかを知りたいのです。
見落としていました。
区間の交差があるか判定するためには
開始時点の 最大値と 終了時点の 最小値を 求めれば簡単です。
TimeSpan CalcCross(TimeSpan begin, TimeSpan end)
{
if (end < begin) {
end += TimeSpan.FromDays(1);
}
TimeSpan m1 = TimeSpan.Parse("22:00");
TimeSpan m2 = TimeSpan.Parse("1.05:00");
TimeSpan x1 = Max(begin ,m1);
TimeSpan x2 = Min(end, m2);
TimeSpan cross = x2 - x1;
if (cross < TimeSpan.Zero) return TimeSpan.Zero;
else return cross;
}
TimeSpan Min(TimeSpan t1, TimeSpan t2)
{
if (t1 > t2) return t2;
else return t1;
}
TimeSpan Max(TimeSpan t1, TimeSpan t2)
{
if (t1 > t2) return t1;
else return t2;
}
[Test]
public void Test1()
{
// 5パターンを試せばよい
Console.WriteLine(CalcCross(TimeSpan.Parse("9:00"), TimeSpan.Parse("19:00"))); // 重ならない 0:00:00
Console.WriteLine(CalcCross(TimeSpan.Parse("19:00"), TimeSpan.Parse("6:00"))); // 開始と終了を含む 7:00:00
Console.WriteLine(CalcCross(TimeSpan.Parse("23:00"), TimeSpan.Parse("1:00"))); // 範囲が含まれる 2:00:00
Console.WriteLine(CalcCross(TimeSpan.Parse("20:00"), TimeSpan.Parse("2:00"))); // 前半が重なる 4:00:00
Console.WriteLine(CalcCross(TimeSpan.Parse("23:00"), TimeSpan.Parse("6:00"))); // 後半が重なる 6:00:00
}
Answered by k system on February 12, 2021
var start = TimeSpan.Parse("19:00");//ここは変動する
var end = TimeSpan.Parse("3:00"); //次の日の3時 ここも変動する
var day = new TimeSpan(1, 0, 0, 0); //次の日のため1日
TimeSpan ans = end + day - start;
ではだめですか?
Answered by 池田茂樹 on February 12, 2021
おそらく、深夜勤務時間の計算がやりたいのだと思われます。
VBでのこんな記事がありますので、参考にしてください。
VB2013での時間帯判定で困っています
上記を参考に、C#で作ってみたのが以下になります。
出退勤の情報には、時刻だけではなく、日付も必要になります。
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
DateTime workStart = DateTime.Parse("2019-06-21 19:00");
DateTime workEnd = DateTime.Parse("2019-06-22 03:00");
TimeSpan workMidNight = CalcMidNightWork(workStart, workEnd);
Console.WriteLine("出勤日時 = " + workStart.ToString());
Console.WriteLine("退勤日時 = " + workEnd.ToString());
Console.WriteLine("深夜勤務 = " + workMidNight.ToString());
return;
}
// 計算対象時間帯の開始・終了時刻のペア情報クラス
public class TimeSpanPair
{
public TimeSpan TSStart { get; set; }
public TimeSpan TSEnd { get; set; }
}
// 計算対象(深夜)時間帯のリスト:計算対象日の00:00が起点
static List<TimeSpanPair> tsMidNight = new List<TimeSpanPair>() {
new TimeSpanPair(){ TSStart = new TimeSpan(0,0,0), TSEnd = new TimeSpan(5,0,0) }, // 00:00-05:00
new TimeSpanPair(){ TSStart = new TimeSpan(22,0,0), TSEnd = new TimeSpan(24,0,0) } // 22:00-24:00
};
/// <summary>
/// 深夜勤務時間取得(複数日をまたぐ連続勤務も計算可)
/// </summary>
/// <param name="startTime">出勤日付時刻</param>
/// <param name="endTime">退勤日付時刻</param>
/// <returns>深夜勤務時間</returns>
static TimeSpan CalcMidNightWork(DateTime startTime, DateTime endTime)
{
TimeSpan result = new TimeSpan(0, 0, 0, 0); // 深夜勤務時間報告初期値00:00
DateTime workStart = startTime; // 該当日毎の勤務開始時刻
DateTime workDate = workStart.Date; // 該当日の00:00
DateTime tspStart = workDate; // 計算対象(深夜)時間帯の開始時刻作業用
DateTime tspEnd = workDate; // 計算対象(深夜)時間帯の終了時刻作業用
do
{
workDate = workStart.Date; // 該当日の00:00を計算ベース値として設定
// 計算対象(深夜)時間帯リストの要素数でループする
foreach (TimeSpanPair tsp in tsMidNight)
{
tspStart = workDate.Add(tsp.TSStart); // 計算対象時間帯の開始時刻設定
tspEnd = workDate.Add(tsp.TSEnd); // 計算対象時間帯の終了時刻設定
// 勤務時間が計算対象時間帯に入っているか判定
if (!((workStart >= tspEnd) || (endTime <= tspStart)))
{
tspStart = (tspStart < workStart) ? workStart : tspStart; // 実際の開始時刻に調整
tspEnd = (tspEnd > endTime) ? endTime : tspEnd; // 実際の終了時刻に調整
result += (tspEnd - tspStart); // 計算対象時間帯の勤務時間を計算して報告値に加算
}
}
workStart = workDate.AddDays(1.0); // 翌日の勤務開始時刻を00:00とする
} while (workStart < endTime); // 勤務時間が残っている間はループする
return result;
}
}
}
Answered by kunif on February 12, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP