using System;
using System.Collections.Generic;
using System.Linq;
using Lunar.Util;
// ReSharper disable MemberCanBePrivate.Global
namespace Lunar
{
///
/// 阳历周
///
public class SolarWeek
{
///
/// 年
///
public int Year { get; }
///
/// 月
///
public int Month { get; }
///
/// 日
///
public int Day { get; }
///
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
///
public int Start { get; }
///
/// 默认当月
///
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
public SolarWeek(int start): this(DateTime.Now, start)
{
}
///
/// 通过日期初始化
///
/// 日期
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
public SolarWeek(DateTime date, int start):this(date.Year, date.Month, date.Day, start)
{
}
///
/// 通过年月初始化
///
/// 年
/// 月,1到12
/// 日,1到31
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
public SolarWeek(int year, int month, int day, int start)
{
Year = year;
Month = month;
Day = day;
Start = start;
}
///
/// 通过指定日期获取阳历周
///
/// 日期
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
/// 阳历周
public static SolarWeek FromDate(DateTime date, int start)
{
return new SolarWeek(date, start);
}
///
/// 通过指定年月日获取阳历周
///
/// 年
/// 月,1到12
/// 日,1到31
/// 星期几作为一周的开始,1234560分别代表星期一至星期天
/// 阳历周
public static SolarWeek FromYmd(int year, int month, int day, int start)
{
return new SolarWeek(year, month, day, start);
}
///
/// 当前日期是在当月第几周,从1开始
///
public int Index
{
get
{
var offset = Solar.FromYmdHms(Year, Month, 1).Week - Start;
if (offset < 0)
{
offset += 7;
}
return (int)Math.Ceiling((Day + offset) * 1D / 7);
}
}
///
/// 当前日期是在当年第几周,从1开始
///
public int IndexInYear
{
get
{
var offset = Solar.FromYmdHms(Year, 1, 1).Week - Start;
if (offset < 0)
{
offset += 7;
}
return (int) Math.Ceiling((SolarUtil.GetDaysInYear(Year, Month, Day) + offset) * 1D / 7);
}
}
///
/// 周推移
///
/// 推移的周数,负数为倒推
/// 是否按月单独计算
/// 推移后的阳历周
public SolarWeek Next(int weeks, bool separateMonth)
{
if (0 == weeks)
{
return new SolarWeek(Year, Month, Day, Start);
}
var solar = Solar.FromYmdHms(Year, Month, Day);
if (separateMonth)
{
var n = weeks;
var week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
var m = Month;
var plus = n > 0;
while (0 != n)
{
solar = solar.Next(plus ? 7 : -7);
week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
var weekMonth = week.Month;
if (m != weekMonth)
{
var index = week.Index;
if (plus)
{
if (1 == index)
{
var firstDay = week.FirstDay;
week = new SolarWeek(firstDay.Year, firstDay.Month, firstDay.Day, Start);
weekMonth = week.Month;
}
else
{
solar = Solar.FromYmdHms(week.Year, week.Month, 1);
week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
}
}
else
{
if (SolarUtil.GetWeeksOfMonth(week.Year, week.Month, Start) == index)
{
var lastDay = week.FirstDay.Next(6);
week = new SolarWeek(lastDay.Year, lastDay.Month, lastDay.Day, Start);
weekMonth = week.Month;
}
else
{
solar = Solar.FromYmdHms(week.Year, week.Month, SolarUtil.GetDaysOfMonth(week.Year, week.Month));
week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
}
}
m = weekMonth;
}
n -= plus ? 1 : -1;
}
return week;
}
else
{
solar = solar.Next(weeks * 7);
return new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
}
}
///
/// 本周第一天的阳历日期(可能跨月)
///
public Solar FirstDay
{
get
{
var solar = Solar.FromYmdHms(Year, Month, Day);
var prev = solar.Week - Start;
if (prev < 0)
{
prev += 7;
}
return solar.Next(-prev);
}
}
///
/// 本周第一天的阳历日期(仅限当月)
///
public Solar FirstDayInMonth
{
get
{
return Days.FirstOrDefault(day => Month == day.Month);
}
}
///
/// 本周的阳历日期列表(可能跨月)
///
public List Days
{
get
{
var firstDay = FirstDay;
var l = new List {firstDay};
for (var i = 1; i < 7; i++)
{
l.Add(firstDay.Next(i));
}
return l;
}
}
///
/// 本周的阳历日期列表(仅限当月)
///
public List DaysInMonth
{
get
{
return Days.Where(day => Month == day.Month).ToList();
}
}
///
public override string ToString()
{
return Year + "." + Month + "." + Index;
}
///
/// 完整字符串输出
///
public string FullString => Year + "年" + Month + "月第" + Index + "周";
}
}