指定周起始日计算指定日期是今年的第几周

目录

注意

VB代码

c#代码

JAVA代码


工作遇到的需求:

  以周日为每周的第一天,计算指定日期(如"2023/01/09")是今年的第几周。

  后面的开发中又用户提出了类似的需求,唯一的不同是以周一为每周的第一天,计算周数。

  针对此情形,需要编写一个公共 Function:实现指定某一天为周起始日(周一至周日均可),计算指定日期为当年的第几周。

        指定周三为每周的第一天,即第一个参数的值为3,计算2023/01/12为当年的第几周。只需传入【周起始天】及【需要计算的额日期】即可计算出周数为【3】。

        共三种代码实现方式: VB、C#、JAVA(JDK8)

注意

        周一为1,周二为2 ...... 周日为7。

        VB 和 C# 日期格式:YYYY/MM/DD

        Java 日期格式:YYYY-MM-DD


VB代码

        VB 的实现最为简单,当然,需求的实际就是从 VB 开始出现的,后续的 C# 与 Java 的版本是根据 VB 代码的逻辑编写出来的。

 Private Sub Form_Load()
 
     Dim res As Integer
     res = DateToWorkWeek("2023/07/06", 4)
     
 End Sub
 
 ' 根据输入的日期和指定的周开始天,计算周数
 ' dateVal    输入的日期
 ' startDay   每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天
 Public Function DateToWorkWeek(dateVal As String, startDay As Integer) As Integer
     
     Dim sFirstDay         As Integer
     Dim iDayOfYear        As Integer
     Dim iDayOfFirstWeek   As Integer
 
     ' 返回今年的 01/01 是周几,周一为1,周二为2 ......
     sFirstDay = Weekday(CDate(Year(dateVal) & "/01/01"), 2)
     
     ' 输入日期是今年的第几天
     iDayOfYear = CInt(DateDiff("d", CDate(Year(dateVal) & "/01/01"), dateVal)) + 1
 
     ' 计算第一周的天数      01/01周几 -  周起始日
     iDayOfFirstWeek = IIf((sFirstDay - startDay) >= 0, 7 + startDay - sFirstDay, Abs(sFirstDay - startDay))
     
     ' 返回周数               输入的日期是否落在第一周内
     DateToWorkWeek = IIf(iDayOfYear <= iDayOfFirstWeek, 1, -(Int(-((iDayOfYear - iDayOfFirstWeek) / 7))) + 1)
     
 End Function

C#代码

 using System;
 
 namespace getWorkWeekNo
 {
     class Program
     {
         static void Main(string[] args)
         {
             string sDate = "2023/01/02";
             int iWeekStartDay = 1;
             int iWeekNo;
             iWeekNo = DateToWorkWeekNo(sDate, iWeekStartDay);
             Console.WriteLine("星期 " + iWeekStartDay + " 为每周第一天");
             Console.WriteLine(sDate + " 为当年第 " + iWeekNo + " 周");
             Console.ReadKey();
         }
 
         /// <summary>
         /// 根据输入的日期和指定的周开始天,计算周数
         /// </summary>
         /// <param name="dateVal">输入的日期</param>
         /// <param name="startDay">每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天</param>
         /// <returns>int</returns>
         public static int DateToWorkWeekNo(string dateVal, int startDay)
         {
             int sFirstDay;
             double iDayOfYear;
             double iDayOfFirstWeek;
             string iYear;
             double res;
             int temp;
 
             DateTime dt = Convert.ToDateTime(dateVal);
             iYear = dt.Year.ToString();
             DateTime dt2 = Convert.ToDateTime(iYear + "/01/01");
             // 返回今年的 01/01 是周几,周一为1,周二为2 ......
             sFirstDay = (Convert.ToInt32(dt2.DayOfWeek) == 0) ? 7 : Convert.ToInt32(dt2.DayOfWeek);
 
             // 输入日期是今年的第几天
             iDayOfYear = DateDiff(dt2, dt) + 1;
 
             // 计算第一周的天数  01/01周几 -  周起始日
             iDayOfFirstWeek = (sFirstDay - startDay) >= 0 ? 7 + startDay - sFirstDay : Math.Abs(sFirstDay - startDay);
 
             // 返回周数
             // 输入的日期是否落在第一周内                Math.Floor 向下取整,问题在于 VB 和 C# 的 int 转换在负数部分存在差异
             res = iDayOfYear <= iDayOfFirstWeek ? 1 : -Math.Floor(-((iDayOfYear - iDayOfFirstWeek) / 7)) + 1;
 
             temp = (int)res;
 
             return temp;
         }
 
         /// <summary>
         /// 计算两个日期之间的间隔天数
         /// </summary>
         /// <param name="dateStart">开始日期</param>
         /// <param name="dateEnd">结束日期</param>
         /// <returns>int</returns>
         private static int DateDiff(DateTime dateStart, DateTime dateEnd)
         {
             DateTime start = Convert.ToDateTime(dateStart.ToShortDateString());
             DateTime end = Convert.ToDateTime(dateEnd.ToShortDateString());
             TimeSpan sp = end.Subtract(start);
             return sp.Days;
 
         }
     }
 
 }

JAVA代码

 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 
 public class Test {
 
     public static void main(String[] args) throws ParseException {
         int res;
         res = DateToWorkWeekNo("2023-02-15", 3);
         System.out.println(res);
     }
 
     /**
      * 根据输入的日期和指定的周开始天,计算周数
      *
      * @param dateVal  输入的日期
      * @param startDay 每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天
      * @return int
      */
     public static int DateToWorkWeekNo(String dateVal, int startDay) throws ParseException {
         int sFirstDay;
         double iDayOfYear;
         double iDayOfFirstWeek;
         String iYear;
         double res;
         int temp;
 
         iYear = dateVal.substring(0, 4);
         // 返回今年的 01/01 是周几,周一为1,周二为2 ......
         sFirstDay = getWeek(iYear + "-01-01");
 
         DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
         Date dt = dateFormat.parse(dateVal);
         Date dt2 = dateFormat.parse(iYear + "-01-01");
 
         // 输入日期是今年的第几天
         iDayOfYear = DateDiff(dt2, dt) + 1;
 
         // 计算第一周的天数  01/01周几 -  周起始日
         iDayOfFirstWeek = (sFirstDay - startDay) >= 0 ? 7 + startDay - sFirstDay : Math.abs(sFirstDay - startDay);
 
         // 返回周数
         // 输入的日期是否落在第一周内                Math.floor 向下取整,问题在于 VB 和 C# 的 int 转换在负数部分存在差异
         res = iDayOfYear <= iDayOfFirstWeek ? 1 : -Math.floor(-((iDayOfYear - iDayOfFirstWeek) / 7)) + 1;
 
         temp = (int) res;
 
         return temp;
     }
 
     public static int getWeek(String sdate) throws ParseException {
         
         DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
         int[] weeks = {7, 1, 2, 3, 4, 5, 6};
         Date parseDate = dateFormat.parse(sdate);
         Calendar c = Calendar.getInstance();
         c.setTime(parseDate);
         int week_index = c.get(Calendar.DAY_OF_WEEK) - 1;
         if (week_index < 0) {
             week_index = 0;
         }
         return weeks[week_index];
     }
 
     /**
      * date2比date1多的天数
      *
      * @param date1 开始日期
      * @param date2 结束日期
      * @return int
      */
     public static int DateDiff(Date date1, Date date2) {
         Calendar cal1 = Calendar.getInstance();
         cal1.setTime(date1);
 
         Calendar cal2 = Calendar.getInstance();
         cal2.setTime(date2);
         int day1 = cal1.get(Calendar.DAY_OF_YEAR);
         int day2 = cal2.get(Calendar.DAY_OF_YEAR);
 
         int year1 = cal1.get(Calendar.YEAR);
         int year2 = cal2.get(Calendar.YEAR);
         if (year1 != year2) //不同年
         {
             int timeDistance = 0;
             for (int i = year1; i < year2; i++) {
                 if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
                 {
                     timeDistance += 366;
                 } else //不是闰年
                 {
                     timeDistance += 365;
                 }
             }
 
             return timeDistance + (day2 - day1);
         } else //同年
         {
             System.out.println("判断day2 - day1 : " + (day2 - day1));
             return day2 - day1;
         }
     }
 
 }

posted @ 2023-02-06 17:27  RokiZhang  阅读(140)  评论(0)    收藏  举报  来源