C#知識系列
最近筆者在寫測試的時候,發現到非常特別狀況,讓我少了這個測試案例…我一直以為年底都是53週,原來有52週
public interface IDateTimeHelper
{
/// <summary>
/// 取時間-避免相依DataTime方便寫單元測試
/// </summary>
/// <returns></returns>
DateTime GetDateTimeNow();
/// <summary>
/// 抓當年度本週
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
int GetCurrentYearWeekNo(DateTime today);
/// <summary>
/// 抓本年度當週的上一週
/// </summary>
/// <param name="today"></param>
/// <returns></returns>
int GetYearLastWeekNo(DateTime today);
/// <summary>
/// 抓本年度當週的前兩週
/// </summary>
/// <param name="today"></param>
/// <returns></returns>
int GetYearTwoAgoWeekNo(DateTime today);
}
public class DateTimeHelper : IDateTimeHelper
{
public DateTime GetDateTimeNow()
{
return DateTime.Now;
}
public int GetYearLastWeekNo(DateTime today)
{
int yearWeekNo = GetCurrentYearWeekNo(today);
return (yearWeekNo % 100 == 1) ? GetYearFinallyWeekNo(today.Year)
: yearWeekNo - 1;
}
public int GetYearTwoAgoWeekNo(DateTime today)
{
int yearWeekNo = GetCurrentYearWeekNo(today);
int weekNo = (yearWeekNo % 100);
if (weekNo == 1)
return GetYearFinallyWeekNo(today.Year) - 1;
else if (weekNo == 2)
return GetYearFinallyWeekNo(today.Year);
else
return yearWeekNo - 2;
}
/// <summary>
/// 抓當年度本週
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public int GetCurrentYearWeekNo(DateTime today)
{
//var firstSaturday = today.AddDays(6 - (int)today.DayOfWeek);
//int week = (firstSaturday.DayOfYear - 1) / 7 + 1;
//string yeeaNo = firstSaturday.ToString("yyyy") + week.ToString("D2");
//return Convert.ToInt32(yeeaNo);
GregorianCalendar gc = new GregorianCalendar();
return Convert.ToInt32(today.Year.ToString() + gc.GetWeekOfYear(today,
CalendarWeekRule.FirstDay, DayOfWeek.Monday).ToString().PadLeft(2, '0'));
}
/// <summary>
/// 去年的十二月底最後一週
/// </summary>
/// <param name="year"></param>
/// <param name="reduceNum"></param>
/// <returns></returns>
private int GetYearFinallyWeekNo(int year)
{
//int lastYear = year - 1;
//string yearWeekNo = string.Empty;
//DateTime firstSaturday = new DateTime();
//int week = 0;
//int i = 0;
//do
//{
// DateTime end = new DateTime(lastYear, 12, 31 - i); //該年最後一天/因為
// firstSaturday = end.AddDays(6 - (int)end.DayOfWeek);
// week = (firstSaturday.DayOfYear - 1) / 7 + 1;
// i++;
//} while ((week == 1));
//yearWeekNo = firstSaturday.ToString("yyyy") + week.ToString("D2");
//return Convert.ToInt32(yearWeekNo);
int lastYear = year - 1;
DateTime end = new DateTime(lastYear, 12, 31); //該年最後一天
GregorianCalendar gc = new GregorianCalendar();
return Convert.ToInt32(lastYear.ToString() + (gc.GetWeekOfYear(end,
CalendarWeekRule.FirstDay, DayOfWeek.Monday)).ToString().PadLeft(2, '0')); //該年的週數
}
}
/// <summary>
/// 日期測試
/// <para> 測試命名:Should_預期行為(ExpectedBehavior)_When_執行測試案例的狀態</para>
/// </summary>
[TestFixture]
public class DateTimeHelper_Ut
{
public IDateTimeHelper _dateTimeHelper;
[SetUp]
public void Setup()
{
_dateTimeHelper = new DateTimeHelper();
}
/// <summary>
/// 當取現在日期,應該得到年週
/// 當2020/1/1,應該202001
/// 當2020/2/1,應該202005
/// 當2020/12/31,應該202053
/// 當2021/1/1,應該202101
/// 當2021/12/31,應該202153
/// 當2022/1/1,應該202201
/// 當2022/12/31,應該202253
/// </summary>
/// <param name="expected"></param>
/// <param name="year"></param>
/// <param name="month"></param>
/// <param name="day"></param>
[Test]
[TestCase(202001, 2020, 1, 1)]
[TestCase(202005, 2020, 2, 1)]
[TestCase(202053, 2020, 12, 31)]
[TestCase(202101, 2021, 1, 1)]
[TestCase(202153, 2021, 12, 31)]
[TestCase(202201, 2022, 1, 1)]
[TestCase(202253, 2022, 12, 31)]
public void Should_YearWeekNo_When_GetNowDate(int expected, int year, int month, int day)
{
ShouldBeCurrentYearWeekNo(expected, year, month, day);
}
private void ShouldBeCurrentYearWeekNo(int expected, int year, int month, int day)
{
Assert.AreEqual(expected, _dateTimeHelper.GetCurrentYearWeekNo(new DateTime(year, month, day)));
}
/// <summary>
/// 當取現在日期,應該取得年度前一週
/// 當2020/1/1,應該201953
/// 當2020/1/6,應該202001
/// 當2021/1/1,應該202053(DBA那邊只認禮拜一、不認後面)
/// 當2021/1/4,應該202101
/// 當2022/1/1,應該202153
/// </summary>
[Test]
[TestCase(201953, 2020, 1, 1)]
[TestCase(202001, 2020, 1, 6)]
[TestCase(202053, 2021, 1, 1)]
[TestCase(202101, 2021, 1, 4)]
[TestCase(202153, 2022, 1, 1)]
public void Should_YearLastWeekNo_When_GetNowDate(int expected, int year, int month, int day)
{
ShouldBeYearLastWeekNo(expected, year, month, day);
}
/// <summary>
/// 當取現在日期,應該取得年度前兩週
/// 當2020/1/1,應該201952
/// 當2020/1/6,應該201953
/// 當2020/1/13,應該202001
/// 當2021/1/1,應該202052
/// 當2021/1/4,應該202053
/// 當2021/1/11,應該202101
/// </summary>
[Test]
[TestCase(201952, 2020, 1, 1)]
[TestCase(201953, 2020, 1, 6)]
[TestCase(202001, 2020, 1, 13)]
[TestCase(202052, 2021, 1, 1)]
[TestCase(202053, 2021, 1, 4)]
[TestCase(202101, 2021, 1, 11)]
public void Should_YearTwoAgoWeekNo_When_GetNowDate(int expected, int year, int month, int day)
{
ShouldBeYearTwoAgoWeekNo(expected, year, month, day);
}
private void ShouldBeYearLastWeekNo(int expected, int year, int month, int day)
{
Assert.AreEqual(expected, _dateTimeHelper.GetYearLastWeekNo(new DateTime(year, month, day)));
}
private void ShouldBeYearTwoAgoWeekNo(int expected, int year, int month, int day)
{
Assert.AreEqual(expected, _dateTimeHelper.GetYearTwoAgoWeekNo(new DateTime(year, month, day)));
}
}
元哥的筆記