chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,555 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Wellan.Common;
|
||||
|
||||
/// <summary>
|
||||
/// 計算時數的類別
|
||||
/// </summary>
|
||||
public class TimeCalc
|
||||
{
|
||||
public string 上班時間;
|
||||
public string 下班時間;
|
||||
public string 午休開始;
|
||||
public string 午休結束;
|
||||
public int 上班分鐘數;
|
||||
public int 午休分鐘數;
|
||||
public bool 彈性上班時間;
|
||||
private BhrdDAC bhrdDao = new BhrdDAC(WGuard1.Query);
|
||||
private RtmeDAC rtmeDao = new RtmeDAC(WGuard1.Query);
|
||||
private BpsnDAC bpsnDao = new BpsnDAC(WGuard1.Query);
|
||||
private BpaaDAC bpaaDao = new BpaaDAC(WGuard1.Query);
|
||||
private BtmeDAC btmeDao = new BtmeDAC(WGuard1.Query);
|
||||
|
||||
public TimeCalc()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 計算時數之前取得各個時間點
|
||||
/// </summary>
|
||||
/// <param name="員工編號"></param>
|
||||
/// <param name="日期"></param>
|
||||
public void Init(string 員工編號, DateTime 日期)
|
||||
{
|
||||
上班時間 = WGuard1.WSetR("UNRPARTIME", 1);
|
||||
下班時間 = WGuard1.WSetR("UNRPARTIME", 2);
|
||||
午休開始 = WGuard1.WSetR("UNRPARTIME", 3);
|
||||
午休結束 = WGuard1.WSetR("UNRPARTIME", 4);
|
||||
彈性上班時間 = WGuard1.WSetR("彈性上班時間", 1) == "Y";
|
||||
|
||||
// 取員工班表
|
||||
var btmeItem = rtmeDao.SelectBtmeDay(員工編號, 日期);
|
||||
if (btmeItem != null && !String.IsNullOrEmpty(btmeItem.BTSTM) && !String.IsNullOrEmpty(btmeItem.BTETM)
|
||||
&& !String.IsNullOrEmpty(btmeItem.BTRST) && !String.IsNullOrEmpty(btmeItem.BTRED))
|
||||
{
|
||||
上班時間 = btmeItem.BTSTM;
|
||||
下班時間 = btmeItem.BTETM;
|
||||
午休開始 = btmeItem.BTRST;
|
||||
午休結束 = btmeItem.BTRED;
|
||||
}
|
||||
// 若員工班表沒有設定,則取專案預設班表
|
||||
else
|
||||
{
|
||||
// 取員工專案年度接單編號
|
||||
var rapyn = bpsnDao.GetProjectByDate(員工編號, 日期);
|
||||
if (!String.IsNullOrEmpty(rapyn))
|
||||
{
|
||||
// 取專案預設班表編號
|
||||
var bptme = bpaaDao.GetTimeTableNo(rapyn);
|
||||
if (!String.IsNullOrEmpty(bptme))
|
||||
{
|
||||
// 取班表
|
||||
btmeItem = btmeDao.SelectOne(bptme).FirstOrDefault();
|
||||
if (btmeItem != null && !String.IsNullOrEmpty(btmeItem.BTSTM) && !String.IsNullOrEmpty(btmeItem.BTETM)
|
||||
&& !String.IsNullOrEmpty(btmeItem.BTRST) && !String.IsNullOrEmpty(btmeItem.BTRED))
|
||||
{
|
||||
上班時間 = btmeItem.BTSTM;
|
||||
下班時間 = btmeItem.BTETM;
|
||||
午休開始 = btmeItem.BTRST;
|
||||
午休結束 = btmeItem.BTRED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
上班分鐘數 = 計算分鐘數(上班時間, 下班時間) - 計算分鐘數(午休開始, 午休結束);
|
||||
午休分鐘數 = 計算分鐘數(午休開始, 午休結束);
|
||||
}
|
||||
|
||||
public static int 進整小時(int 分鐘)
|
||||
{
|
||||
double 渣渣 = ((double)分鐘 / 30d) % 1d;
|
||||
|
||||
if (渣渣 > 0.5d)
|
||||
return (分鐘 / 60 + 1) * 60;
|
||||
else
|
||||
return (分鐘 / 60) * 60;
|
||||
}
|
||||
|
||||
public static int 進半小時(int 分鐘)
|
||||
{
|
||||
double 渣渣 = ((double)分鐘 / 15d) % 1d;
|
||||
|
||||
if (渣渣 > 0.5d)
|
||||
return (分鐘 / 30 + 1) * 30;
|
||||
else
|
||||
return (分鐘 / 30) * 30;
|
||||
}
|
||||
|
||||
public static int 計算分鐘數(string tm1, string tm2)
|
||||
{
|
||||
DateTime dt1 = new DateTime();
|
||||
DateTime dt2 = new DateTime();
|
||||
dt1 = dt1.AddHours(Convert.ToInt32((tm1 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm1 + "00:00").Substring(3, 2)));
|
||||
dt2 = dt2.AddHours(Convert.ToInt32((tm2 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm2 + "00:00").Substring(3, 2)));
|
||||
|
||||
return Convert.ToInt32((dt2 - dt1).TotalMinutes);
|
||||
}
|
||||
|
||||
public static string 加分鐘數(string tm1, int minutes)
|
||||
{
|
||||
DateTime dt1 = new DateTime();
|
||||
dt1 = dt1.AddHours(Convert.ToInt32((tm1 + "00:00").Substring(0, 2))).AddMinutes(Convert.ToInt32((tm1 + "00:00").Substring(3, 2)));
|
||||
dt1 = dt1.AddMinutes(minutes);
|
||||
|
||||
return dt1.ToString("HH:mm");
|
||||
}
|
||||
|
||||
public int 計算午休分鐘數(string 起時, string 迄時)
|
||||
{
|
||||
if (起時.CompareTo(午休開始) <= 0 && 迄時.CompareTo(午休結束) >= 0)
|
||||
return 午休分鐘數;
|
||||
else if (起時.CompareTo(午休開始) >= 0 && 起時.CompareTo(午休結束) <= 0 && 迄時.CompareTo(午休結束) >= 0)
|
||||
return 計算分鐘數(起時, 午休結束);
|
||||
else if (起時.CompareTo(午休開始) <= 0 && 迄時.CompareTo(午休開始) >= 0 && 迄時.CompareTo(午休結束) <= 0)
|
||||
return 計算分鐘數(午休開始, 迄時);
|
||||
else if (起時.CompareTo(午休開始) >= 0 && 起時.CompareTo(午休結束) <= 0 && 迄時.CompareTo(午休開始) >= 0 && 迄時.CompareTo(午休結束) <= 0)
|
||||
return 計算分鐘數(起時, 迄時);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int 計算請假總時數(string 員工編號, DateTime 起日, DateTime 迄日, string 起時, string 迄時, string 假別, bool is進整小時)
|
||||
{
|
||||
Init(員工編號, 起日);
|
||||
|
||||
if (String.IsNullOrEmpty(起時))
|
||||
起時 = 上班時間;
|
||||
if (String.IsNullOrEmpty(迄時))
|
||||
迄時 = 下班時間;
|
||||
|
||||
int 分鐘數;
|
||||
|
||||
// 起始與結束同一天
|
||||
if (起日 == 迄日)
|
||||
{
|
||||
分鐘數 = 計算分鐘數(起時, 迄時) - 計算午休分鐘數(起時, 迄時);
|
||||
}
|
||||
// 起始與結束不同天
|
||||
else
|
||||
{
|
||||
DateTime std = 起日;
|
||||
分鐘數 = 0;
|
||||
|
||||
while (std <= 迄日)
|
||||
{
|
||||
Init(員工編號, std);
|
||||
|
||||
// 不是假日,或是產假,要列入時數計算
|
||||
if (!bhrdDao.IsHoliday(員工編號, std) || 假別 == RPAR_TYPE.T05_產假)
|
||||
{
|
||||
// 第一天
|
||||
if (std == 起日)
|
||||
{
|
||||
分鐘數 += 計算分鐘數(起時, 下班時間) - 計算午休分鐘數(起時, 下班時間);
|
||||
}
|
||||
// 最後一天
|
||||
else if (std == 迄日)
|
||||
{
|
||||
分鐘數 += 計算分鐘數(上班時間, 迄時) - 計算午休分鐘數(上班時間, 迄時);
|
||||
}
|
||||
// 中間其他天
|
||||
else
|
||||
{
|
||||
分鐘數 += 上班分鐘數;
|
||||
}
|
||||
}
|
||||
|
||||
std = std.AddDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (is進整小時)
|
||||
分鐘數 = 進半小時(分鐘數);
|
||||
return 分鐘數;
|
||||
}
|
||||
|
||||
public int 計算請假跨日數(string 員工編號, DateTime 起日, DateTime 迄日, string 假別)
|
||||
{
|
||||
// 起始與結束同一天
|
||||
if (起日 == 迄日)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// 起始與結束不同天
|
||||
else
|
||||
{
|
||||
DateTime std = 起日;
|
||||
int 天數 = 0;
|
||||
|
||||
while (std <= 迄日)
|
||||
{
|
||||
// 不是假日,或是產假,要列入時數計算
|
||||
if (!bhrdDao.IsHoliday(員工編號, std) || 假別 == RPAR_TYPE.T05_產假)
|
||||
{
|
||||
天數++;
|
||||
}
|
||||
std = std.AddDays(1);
|
||||
}
|
||||
return 天數;
|
||||
}
|
||||
}
|
||||
|
||||
public int 計算請假當日時數(string 員工編號, DateTime 日期, DateTime 起日, DateTime 迄日, string 起時, string 迄時, string 假別, bool is進整小時)
|
||||
{
|
||||
int 當日分鐘數 = 0;
|
||||
|
||||
// 起始與結束同一天
|
||||
if (起日 == 迄日)
|
||||
{
|
||||
Init(員工編號, 起日);
|
||||
|
||||
if (String.IsNullOrEmpty(起時))
|
||||
起時 = 上班時間;
|
||||
if (String.IsNullOrEmpty(迄時))
|
||||
迄時 = 下班時間;
|
||||
|
||||
當日分鐘數 = 計算分鐘數(起時, 迄時) - 計算午休分鐘數(起時, 迄時);
|
||||
|
||||
if (is進整小時)
|
||||
return 進整小時(當日分鐘數);
|
||||
else
|
||||
return 當日分鐘數;
|
||||
}
|
||||
// 起始與結束不同天
|
||||
else
|
||||
{
|
||||
DateTime std = 起日;
|
||||
|
||||
while (std <= 迄日)
|
||||
{
|
||||
Init(員工編號, std);
|
||||
|
||||
// 不是假日,或是產假,要列入時數計算
|
||||
if (!bhrdDao.IsHoliday(員工編號, std) || 假別 == RPAR_TYPE.T05_產假)
|
||||
{
|
||||
// 第一天
|
||||
if (std == 起日)
|
||||
{
|
||||
當日分鐘數 = 計算分鐘數(起時, 下班時間) - 計算午休分鐘數(起時, 下班時間);
|
||||
}
|
||||
// 最後一天
|
||||
else if (std == 迄日)
|
||||
{
|
||||
當日分鐘數 = 計算分鐘數(上班時間, 迄時) - 計算午休分鐘數(上班時間, 迄時);
|
||||
}
|
||||
// 中間其他天
|
||||
else
|
||||
{
|
||||
當日分鐘數 = 上班分鐘數;
|
||||
}
|
||||
// 只計算一天,就返回
|
||||
if (日期 == std)
|
||||
{
|
||||
if (is進整小時)
|
||||
return 進整小時(當日分鐘數);
|
||||
else
|
||||
return 當日分鐘數;
|
||||
}
|
||||
}
|
||||
else
|
||||
當日分鐘數 = 0;
|
||||
|
||||
std = std.AddDays(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int 計算加班時數(string 員工編號, DateTime 日期, string 起時, string 迄時, bool 休息日)
|
||||
{
|
||||
Init(員工編號, 日期);
|
||||
|
||||
int 分鐘數 = 計算分鐘數(起時, 迄時) - 計算午休分鐘數(起時, 迄時);
|
||||
|
||||
// 2018/3/1 之後休息日加班不進整 4 小時
|
||||
if (休息日 && 日期.CompareTo(new DateTime(2018, 3, 1)) < 0)
|
||||
分鐘數 = (int)(Math.Ceiling((decimal)分鐘數 / 240m) * 240m);
|
||||
|
||||
return 分鐘數;
|
||||
}
|
||||
|
||||
//public static void 拆分加班時數(int 分鐘數, bool 是假日, out int 前二, out int 後二, out int 假日)
|
||||
//{
|
||||
// 前二 = 0;
|
||||
// 後二 = 0;
|
||||
// 假日 = 0;
|
||||
|
||||
// if (是假日)
|
||||
// 假日 = 分鐘數;
|
||||
// else
|
||||
// {
|
||||
// if (分鐘數 < 120)
|
||||
// 前二 = 分鐘數;
|
||||
// else
|
||||
// {
|
||||
// 前二 = 120;
|
||||
// 後二 = 分鐘數 - 120;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
public int 計算差旅時數(string 員工編號, DateTime 起日, DateTime 迄日, string 起時, string 迄時)
|
||||
{
|
||||
Init(員工編號, 起日);
|
||||
|
||||
if (String.IsNullOrEmpty(起時))
|
||||
起時 = 上班時間;
|
||||
if (String.IsNullOrEmpty(迄時))
|
||||
迄時 = 下班時間;
|
||||
|
||||
int 分鐘數;
|
||||
|
||||
// 起始與結束同一天
|
||||
if (起日 == 迄日)
|
||||
{
|
||||
分鐘數 = 計算分鐘數(起時, 迄時) - 計算午休分鐘數(起時, 迄時);
|
||||
}
|
||||
// 起始與結束不同天
|
||||
else
|
||||
{
|
||||
DateTime std = 起日;
|
||||
分鐘數 = 0;
|
||||
|
||||
while (std <= 迄日)
|
||||
{
|
||||
Init(員工編號, std);
|
||||
|
||||
// 第一天
|
||||
if (std == 起日)
|
||||
{
|
||||
分鐘數 += 計算分鐘數(起時, 下班時間) - 計算午休分鐘數(起時, 下班時間);
|
||||
}
|
||||
// 最後一天
|
||||
else if (std == 迄日)
|
||||
{
|
||||
分鐘數 += 計算分鐘數(上班時間, 迄時) - 計算午休分鐘數(上班時間, 迄時);
|
||||
}
|
||||
// 中間其他天
|
||||
else
|
||||
{
|
||||
分鐘數 += 上班分鐘數;
|
||||
}
|
||||
|
||||
std = std.AddDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 分鐘數;
|
||||
}
|
||||
|
||||
public int 計算差旅當日時數(string 員工編號, DateTime 日期, DateTime 起日, DateTime 迄日, string 起時, string 迄時)
|
||||
{
|
||||
Init(員工編號, 起日);
|
||||
|
||||
if (String.IsNullOrEmpty(起時))
|
||||
起時 = 上班時間;
|
||||
if (String.IsNullOrEmpty(迄時))
|
||||
迄時 = 下班時間;
|
||||
|
||||
int 分鐘數;
|
||||
|
||||
// 起始與結束同一天
|
||||
if (起日 == 迄日)
|
||||
{
|
||||
分鐘數 = 計算分鐘數(起時, 迄時) - 計算午休分鐘數(起時, 迄時);
|
||||
if (日期 == 起日)
|
||||
return 分鐘數;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
// 起始與結束不同天
|
||||
else
|
||||
{
|
||||
DateTime std = 起日;
|
||||
|
||||
while (std <= 迄日)
|
||||
{
|
||||
Init(員工編號, std);
|
||||
分鐘數 = 0;
|
||||
|
||||
// 第一天
|
||||
if (std == 起日)
|
||||
{
|
||||
分鐘數 = 計算分鐘數(起時, 下班時間) - 計算午休分鐘數(起時, 下班時間);
|
||||
}
|
||||
// 最後一天
|
||||
else if (std == 迄日)
|
||||
{
|
||||
分鐘數 = 計算分鐘數(上班時間, 迄時) - 計算午休分鐘數(上班時間, 迄時);
|
||||
}
|
||||
// 中間其他天
|
||||
else
|
||||
{
|
||||
分鐘數 = 上班分鐘數;
|
||||
}
|
||||
|
||||
if (日期 == std)
|
||||
return 分鐘數;
|
||||
|
||||
std = std.AddDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static DateTime 轉換時區(string 時區, DateTime 日期, string 時間)
|
||||
{
|
||||
// 解析30小時制(小時可能 >= 24,表示跨入隔日凌晨)
|
||||
var parts = 時間.Split(':');
|
||||
var timeSpan = new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
|
||||
var sourceTime = 日期.Date.Add(timeSpan);
|
||||
|
||||
if (string.IsNullOrEmpty(時區) || string.Compare(時區, "Taipei Standard Time") == 0)
|
||||
{
|
||||
return sourceTime;
|
||||
}
|
||||
|
||||
// 重要:將 Kind 設為 Unspecified
|
||||
sourceTime = DateTime.SpecifyKind(sourceTime, DateTimeKind.Unspecified);
|
||||
|
||||
// 轉換到目標時區
|
||||
var sourceZone = TimeZoneInfo.FindSystemTimeZoneById("Taipei Standard Time");
|
||||
var targetZone = TimeZoneInfo.FindSystemTimeZoneById(時區);
|
||||
|
||||
var utcTime = TimeZoneInfo.ConvertTimeToUtc(sourceTime, sourceZone);
|
||||
var targetTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, targetZone);
|
||||
|
||||
return targetTime;
|
||||
}
|
||||
|
||||
public static string 轉換打卡時區(string 時區, DateTime 打卡日期, string 打卡時間)
|
||||
{
|
||||
var targetTime = 轉換時區(時區, 打卡日期, 打卡時間);
|
||||
|
||||
// 輸出 30 小時制時分秒
|
||||
// 06:00 之前算前一天,小時數加 24
|
||||
int outputHours = targetTime.Hour;
|
||||
if (targetTime.TimeOfDay < new TimeSpan(6, 0, 0))
|
||||
outputHours += 24;
|
||||
|
||||
return string.Format("{0:00}:{1:00}:{2:00}", outputHours, targetTime.Minute, targetTime.Second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 30 小時制的日期類別
|
||||
/// </summary>
|
||||
public class DateAndTime
|
||||
{
|
||||
/// <summary>
|
||||
/// 台灣工作日期
|
||||
/// </summary>
|
||||
public DateTime TwWorkDate;
|
||||
|
||||
/// <summary>
|
||||
/// 台灣日曆日期
|
||||
/// </summary>
|
||||
public DateTime TwCalendarDate;
|
||||
|
||||
/// <summary>
|
||||
/// 台灣時間
|
||||
/// </summary>
|
||||
public string TwTime;
|
||||
|
||||
/// <summary>
|
||||
/// 當地日期
|
||||
/// </summary>
|
||||
public DateTime LocalDate;
|
||||
|
||||
/// <summary>
|
||||
/// 當地時間
|
||||
/// </summary>
|
||||
public string LocalTime;
|
||||
|
||||
/// <summary>
|
||||
/// 時區名稱
|
||||
/// </summary>
|
||||
public string TimezoneName;
|
||||
|
||||
/// <summary>
|
||||
/// 時區ID
|
||||
/// </summary>
|
||||
public string TimeZoneID;
|
||||
|
||||
/// <summary>
|
||||
/// 打卡的日期
|
||||
/// </summary>
|
||||
public DateTime CardDate;
|
||||
|
||||
public DateAndTime(DateTime twWorkDate, DateTime twCalendarDate, string twTime, DateTime localDate, string localTime, string timezoneName, string timezoneID) : base()
|
||||
{
|
||||
TwWorkDate = twWorkDate;
|
||||
TwCalendarDate = twCalendarDate;
|
||||
TwTime = twTime;
|
||||
LocalDate = localDate;
|
||||
LocalTime = localTime;
|
||||
TimezoneName = timezoneName;
|
||||
TimeZoneID = timezoneID;
|
||||
CardDate = string.IsNullOrEmpty(TimeZoneID) || string.Compare(TimeZoneID, "Taipei Standard Time") == 0
|
||||
? TwWorkDate
|
||||
: TwCalendarDate;
|
||||
}
|
||||
|
||||
public static DateAndTime GetNow(string bpeno)
|
||||
{
|
||||
var twNow = DateTime.UtcNow.AddHours(8);
|
||||
var rasnDao = new RasnDAC(WGuard1.Query);
|
||||
string timezoneID;
|
||||
string timezoneName;
|
||||
rasnDao.GetTimeZone(bpeno, twNow, out timezoneID, out timezoneName);
|
||||
|
||||
var twCalendarDate = twNow.Date;
|
||||
var twWorkDate = twNow.Date;
|
||||
var localNow = TimeCalc.轉換時區(timezoneID, twNow.Date, twNow.ToString("HH:mm:ss"));
|
||||
var localDate = localNow.Date;
|
||||
var twHourOffset = 0;
|
||||
var localHourOffset = 0;
|
||||
|
||||
// 06:00 之前算前一天
|
||||
if (twNow.TimeOfDay < new TimeSpan(6, 0, 0))
|
||||
{
|
||||
twWorkDate = twWorkDate.AddDays(-1);
|
||||
twHourOffset = 24;
|
||||
}
|
||||
if (localNow.TimeOfDay < new TimeSpan(6, 0, 0))
|
||||
{
|
||||
localDate = localDate.AddDays(-1);
|
||||
localHourOffset = 24;
|
||||
}
|
||||
|
||||
return new DateAndTime(
|
||||
twWorkDate,
|
||||
twCalendarDate,
|
||||
string.Format("{0:00}:{1:00}:{2:00}", twNow.TimeOfDay.Hours + twHourOffset, twNow.TimeOfDay.Minutes, twNow.Second),
|
||||
localDate,
|
||||
string.Format("{0:00}:{1:00}:{2:00}", localNow.TimeOfDay.Hours + localHourOffset, localNow.TimeOfDay.Minutes, localNow.Second),
|
||||
timezoneName,
|
||||
timezoneID
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user