[英]Hard time while creating my own Period class
I'm having some hard time building my own period class, i know that there are some already made classes out there but due to internal restrictions i will have to implement my own. 我在建立自己的周期类时遇到了一些困难,我知道那里已经有一些已经完成的类,但是由于内部限制,我将不得不实现自己的类。 The constructor (code below) basically accepts 2 dates, a start and an end, the method makeWeeks(), will devide this period into weeks, i developed this according to the "head-tail" principle that i learned when i was studying lists.
构造函数(下面的代码)基本上接受2个日期,一个开始和一个结束,方法makeWeeks()将这段时间划分为几个星期,我根据我在学习列表时学到的“头尾”原理开发了这个日期。
heres the code (the essentials) 继承人代码(要点)
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;
}
I'm afraid there is something wrong, this works fine in most cases but in some cases, (like November and December 2011) the second week is not collected, and in March 2012 the last week is not collected if you set as endDate 31/Mar/2012 but it is if you select as end 30/Mar/2012. 恐怕出了点问题,在大多数情况下都可以,但是在某些情况下(例如,2011年11月和2011年12月),第二周不收集,如果您设置为endDate 31,则在2012年3月不收集最后一周/ Mar / 2012,但如果您选择将其作为30 / Mar / 2012结尾。 Do you have any advice?
您有什么建议吗?
Solved! 解决了!
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());
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.