プログラム実装

勤怠管理システムの自作-限度時間の計算処理

平成10年12月28日 労働省告示 第154号
https://www.mhlw.go.jp/content/12602000/000348459.pdf

同じことがアラビア数字で書かれた資料
http://labor.tank.jp/wwwsiryou/messages/58.html

上記の計算をそのままC#にした結果

/// <summary>
/// 労働基準法第36条
/// 平成10年12月28日 労働省告示第154号 第3条
/// 限度時間(1日を超え3か月以内の期間)を算出する。
/// (もう一方のメソッドに当てはまらない場合、こっちを使えばOK)
/// </summary>
/// <param name="month">期間 月</param>
/// <param name="day">期間 日</param>
/// <param name="definiteDayCount">期間 月 と 期間 日 の明確な日数が判明している場合はこちらに指定する</param>
/// <returns>限度時間 (TimeSpan.Ticks)</returns>
public static long Law36_GetLimitTime(int month, int day, int? definiteDayCount = null)
{
    // 月
    // ピッタリである場合
    if (month == 3 && day == 0)
    {
        // 3箇月
        return TimeSpan.FromHours(120).Ticks;
    }
    if (month == 2 && day == 0)
    {
        // 2箇月
        return TimeSpan.FromHours(81).Ticks;
    }
    if (month == 1 && day == 0)
    {
        // 1箇月
        return TimeSpan.FromHours(45).Ticks;
    }

    // 「当該日数」
    decimal dayCount;

    if (definiteDayCount.HasValue)
    {
        // 明確な日数が分かる場合はそのまま使う
        dayCount = definiteDayCount.Value;
    }
    else
    {
        // 明確な日数が不明な場合は1か月=30日として日数を算出する。
        // 労働省告示第154号に「八十一時間に当該日数を六十で除して得た数」といった記述があり、1か月=30日と考えていることが推測できる。
        dayCount = (month * 30) + day;
    }

    // 1時間未満の端数があるときは、これを1時間に切り上げる

    // 5
    // 2箇月を超え3箇月未満の日数を単位とする期間
    if (month == 2)
    {
        // 120時間に当該日数を90で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(120m * (dayCount / 90m));

        // その時間が81時間を下回るときは81時間
        if (wk < 81)
        {
            wk = 81;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 4
    // 1箇月を超え2箇月末満の日数を単位とする期間
    if (month == 1)
    {
        // 81時間に当該日数を60で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(81m * (dayCount / 60m));

        // その時間が45時間を下回るときは、45時間
        if (wk < 45)
        {
            wk = 45;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 週
    // ピッタリである場合
    if (day == 28)
    {
        // 4週間
        return TimeSpan.FromHours(43).Ticks;
    }
    if (day == 14)
    {
        // 2週間
        return TimeSpan.FromHours(27).Ticks;
    }
    if (day == 7)
    {
        // 1週間
        return TimeSpan.FromHours(15).Ticks;
    }

    // 3
    // 2週間を超え4週間未満の日数を単位とする期間
    if (14 < day && day < 28)
    {
        // 43時間に当該日数を28で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(43m * (dayCount / 28m));

        // その時間が27時間を下回るときは27時間
        if (wk < 27)
        {
            wk = 27;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 2
    // 1週間を超え2週間未満の日数を単位とする期間
    if (7 < day && day < 14)
    {
        // 27時間に当該日数を14で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(27m * (dayCount / 14m));
        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 1
    // 1日を超え1週間未満の日数を単位とする期間
    if (1 < day && day < 7)
    {
        // 15時間に当該日数を7で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(15m * (dayCount / 7m));
        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    return 0;
}

/// <summary>
/// 労働基準法第36条
/// 平成10年12月28日 労働省告示第154号 第4条
/// 労働時間の延長の限度を算出する。
/// (1年単位の変形労働時間制、かつ、対象期間が3か月を超える場合専用)
/// </summary>
/// <param name="month">期間 月</param>
/// <param name="day">期間 日</param>
/// <param name="definiteDayCount">期間 月 と 期間 日 の明確な日数が判明している場合はこちらに指定する</param>
/// <returns>限度時間 (TimeSpan.Ticks)</returns>
public static long Law36_GetLimitTimeFlex1Y3MOver(int month, int day, int? definiteDayCount = null)
{
    // 月
    // ピッタリである場合
    if (month == 3 && day == 0)
    {
        // 3箇月
        return TimeSpan.FromHours(110).Ticks;
    }
    if (month == 2 && day == 0)
    {
        // 2箇月
        return TimeSpan.FromHours(75).Ticks;
    }
    if (month == 1 && day == 0)
    {
        // 1箇月
        return TimeSpan.FromHours(42).Ticks;
    }

    // 「当該日数」
    decimal dayCount;

    if (definiteDayCount.HasValue)
    {
        // 明確な日数が分かる場合はそのまま使う
        dayCount = definiteDayCount.Value;
    }
    else
    {
        // 明確な日数が不明な場合は1か月=30日として日数を算出する。
        // 労働省告示第154号に「八十一時間に当該日数を六十で除して得た数」といった記述があり、1か月=30日と考えていることが推測できる。
        dayCount = (month * 30) + day;
    }

    // 1時間未満の端数があるときは、これを1時間に切り上げる

    // 5
    // 2箇月を超え3箇月未満の日数を単位とする期間
    if (month == 2)
    {
        // 110時間に当該日数を90で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(110m * (dayCount / 90m));

        // その時間が75時間を下回るときは75時間
        if (wk < 75)
        {
            wk = 75;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 4
    // 1箇月を超え2箇月末満の日数を単位とする期間
    if (month == 1)
    {
        // 75時間に当該日数を60で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(75m * (dayCount / 60m));

        // その時間が42時間を下回るときは、42時間
        if (wk < 42)
        {
            wk = 42;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 週
    // ピッタリである場合
    if (day == 28)
    {
        // 4週間
        return TimeSpan.FromHours(40).Ticks;
    }
    if (day == 14)
    {
        // 2週間
        return TimeSpan.FromHours(25).Ticks;
    }
    if (day == 7)
    {
        // 1週間
        return TimeSpan.FromHours(14).Ticks;
    }

    // 3
    // 2週間を超え4週間未満の日数を単位とする期間
    if (14 < day && day < 28)
    {
        // 40時間に当該日数を28で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(40m * (dayCount / 28m));

        // その時間が25時間を下回るときは27時間
        if (wk < 25)
        {
            wk = 25;
        }

        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 2
    // 1週間を超え2週間未満の日数を単位とする期間
    if (7 < day && day < 14)
    {
        // 25時間に当該日数を14で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(25m * (dayCount / 14m));
        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    // 1
    // 1日を超え1週間未満の日数を単位とする期間
    if (1 < day && day < 7)
    {
        // 14時間に当該日数を7で除して得た数を乗じて得た時間
        var wk = Math.Ceiling(14m * (dayCount / 7m));
        return TimeSpan.FromHours(Convert.ToInt32(wk)).Ticks;
    }

    return 0;
}
タイトルとURLをコピーしました