【问题标题】:Get week number of given date by passing start and end date in java通过在java中传递开始和结束日期来获取给定日期的周数
【发布时间】:2016-10-04 04:34:06
【问题描述】:

我正在尝试获取介于开始日期和结束日期之间的给定日期的周数。 下面是我用来获取的代码,但它只能工作 4 周。

我需要它让它工作数周。

public static int getWeekNO( Timestamp startTime,Timestamp endTime , Timestamp dateTime) throws RuntimeException {

        String formatted = null;
        Timestamp currentTimestamp;
        int weekNumber = 0;

        logger.debug("startTime"+startTime);
        logger.debug("endTime"+endTime);
        logger.debug("dateTime"+dateTime);
        try {
            String formatDateFirst =  "";
            String formatDateSecond = "";
            String formatDateThird = "";
            String formatDateFourth = "";
            String givenDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateTime);
            String startDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime);
            String endDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTime);
            logger.debug("givenDateString"+givenDateString);
            logger.debug("startDateString"+startDateString);
            logger.debug("endDateString"+endDateString);


            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Calendar c = Calendar.getInstance();
            Date givenDate = sdf.parse(givenDateString);
            Date startDate = sdf.parse(startDateString);
            Date endDate = sdf.parse(endDateString);

            logger.debug("givenDate"+givenDate);
            logger.debug("startDate"+startDate);
            logger.debug("endDate"+endDate);

            c.setTime(sdf.parse(startDateString));

            c.add(Calendar.DAY_OF_MONTH, 6); // number of days to add
            formatDateFirst = sdf.format(c.getTime());
            Date firstWeekDate = (Date) sdf.parse(formatDateFirst);
            logger.debug("endDate"+firstWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateSecond = sdf.format(c.getTime());
            Date secondWeekDate = (Date) sdf.parse(formatDateSecond);
            logger.debug("endDate"+secondWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateThird = sdf.format(c.getTime());
            Date thirdWeekDate = (Date) sdf.parse(formatDateThird);
            logger.debug("endDate"+thirdWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateFourth = sdf.format(c.getTime());
            Date fourthWeekDate = (Date) sdf.parse(formatDateFourth);
            logger.debug("endDate"+fourthWeekDate);


            if (givenDate.compareTo(firstWeekDate) <= 0) {
                weekNumber = 1;
            } else if (givenDate.compareTo(secondWeekDate) <= 0
                    && givenDate.compareTo(firstWeekDate) > 0) {
                weekNumber = 2;
                } else if (givenDate.compareTo(thirdWeekDate) <= 0
                    && givenDate.compareTo(secondWeekDate) > 0) {
                    weekNumber = 3;
            }else if (givenDate.compareTo(fourthWeekDate) <= 0
                    && givenDate.compareTo(thirdWeekDate) > 0) {
                    weekNumber = 4;
            }else{
                logger.debug("Not a Valid Date");
            }

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return weekNumber;
    } 

例子:

  start Timestamp: 09/04/2016 00:00:00,End Timestamp: 28/06/2016 00:00:00. Given Timestamp : 15/05/2016 00:00:00

so here:week 1:09/04/2016 - 15/04/2016
        week 2:16/04/2016 - 22/04/2016
        week 3:23/04/2016 - 29/04/2016
        week 4:30/04/2016 - 06/05/2016
        week 5:07/05/2016 - 13/05/2016
        week 6:14/05/2016 - 20/05/2016 -- my given timestamp falls here
        week 7:21/05/2016 - 27/05/2016
        week 8:28/05/2016 - 03/06/2016

so now my output for week no should be week:6 

这里我使用的是 java 1.7,所以我无法使用 -- import java.time.LocalDateTime; 导入 java.time.temporal.ChronoUnit;

我怎么能做到,这个请帮帮我。

【问题讨论】:

  • 使用Joda Time
  • @Elliott Frisch Joda 时间存在于 Java SE 8 中,我正在开发 Java SE 7 构建项目
  • @dafodil 不,Joda-Time 是第三方库,不是 Java 的一部分。我怀疑您正在考虑 java.time,它内置于 Java 8 及更高版本中,取代了旧的日期时间类,并受到 Joda-Time 的启发。 Joda-Time 团队建议用户迁移到 java.time。大部分 java.time 功能在ThreeTen-Backport 中向后移植,并在ThreeTenABP 中进一步适应Android。
  • @Basil Bourque 您的评论提供了丰富的信息,谢谢。但我也不应该使用任何第三方库,因为我正在处理已经构建的项目,它应该由现有的库和 api 维护。
  • @dafodil 您是否在问:对于给定的时间间隔(一对日期时间值),该时间间隔开始后多少周是特定的日期时间值(第三个单独的日期时间值)?

标签: java datetime


【解决方案1】:
    public static int getWeekNO(Timestamp startTime, Timestamp endTime, Timestamp dateTime) {
      if (dateTime.compareTo(startTime) < 0 || dateTime.compareTo(endTime) > 0) {
        System.out.println("Not a Valid Date");
        return -1;
      }
      return (int) ((dateTime.getTime() - startTime.getTime() - 1) / (1000L * 3600 * 24 * 7)) + 1;
    }

编辑:

作为请求,更新了答案,

public static int getWeekNO(Timestamp startTime, Timestamp endTime, Timestamp dateTime) {
  if (dateTime.compareTo(startTime) < 0 || dateTime.compareTo(endTime) > 0) {
    System.out.println("Not a Valid Date");
    return -1;
  }
  int dayDiff = (int) ((dateTime.getTime() - startTime.getTime()) / (1000L * 3600 * 24)) + 1;
  int week = dayDiff / 7;
  return dayDiff % 7 == 0 ? week : week + 1;
}

注意:注意Date/Timestamp的构造函数,

  Timestamp startTime = new Timestamp(2016, 5, 30, 0, 0, 0, 0);
  Timestamp dateTime = new Timestamp(2016, 6, 6, 0, 0, 0, 0);

这个构造函数月份从 0 开始。所以上面的代码是比较 2016-4-30 和 2016-5-6。只有一周。

【讨论】:

  • 如果要忽略“HH:mm:ss”,只需将三个输入的三个值重置为零即可。它不包含在答案中。
  • 如何重置“HH:mm:ss”值,你能在代码中显示吗,我在谷歌搜索它只显示日历重置。
  • 如果我将 startdate 设为 2016、05、17 并将 dateTime 设为 2016、06、01,它会给出 2 周而不是 3 周。我该如何纠正它
  • @dafodil 这是边缘情况。我的计算是从 2016-05-17 00:00 到 2016-06-01 00:00。持续时间正好是 2 周。你可以说是2周结束,也可以说是3周开始,完全没问题。这是你的决定。只需从最后一行中删除 -1
  • 它不应该只限制特定的时间间隔,我给它的任何日期间隔都必须为此工作。你能帮我解决这个问题吗
【解决方案2】:

使用 java.time

不要将java.sql.Timestamp 用于业务逻辑。该类仅用于与您的数据库交换数据。甚至这个目的现在也被 java.time 类所取代。对于 Java 7,请使用下面项目符号中列出的 java.time 的后向端口。

麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleTextFormat 现在是 legacy,被 java.time 类所取代。

DayOfWeek

指定您认为是一周开始的星期几。使用DayOfWeek 枚举对象。顺便说一句,标准的ISO 8601 week 定义从星期一开始。

DayOfWeek dowStart = DayOfWeek.MONDAY ;

LocalDate

LocalDate 类表示没有时间和时区的仅日期值。

指定您的开始/停止日期。

LocalDate start = LocalDate.parse( 2016 , 4 , 9 ) ; 
LocalDate stop = LocalDate.parse( 2016 , 6 , 28 ) ;
LocalDate first = start.with( TemporalAdjusters.previousOrSame( dowStart ) ) ;

List<LocalDate> dates = new ArrayList<>() ;
LocalDate ld = first ; // Initialize for loop.
while( ld.isBefore( stop ) ) {  // While the local date is before the stopping point.
    dates.add( ld ) ;
    // Prepare for next loop.
    ld = ld.plusWeeks( 1 ) ;
}

现在以您选择的任何方式报告您的一周开始日期。

int i = 0 ;  // Initialize for loop.
for( LocalDate ld : dates ) {
    i ++ ;
    String output = "Week # " + i + ":" + ld + " - " + ld.plusDays( 6 ) ;
    …
}

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多