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

在工作中,遇到了一个需求:

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

  后面又出现了类似的需求,唯一的不同是以周一为每周的第一天,计算周数。

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

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

VB代码如下:

 1 Private Sub Form_Load()
 2 
 3     Dim res As Integer
 4     res = DateToWorkWeek("2023/07/06", 4)
 5     
 6 End Sub
 7 
 8 ' 根据输入的日期和指定的周开始天,计算周数
 9 ' dateVal    输入的日期
10 ' startDay   每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天
11 Public Function DateToWorkWeek(dateVal As String, startDay As Integer) As Integer
12     
13     Dim sFirstDay         As Integer
14     Dim iDayOfYear        As Integer
15     Dim iDayOfFirstWeek   As Integer
16 
17     ' 返回今年的 01/01 是周几,周一为1,周二为2 ......
18     sFirstDay = Weekday(CDate(Year(dateVal) & "/01/01"), 2)
19     
20     ' 输入日期是今年的第几天
21     iDayOfYear = CInt(DateDiff("d", CDate(Year(dateVal) & "/01/01"), dateVal)) + 1
22 
23     ' 计算第一周的天数      01/01周几 -  周起始日
24     iDayOfFirstWeek = IIf((sFirstDay - startDay) >= 0, 7 + startDay - sFirstDay, Abs(sFirstDay - startDay))
25     
26     ' 返回周数               输入的日期是否落在第一周内
27     DateToWorkWeek = IIf(iDayOfYear <= iDayOfFirstWeek, 1, -(Int(-((iDayOfYear - iDayOfFirstWeek) / 7))) + 1)
28     
29 End Function

c#代码如下:

 1 using System;
 2 
 3 namespace getWorkWeekNo
 4 {
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             string sDate = "2023/01/02";
10             int iWeekStartDay = 1;
11             int iWeekNo;
12             iWeekNo = DateToWorkWeekNo(sDate, iWeekStartDay);
13             Console.WriteLine("星期 " + iWeekStartDay + " 为每周第一天");
14             Console.WriteLine(sDate + " 为当年第 " + iWeekNo + "");
15             Console.ReadKey();
16         }
17 
18         /// <summary>
19         /// 根据输入的日期和指定的周开始天,计算周数
20         /// </summary>
21         /// <param name="dateVal">输入的日期</param>
22         /// <param name="startDay">每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天</param>
23         /// <returns>int</returns>
24         public static int DateToWorkWeekNo(string dateVal, int startDay)
25         {
26             int sFirstDay;
27             double iDayOfYear;
28             double iDayOfFirstWeek;
29             string iYear;
30             double res;
31             int temp;
32 
33             DateTime dt = Convert.ToDateTime(dateVal);
34             iYear = dt.Year.ToString();
35             DateTime dt2 = Convert.ToDateTime(iYear + "/01/01");
36             // 返回今年的 01/01 是周几,周一为1,周二为2 ......
37             sFirstDay = (Convert.ToInt32(dt2.DayOfWeek) == 0) ? 7 : Convert.ToInt32(dt2.DayOfWeek);
38 
39             // 输入日期是今年的第几天
40             iDayOfYear = DateDiff(dt2, dt) + 1;
41 
42             // 计算第一周的天数  01/01周几 -  周起始日
43             iDayOfFirstWeek = (sFirstDay - startDay) >= 0 ? 7 + startDay - sFirstDay : Math.Abs(sFirstDay - startDay);
44 
45             // 返回周数
46             // 输入的日期是否落在第一周内                Math.Floor 向下取整,问题在于 VB 和 C# 的 int 转换在负数部分存在差异
47             res = iDayOfYear <= iDayOfFirstWeek ? 1 : -Math.Floor(-((iDayOfYear - iDayOfFirstWeek) / 7)) + 1;
48 
49             temp = (int)res;
50 
51             return temp;
52         }
53 
54         /// <summary>
55         /// 计算两个日期之间的间隔天数
56         /// </summary>
57         /// <param name="dateStart">开始日期</param>
58         /// <param name="dateEnd">结束日期</param>
59         /// <returns>int</returns>
60         private static int DateDiff(DateTime dateStart, DateTime dateEnd)
61         {
62             DateTime start = Convert.ToDateTime(dateStart.ToShortDateString());
63             DateTime end = Convert.ToDateTime(dateEnd.ToShortDateString());
64             TimeSpan sp = end.Subtract(start);
65             return sp.Days;
66 
67         }
68     }
69 
70 }

JAVA代码如下:

  1 import java.text.DateFormat;
  2 import java.text.ParseException;
  3 import java.text.SimpleDateFormat;
  4 import java.util.Calendar;
  5 import java.util.Date;
  6 
  7 public class Test {
  8 
  9     public static void main(String[] args) throws ParseException {
 10         int res;
 11         res = DateToWorkWeekNo("2023-02-15", 3);
 12         System.out.println(res);
 13     }
 14 
 15     /**
 16      * 根据输入的日期和指定的周开始天,计算周数
 17      *
 18      * @param dateVal  输入的日期
 19      * @param startDay 每周几为一周起始,输入7,即代表周日为一周的第一天,即周起始天
 20      * @return int
 21      */
 22     public static int DateToWorkWeekNo(String dateVal, int startDay) throws ParseException {
 23         int sFirstDay;
 24         double iDayOfYear;
 25         double iDayOfFirstWeek;
 26         String iYear;
 27         double res;
 28         int temp;
 29 
 30         iYear = dateVal.substring(0, 4);
 31         // 返回今年的 01/01 是周几,周一为1,周二为2 ......
 32         sFirstDay = getWeek(iYear + "-01-01");
 33 
 34         DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 35 
 36         Date dt = dateFormat.parse(dateVal);
 37         Date dt2 = dateFormat.parse(iYear + "-01-01");
 38 
 39         // 输入日期是今年的第几天
 40         iDayOfYear = DateDiff(dt2, dt) + 1;
 41 
 42         // 计算第一周的天数  01/01周几 -  周起始日
 43         iDayOfFirstWeek = (sFirstDay - startDay) >= 0 ? 7 + startDay - sFirstDay : Math.abs(sFirstDay - startDay);
 44 
 45         // 返回周数
 46         // 输入的日期是否落在第一周内                Math.floor 向下取整,问题在于 VB 和 C# 的 int 转换在负数部分存在差异
 47         res = iDayOfYear <= iDayOfFirstWeek ? 1 : -Math.floor(-((iDayOfYear - iDayOfFirstWeek) / 7)) + 1;
 48 
 49         temp = (int) res;
 50 
 51         return temp;
 52     }
 53 
 54     public static int getWeek(String sdate) throws ParseException {
 55         
 56         DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 57         int[] weeks = {7, 1, 2, 3, 4, 5, 6};
 58         Date parseDate = dateFormat.parse(sdate);
 59         Calendar c = Calendar.getInstance();
 60         c.setTime(parseDate);
 61         int week_index = c.get(Calendar.DAY_OF_WEEK) - 1;
 62         if (week_index < 0) {
 63             week_index = 0;
 64         }
 65         return weeks[week_index];
 66     }
 67 
 68     /**
 69      * date2比date1多的天数
 70      *
 71      * @param date1 开始日期
 72      * @param date2 结束日期
 73      * @return int
 74      */
 75     public static int DateDiff(Date date1, Date date2) {
 76         Calendar cal1 = Calendar.getInstance();
 77         cal1.setTime(date1);
 78 
 79         Calendar cal2 = Calendar.getInstance();
 80         cal2.setTime(date2);
 81         int day1 = cal1.get(Calendar.DAY_OF_YEAR);
 82         int day2 = cal2.get(Calendar.DAY_OF_YEAR);
 83 
 84         int year1 = cal1.get(Calendar.YEAR);
 85         int year2 = cal2.get(Calendar.YEAR);
 86         if (year1 != year2) //不同年
 87         {
 88             int timeDistance = 0;
 89             for (int i = year1; i < year2; i++) {
 90                 if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
 91                 {
 92                     timeDistance += 366;
 93                 } else //不是闰年
 94                 {
 95                     timeDistance += 365;
 96                 }
 97             }
 98 
 99             return timeDistance + (day2 - day1);
100         } else //同年
101         {
102             System.out.println("判断day2 - day1 : " + (day2 - day1));
103             return day2 - day1;
104         }
105     }
106 
107 }

 

posted @ 2023-01-16 13:04  RokiZhang  阅读(95)  评论(0)    收藏  举报