首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建我自己的Period类时遇到困难

创建我自己的Period类时遇到困难
EN

Stack Overflow用户
提问于 2012-05-30 17:38:31
回答 1查看 207关注 0票数 1

我在构建自己的period类时遇到了一些困难,我知道有一些已经创建的类,但由于内部限制,我将不得不实现我自己的类。构造器(下面的代码)基本上接受两个日期,一个开始和一个结束,方法makeWeeks()将这段时间划分为星期,我根据我在学习列表时学到的“头-尾”原则开发了这个方法。

以下是代码(要点)

代码语言:javascript
复制
public class Period implements Serializable
{
  private static final long serialVersionUID = 1L;

  private Calendar          start;

  private Calendar          end;

  private long              durationMillis;

  private long              startMillis;

  private long              endMillis;

  private long              MAX              = 604800000; //A week in millis

  private long              DAY              = 86400000;

  private long              SIX              = 518400000;

  private ArrayList<Week>   weeks;


  public Period(Calendar start, Calendar end)
  {

    this.start = start;
    this.end = end;
    startMillis = start.getTimeInMillis();
    endMillis = end.getTimeInMillis();
    durationMillis = endMillis - startMillis;
    int startWeek = start.get(Calendar.WEEK_OF_YEAR);
    int endWeek = end.get(Calendar.WEEK_OF_YEAR);
    weeks = new ArrayList<Week>();

  }

  /**
   * Construct the weeks in this period
   * 
   * @return
   */
  public ArrayList<Week> makeWeeks()
  {
    long borderLine;

    if ((durationMillis < MAX) || (endMillis < startMillis))
    {
      return null;
    }
    Calendar endHead = Calendar.getInstance();
    //If first week is not Monday then count the days that have been completed
    if (start.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY)
    {
      int days = 0;
      start = adjustCalendar(start);//Set time to 0:0:0:0
      days = getDaysToMonday(start.get(Calendar.DAY_OF_WEEK));
      endHead.setTimeInMillis(start.getTimeInMillis());
      endHead.add(Calendar.DAY_OF_YEAR, days - 1);
      weeks.add(new Week(start, endHead, days, calcCompletion(days), setWeekNumber(start)));//was endHead
      borderLine = endHead.getTimeInMillis() + DAY;
    }//head week set

    else
    {
      start = adjustCalendar(start);
      endHead.setTimeInMillis(start.getTimeInMillis());//Successful
      borderLine = endHead.getTimeInMillis();
    }

    long endMillis = 0;

    while ((((borderLine + SIX)) < (end.getTimeInMillis() + 1)))
    {

      Calendar endNext = Calendar.getInstance();
      Calendar begin = Calendar.getInstance();
      begin.setTimeInMillis(borderLine);
      endNext.setTimeInMillis(borderLine + SIX);

      weeks.add(new Week(begin, endNext, 7, true, setWeekNumber(begin)));
      borderLine += MAX;
      endMillis = endNext.getTimeInMillis();
    }
    //adjust Tail

    Calendar tail = Calendar.getInstance();
    tail.setTimeInMillis(endMillis + DAY);//the beginning of the tail

    tail = adjustCalendar(tail);//set to 00:00:00

    int daysTail = getDaysToTail(end.get(Calendar.DAY_OF_WEEK) + 1);
    if (daysTail != 0)
    {
      weeks.add(new Week(tail, end, daysTail, calcCompletion(daysTail), setWeekNumber(end)));
    }
    return weeks;
  }//EOF makeweeks


  private int setWeekNumber(Calendar cal)
  {

    return cal.get(Calendar.WEEK_OF_YEAR);
  }

  /**
   * This method returns the amount of days between the given day and the next coming Monday
   */
  private int getDaysToMonday(int currentDay)
  {

    switch (currentDay)
    {

      case 1://sunday
        return 1;

      case 2://monday
        return 0;

      case 3://tuesday
        return 6;

      case 4://wednesday
        return 5;

      case 5://thursday
        return 4;

      case 6://friday
        return 3;

      case 7://saturday
        return 2;
    }
    return 0;

  }//EOF method

  /**
   * Returns the day to the end of the final week, always start counting from a Monday
   * 
   * @return
   */
  private int getDaysToTail(int tailDay)
  {

    switch (tailDay)
    {

      case 1://sunday
        return 0;

      case 2://monday
        return 1;

      case 3://tuesday
        return 2;

      case 4://wednesday
        return 3;

      case 5://thursday
        return 4;

      case 6://friday
        return 5;

      case 7://saturday
        return 6;
    }

    return 0;

  }

  /**
   * Returns the amount of weeks stored in this period, completed and non
   * 
   * @return
   */
  public int totalWeeks()
  {
    return weeks.size();
  }

  /**
   * Tells us if the selected period is at least one week
   * will return no result.
   * 
   * @return
   */
  public boolean isAtleastWeek()
  {
    long diff = end.getTimeInMillis() - start.getTimeInMillis();
    if (diff < MAX)
    {
      return false;
    }
    return true;
  }



  /**
   * Provided a week-number, gives back a Week marked by that week-number, if existing.
   * 
   * @param weekNumber
   * @return
   */
  public Week getWeek(Double weekNumber)
  {

    int weekNumberInt = weekNumber.intValue();
    for (Week week : weeks)
    {
      if (weekNumberInt == week.getWeekNumber())
      {
        return week;
      }
    }
    return null;
  }

  /**
   * This method will set the calendars time (H:M:S:M) to 0:0:0:0 so to be able to calculate a precise start and End,
   * dates will remain unaltered
   * 
   * @param cal
   * @return
   */
  private Calendar adjustCalendar(Calendar nu)
  {

    nu.set(Calendar.HOUR, 0);
    nu.set(Calendar.MINUTE, 0);
    nu.set(Calendar.SECOND, 0);
    nu.set(Calendar.MILLISECOND, 0);

    return nu;
  }

我担心有问题,这在大多数情况下工作良好,但在某些情况下,第二周(如2011年11月和12月)不收集,并在2012年3月不收集最后一周,如果您设置为endDate 31/Mar/2012,但如果您选择作为结束30/Mar/2012。你有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-01 16:06:21

解决了!

代码语言:javascript
复制
public class Period implements Serializable
{
  private static final long serialVersionUID = 1L;

  private Calendar          start;

  private Calendar          end;

  private Calendar          startClone;

  private Calendar          endClone;

  private long              durationMillis;

  private long              startMillis;

  private long              endMillis;

  private long              MAX              = 604800000; //A week in millis

  private long              DAY              = 86400000;

  private long              SIX              = 518400000;

  private ArrayList<Week>   weeks;

  /**
   * Constructor accepts 2 Calendars
   * 
   * @param start
   * @param end
   */
  public Period(Calendar start, Calendar end)
  {

    this.start = start;
    this.end = end;
    startClone = (Calendar)start.clone();
    endClone = (Calendar)end.clone();
    startMillis = start.getTimeInMillis();
    endMillis = end.getTimeInMillis();
    durationMillis = endMillis - startMillis;
    int startWeek = start.get(Calendar.WEEK_OF_YEAR);
    int endWeek = end.get(Calendar.WEEK_OF_YEAR);
    weeks = new ArrayList<Week>();

  }

  /**
   * Construct the weeks in this period
   * 
   * @return
   */
  public ArrayList<Week> makeWeeks()
  {
    Calendar borderLine;
    //The meaning of this is to report on weeks, so shorter periods wont be taken in consideration
    if ((durationMillis < MAX) || (endMillis < startMillis))
    {
      return null;
    }
    Calendar endHead = Calendar.getInstance();
    //If first week is not Monday then count the days that have been completed
    if (start.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY)
    {
      int days = 0;
      start = adjustCalendar(start);//Set time to 0:0:0:0
      days = getDaysToMonday(start.get(Calendar.DAY_OF_WEEK));
      endHead = (Calendar)start.clone();
      endHead.add(Calendar.DAY_OF_YEAR, days - 1);
      weeks.add(new Week(start, endHead, days, calcCompletion(days), setWeekNumber(start)));//was endHead
      //borderLine = endHead.getTimeInMillis() + DAY;
      Calendar vector = endHead;
      vector.add(Calendar.DAY_OF_YEAR, 1);
      borderLine = vector;
    }//head week set

    else
    {
      start = adjustCalendar(start);
      endHead = (Calendar)start.clone();//Successful
      borderLine = (Calendar)endHead.clone();
    }

    long endMillis = 0;

    while ((((borderLine.getTimeInMillis() + SIX)) < (end.getTimeInMillis() + 1)))
    {

      Calendar endNext = Calendar.getInstance();
      Calendar begin = Calendar.getInstance();
      begin = (Calendar)borderLine.clone();
      endNext = (Calendar)borderLine.clone();
      endNext.add(Calendar.DAY_OF_YEAR, 6);
      weeks.add(new Week(begin, endNext, 7, true, setWeekNumber(begin)));
      borderLine.add(Calendar.DAY_OF_YEAR, 7);
      endMillis = endNext.getTimeInMillis();
    }
    //adjust Tail

    Calendar tail = Calendar.getInstance();
    tail.setTimeInMillis(endMillis);

    tail.add(Calendar.DAY_OF_YEAR, 1);//the beginning of the tail

    if (!(tail.get(Calendar.DAY_OF_YEAR) >= end.get(Calendar.DAY_OF_YEAR)))
    {
      tail = adjustCalendar(tail);//set to 00:00:00

      int daysTail = getDaysToTail(end.get(Calendar.DAY_OF_WEEK));
      if (daysTail != 0)
      {
        weeks.add(new Week(tail, end, daysTail, calcCompletion(daysTail), setWeekNumber(end)));
      }
    }
    return weeks;
  }//EOF makeweeks

  /**
   * Get the weekNumber
   * 
   * @return
   */
  private double setWeekNumber(Calendar cal)
  {

    Integer week = cal.get(Calendar.WEEK_OF_YEAR);
    Double clone = week.doubleValue();
    return clone;
  }

  /**
   * This method returns the amount of days between the given day and the next coming Monday
   */
  private int getDaysToMonday(int currentDay)
  {

    switch (currentDay)
    {

      case 1://sunday
        return 1;

      case 2://monday
        return 0;

      case 3://tuesday
        return 6;

      case 4://wednesday
        return 5;

      case 5://thursday
        return 4;

      case 6://friday
        return 3;

      case 7://saturday
        return 2;
    }
    return 0;

  }//EOF method

  /**
   * Returns the day to the end of the final week, always start counting from a Monday
   * 
   * @return
   */
  private int getDaysToTail(int tailDay)
  {

    switch (tailDay)
    {

      case 1://sunday
        return 0;

      case 2://monday
        return 1;

      case 3://tuesday
        return 2;

      case 4://wednesday
        return 3;

      case 5://thursday
        return 4;

      case 6://friday
        return 5;

      case 7://saturday
        return 6;
    }

    return 0;

  }

  /**
   * Returns the amount of weeks stored in this period, completed and non
   * 
   * @return
   */
  public int totalWeeks()
  {
    return weeks.size();
  }

  /**
   * Tells us if the selected period is at least one week, since this is a weekly report, selecting less then a week
   * will return no result.
   * 
   * @return
   */
  public boolean isAtleastWeek()
  {
    long diff = endClone.getTimeInMillis() - startClone.getTimeInMillis();
    if (diff < MAX)
    {
      return false;
    }
    return true;
  }

  /**
   * Provide the dates(start and end of a week) in the form of a String
   * 
   * @param weekNumber
   * @return
   */
  public String getDates(Double weekNumber)
  {

    int weekNumberInt = weekNumber.intValue();

    String vector = new String();

    for (Week week : weeks)
    {
      if (week.getWeekNumber() == weekNumberInt)
      {
        vector += week.getStart().get(Calendar.DAY_OF_MONTH) + "/";
        vector += (week.getStart().get(Calendar.MONTH) + 1) + "/";
        vector += week.getStart().get(Calendar.YEAR) + "-";
        vector += (week.getEnd().get(Calendar.DAY_OF_MONTH)) + "/";
        vector += (week.getEnd().get(Calendar.MONTH) + 1) + "/";
        vector += week.getEnd().get(Calendar.YEAR);
      }
    }
    return vector;
  }

  /**
   * Provided a week-number, gives back a Week marked by that week-number, if existing.
   * 
   * @param weekNumber
   * @return
   */
  public Week getWeek(Double weekNumber)
  {

    int weekNumberInt = weekNumber.intValue();
    for (Week week : weeks)
    {
      if (weekNumberInt == week.getWeekNumber())
      {
        return week;
      }
    }
    return null;
  }

  /**
   * This method will set the calendars time (H:M:S:M) to 0:0:0:0 so to be able to calculate a precise start and End,
   * dates will remain unaltered
   * 
   * @param cal
   * @return
   */
  private Calendar adjustCalendar(Calendar nu)
  {

    nu.set(Calendar.HOUR, 0);
    nu.set(Calendar.MINUTE, 0);
    nu.set(Calendar.SECOND, 0);
    nu.set(Calendar.MILLISECOND, 0);

    return nu;
  }

  /**
   * BBC defines a week "complete" only if 4 or more days of that week have passed.
   * 
   * @param days
   * @return
   */
  private boolean calcCompletion(int days)
  {
    if (days < 4)
    {
      return false;
    }
    return true;
  }

  /**
   * @return
   */
  public boolean hasWeekNumber(Double weekNumber)
  {

    for (Week week : weeks)
    {
      if (weekNumber.intValue() == week.getWeekNumber())
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns the highest week number
   * 
   * @return
   */
  public double getHighestWeekNumber()
  {
    return weeks.get(weeks.size() - 1).getWeekNumber();
  }

  /**
   * Test method to print fields of a calendar
   */
  private String showCalValues(Calendar cal)
  {

    return "Day of year " + cal.get(Calendar.DAY_OF_YEAR) + " Day of month: " + cal.get(Calendar.DAY_OF_MONTH)
        + " Day of week: " + cal.get(Calendar.DAY_OF_WEEK) + " month " + cal.get(Calendar.MONTH) + " date: "
        + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.MILLISECOND)
        + " week number: " + cal.get(Calendar.WEEK_OF_YEAR) + " millis: " + cal.getTimeInMillis();
  }

  /**
   * Test method that prints the weeks
   */
  private void showWeeks()
  {
    for (Week w : weeks)
    {
      System.out.println(w.getWeekNumber() + " start millis: " + w.getStart().getTimeInMillis());
    }
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10813676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档