This method splits the first day off of a time span.

@param calendar current calendar
@param assignment timephased assignment span
@return first day and remainder assignments
186733
private TimephasedWork[] splitFirstDay(ProjectCalendar calendar, TimephasedWork assignment)
   {
      TimephasedWork[] result = new TimephasedWork[2];

      //
      // Retrieve data used to calculate the pro-rata work split
      //
      Date assignmentStart = assignment.getStart();
      Date assignmentFinish = assignment.getFinish();
      Duration calendarWork = calendar.getWork(assignmentStart, assignmentFinish, TimeUnit.MINUTES);
      Duration assignmentWork = assignment.getTotalAmount();

      if (calendarWork.getDuration() != 0)
      {
         //
         // Split the first day
         //
         Date splitFinish;
         double splitMinutes;
         if (calendar.isWorkingDate(assignmentStart))
         {
            Date splitStart = assignmentStart;
            Date splitFinishTime = calendar.getFinishTime(splitStart);
            splitFinish = DateHelper.setTime(splitStart, splitFinishTime);

            Duration calendarSplitWork = calendar.getWork(splitStart, splitFinish, TimeUnit.MINUTES);
            Duration calendarWorkPerDay = calendar.getWork(splitStart, TimeUnit.MINUTES);
            Duration assignmentWorkPerDay = assignment.getAmountPerDay();
            Duration splitWork;

            if (calendarSplitWork.durationComponentEquals(calendarWorkPerDay))
            {
               {
                  if (calendarSplitWork.durationComponentEquals(assignmentWorkPerDay))
                  {
                     splitWork = assignmentWorkPerDay;
                     splitMinutes = splitWork.getDuration();
                  }
                  else
                  {
                     splitMinutes = assignmentWorkPerDay.getDuration();
                     splitMinutes *= calendarSplitWork.getDuration();
                     splitMinutes /= (8 * 60); // this appears to be a fixed value
                     splitWork = Duration.getInstance(splitMinutes, TimeUnit.MINUTES);
                  }
               }
            }
            else
            {
               splitMinutes = assignmentWorkPerDay.getDuration();
               splitMinutes *= calendarSplitWork.getDuration();
               splitMinutes /= (8 * 60); // this appears to be a fixed value
               splitWork = Duration.getInstance(splitMinutes, TimeUnit.MINUTES);
            }

            TimephasedWork split = new TimephasedWork();
            split.setStart(splitStart);
            split.setFinish(splitFinish);
            split.setTotalAmount(splitWork);

            result[0] = split;
         }
         else
         {
            splitFinish = assignmentStart;
            splitMinutes = 0;
         }

         //
         // Split the remainder
         //
         Date splitStart = calendar.getNextWorkStart(splitFinish);
         splitFinish = assignmentFinish;
         TimephasedWork split;
         if (splitStart.getTime() > splitFinish.getTime())
         {
            split = null;
         }
         else
         {
            splitMinutes = assignmentWork.getDuration() - splitMinutes;
            Duration splitWork = Duration.getInstance(splitMinutes, TimeUnit.MINUTES);

            split = new TimephasedWork();
            split.setStart(splitStart);
            split.setFinish(splitFinish);
            split.setTotalAmount(splitWork);
            split.setAmountPerDay(assignment.getAmountPerDay());
         }

         result[1] = split;
      }
      return result;
   }
809900
private void readAssignment(Project.Assignments.Assignment assignment, SplitTaskFactory splitFactory, TimephasedWorkNormaliser normaliser)
   {
      BigInteger taskUID = assignment.getTaskUID();
      BigInteger resourceUID = assignment.getResourceUID();
      if (taskUID != null && resourceUID != null)
      {
         Task task = m_projectFile.getTaskByUniqueID(Integer.valueOf(taskUID.intValue()));
         if (task != null)
         {
            Resource resource = m_projectFile.getResourceByUniqueID(Integer.valueOf(resourceUID.intValue()));
            ProjectCalendar calendar = null;
            if (resource != null)
            {
               calendar = resource.getResourceCalendar();
            }

            if (calendar == null || task.getIgnoreResourceCalendar())
            {
               calendar = task.getEffectiveCalendar();
            }

            LinkedList<TimephasedWork> timephasedComplete = readTimephasedAssignment(calendar, assignment, 2);
            LinkedList<TimephasedWork> timephasedPlanned = readTimephasedAssignment(calendar, assignment, 1);
            boolean raw = true;

            if (isSplit(calendar, timephasedComplete) || isSplit(calendar, timephasedPlanned))
            {
               task.setSplits(new LinkedList<DateRange>());
               normaliser.normalise(calendar, timephasedComplete);
               normaliser.normalise(calendar, timephasedPlanned);
               splitFactory.processSplitData(task, timephasedComplete, timephasedPlanned);
               raw = false;
            }

            DefaultTimephasedWorkContainer timephasedCompleteData = new DefaultTimephasedWorkContainer(calendar, normaliser, timephasedComplete, raw);
            DefaultTimephasedWorkContainer timephasedPlannedData = new DefaultTimephasedWorkContainer(calendar, normaliser, timephasedPlanned, raw);

            ResourceAssignment mpx = task.addResourceAssignment(resource);

            mpx.setActualCost(DatatypeConverter.parseCurrency(assignment.getActualCost()));
            mpx.setActualFinish(assignment.getActualFinish());
            mpx.setActualOvertimeCost(DatatypeConverter.parseCurrency(assignment.getActualOvertimeCost()));
            mpx.setActualOvertimeWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getActualOvertimeWork()));
            //assignment.getActualOvertimeWorkProtected()
            mpx.setActualStart(assignment.getActualStart());
            mpx.setActualWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getActualWork()));
            //assignment.getActualWorkProtected()
            mpx.setACWP(DatatypeConverter.parseCurrency(assignment.getACWP()));
            mpx.setBCWP(DatatypeConverter.parseCurrency(assignment.getBCWP()));
            mpx.setBCWS(DatatypeConverter.parseCurrency(assignment.getBCWS()));
            //assignment.getBookingType()
            mpx.setBudgetCost(DatatypeConverter.parseCurrency(assignment.getBudgetCost()));
            mpx.setBudgetWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getBudgetWork()));
            mpx.setCost(DatatypeConverter.parseCurrency(assignment.getCost()));
            mpx.setCostRateTableIndex(NumberHelper.getInt(assignment.getCostRateTable()));
            mpx.setCreateDate(assignment.getCreationDate());
            mpx.setCV(DatatypeConverter.parseCurrency(assignment.getCV()));
            mpx.setDelay(DatatypeConverter.parseDurationInTenthsOfMinutes(assignment.getDelay()));
            mpx.setFinish(assignment.getFinish());
            mpx.setVariableRateUnits(BooleanHelper.getBoolean(assignment.isHasFixedRateUnits()) ? null : DatatypeConverter.parseTimeUnit(assignment.getRateScale()));
            mpx.setGUID(assignment.getGUID());
            mpx.setHyperlink(assignment.getHyperlink());
            mpx.setHyperlinkAddress(assignment.getHyperlinkAddress());
            mpx.setHyperlinkSubAddress(assignment.getHyperlinkSubAddress());
            mpx.setLevelingDelay(DatatypeConverter.parseDurationInTenthsOfMinutes(m_projectFile.getProjectProperties(), assignment.getLevelingDelay(), DatatypeConverter.parseDurationTimeUnits(assignment.getLevelingDelayFormat())));
            mpx.setNotes(assignment.getNotes());
            mpx.setOvertimeCost(DatatypeConverter.parseCurrency(assignment.getOvertimeCost()));
            mpx.setOvertimeWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getOvertimeWork()));
            mpx.setPercentageWorkComplete(assignment.getPercentWorkComplete());
            //mpx.setPlannedCost();
            //mpx.setPlannedWork();
            mpx.setRegularWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getRegularWork()));
            mpx.setRemainingCost(DatatypeConverter.parseCurrency(assignment.getRemainingCost()));
            mpx.setRemainingOvertimeCost(DatatypeConverter.parseCurrency(assignment.getRemainingOvertimeCost()));
            mpx.setRemainingOvertimeWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getRemainingOvertimeWork()));
            mpx.setRemainingWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getRemainingWork()));
            mpx.setResume(assignment.getResume());
            mpx.setStart(assignment.getStart());
            mpx.setStop(assignment.getStop());
            mpx.setSV(DatatypeConverter.parseCurrency(assignment.getSV()));
            mpx.setUniqueID(NumberHelper.getInteger(assignment.getUID()));
            mpx.setUnits(DatatypeConverter.parseUnits(assignment.getUnits()));
            mpx.setVAC(DatatypeConverter.parseCurrency(assignment.getVAC()));
            mpx.setWork(DatatypeConverter.parseDuration(m_projectFile, TimeUnit.HOURS, assignment.getWork()));
            mpx.setWorkContour(assignment.getWorkContour());

            mpx.setTimephasedActualWork(timephasedCompleteData);
            mpx.setTimephasedWork(timephasedPlannedData);

            readAssignmentExtendedAttributes(assignment, mpx);

            readAssignmentBaselines(assignment, mpx);

            // Read last to ensure caching works as expected
            mpx.setCostVariance(DatatypeConverter.parseCurrency(assignment.getCostVariance()));
            mpx.setWorkVariance(DatatypeConverter.parseDurationInThousanthsOfMinutes(m_projectFile.getProjectProperties(), assignment.getWorkVariance(), TimeUnit.HOURS));
            mpx.setStartVariance(DatatypeConverter.parseDurationInTenthsOfMinutes(m_projectFile.getProjectProperties(), assignment.getStartVariance(), TimeUnit.DAYS));
            mpx.setFinishVariance(DatatypeConverter.parseDurationInTenthsOfMinutes(m_projectFile.getProjectProperties(), assignment.getFinishVariance(), TimeUnit.DAYS));

            m_eventManager.fireAssignmentReadEvent(mpx);
         }
      }
   }
58235
public void setDate(final Date date) {
		if (date == null) {
			setPartialDate(null, null, null);
		} else {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			Integer year = cal.get(Calendar.YEAR);
			Integer month = cal.get(Calendar.MONTH) + 1;
			Integer day = cal.get(Calendar.DAY_OF_MONTH);
			setPartialDate(day, month, year);
		}
	}
326944
public static LocalDate firstDay(LocalDate localDate) {
        return LocalDate.of(localDate.getYear(), localDate.getMonth(), 1);
    }
99855
private void splitDays(ProjectCalendar calendar, LinkedList<TimephasedWork> list)
   {
      LinkedList<TimephasedWork> result = new LinkedList<TimephasedWork>();
      boolean remainderInserted = false;
      
      for (TimephasedWork assignment : list)
      {
         if (remainderInserted)
         {
            assignment.setStart(DateHelper.addDays(assignment.getStart(), 1));
            remainderInserted = false;
         }

         while (assignment != null)
         {
            Date startDay = DateHelper.getDayStartDate(assignment.getStart());
            Date finishDay = DateHelper.getDayStartDate(assignment.getFinish());

            // special case - when the finishday time is midnight, it's really the previous day...
            if (assignment.getFinish().getTime() == finishDay.getTime())
            {
               finishDay = DateHelper.addDays(finishDay, -1);
            }

            if (startDay.getTime() == finishDay.getTime())
            {
               Duration totalWork = assignment.getTotalAmount();
               Duration assignmentWork = getAssignmentWork(calendar, assignment);
               if ((totalWork.getDuration() - assignmentWork.getDuration()) > EQUALITY_DELTA)
               {
                  assignment.setTotalAmount(assignmentWork);
                  result.add(assignment);
                  Duration remainingWork = Duration.getInstance(totalWork.getDuration() - assignmentWork.getDuration(), TimeUnit.MINUTES);
                  
                  Date remainderStart = DateHelper.addDays(finishDay, 1);
                  Date remainderFinish = DateHelper.addDays(remainderStart, 1);
                  
                  TimephasedWork remainder = new TimephasedWork();
                  remainder.setStart(remainderStart);
                  remainder.setFinish(remainderFinish);
                  remainder.setTotalAmount(remainingWork);
                  result.add(remainder);

                  remainderInserted = true;
               }
               else
               {
                  result.add(assignment);
               }
               break;
            }

            TimephasedWork[] split = splitFirstDay(calendar, assignment);
            if (split[0] != null)
            {
               result.add(split[0]);
            }

            if (assignment.equals(split[1]))
            {
               break;
            }

            assignment = split[1];
         }
      }
     
      list.clear();
      list.addAll(result);
   }
143440
@Override
    public ScheduledFuture<?> schedule(Topic topic, long initialDelay, long period, TimeUnit unit) {
        return schedule(topic, null, initialDelay, period, unit);
    }
1154789
public boolean isDayExcluded (final Calendar day)
  {

    if (day == null)
    {
      throw new IllegalArgumentException ("Parameter day must not be null");
    }

    // Check baseCalendar first
    if (!super.isTimeIncluded (day.getTime ().getTime ()))
    {
      return true;
    }

    final int dmonth = day.get (Calendar.MONTH);
    final int dday = day.get (Calendar.DAY_OF_MONTH);

    if (m_bDataSorted == false)
    {
      Collections.sort (m_aExcludeDays, new CalendarComparator ());
      m_bDataSorted = true;
    }

    final Iterator <Calendar> iter = m_aExcludeDays.iterator ();
    while (iter.hasNext ())
    {
      final Calendar cl = iter.next ();

      // remember, the list is sorted
      if (dmonth < cl.get (Calendar.MONTH))
      {
        return false;
      }

      if (dday != cl.get (Calendar.DAY_OF_MONTH))
      {
        continue;
      }

      if (dmonth != cl.get (Calendar.MONTH))
      {
        continue;
      }

      return true;
    }

    return false;
  }
523604
public CalendarDay getDayFromLocation(float x, float y) {
        int dayStart = mPadding;
        if (x < dayStart || x > mWidth - mPadding) {
            return null;
        }
        // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
        int row = (int) (y - MONTH_HEADER_SIZE) / mRowHeight;
        int column = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));

        int day = column - findDayOffset() + 1;
        day += row * mNumDays;
        if (day < 1 || day > mNumCells) {
            return null;
        }
        return new CalendarDay(mYear, mMonth, day);
    }
1121156
public static void setCalendarData(Calendar calendar, Locale locale)
    {
        int[] array = (int[])localeData.get(locale);
        if(array == null)
        {
            Calendar c = Calendar.getInstance(locale);
            array = new int[2];
            array[0] = c.getFirstDayOfWeek();
            array[1] = c.getMinimalDaysInFirstWeek();
            localeData.putIfAbsent(locale, array);
        }
        calendar.setFirstDayOfWeek(array[0]);
        calendar.setMinimalDaysInFirstWeek(array[1]);
    }
203738
public static Calendar beginOfWeek(Calendar calendar, boolean isMondayAsFirstDay) {
		if(isMondayAsFirstDay) {
			calendar.setFirstDayOfWeek(Calendar.MONDAY);
		}
		return truncate(calendar, DateField.WEEK_OF_MONTH);
	}
345711
private void writeAssignmentTimephasedData(ResourceAssignment mpx, Project.Assignments.Assignment xml)
   {
      if (m_writeTimphasedData && mpx.getHasTimephasedData())
      {
         List<TimephasedDataType> list = xml.getTimephasedData();
         ProjectCalendar calendar = mpx.getCalendar();
         BigInteger assignmentID = xml.getUID();

         List<TimephasedWork> complete = mpx.getTimephasedActualWork();
         List<TimephasedWork> planned = mpx.getTimephasedWork();

         if (m_splitTimephasedAsDays)
         {
            TimephasedWork lastComplete = null;
            if (complete != null && !complete.isEmpty())
            {
               lastComplete = complete.get(complete.size() - 1);
            }

            TimephasedWork firstPlanned = null;
            if (planned != null && !planned.isEmpty())
            {
               firstPlanned = planned.get(0);
            }

            if (planned != null)
            {
               planned = splitDays(calendar, mpx.getTimephasedWork(), null, lastComplete);
            }

            if (complete != null)
            {
               complete = splitDays(calendar, complete, firstPlanned, null);
            }
         }

         if (planned != null)
         {
            writeAssignmentTimephasedData(assignmentID, list, planned, 1);
         }

         if (complete != null)
         {
            writeAssignmentTimephasedData(assignmentID, list, complete, 2);
         }
      }
   }
1238623
protected void moveToIntervalStart(Calendar cal) {
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.clear();
        cal.set(year, month, day);
    }
733318
public static Calendar beginOfQuarter(Calendar calendar) {
		calendar.set(Calendar.MONTH, calendar.get(DateField.MONTH.getValue()) / 3 * 3);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return beginOfDay(calendar);
	}
513351
private LinkedList<TimephasedWork> readTimephasedAssignment(ProjectCalendar calendar, Project.Assignments.Assignment assignment, int type)
   {
      LinkedList<TimephasedWork> result = new LinkedList<TimephasedWork>();

      for (TimephasedDataType item : assignment.getTimephasedData())
      {
         if (NumberHelper.getInt(item.getType()) != type)
         {
            continue;
         }

         Date startDate = item.getStart();
         Date finishDate = item.getFinish();

         // Exclude ranges which don't have a start and end date.
         // These seem to be generated by Synchro and have a zero duration.
         if (startDate == null && finishDate == null)
         {
            continue;
         }

         Duration work = DatatypeConverter.parseDuration(m_projectFile, TimeUnit.MINUTES, item.getValue());
         if (work == null)
         {
            work = Duration.getInstance(0, TimeUnit.MINUTES);
         }
         else
         {
            work = Duration.getInstance(NumberHelper.round(work.getDuration(), 2), TimeUnit.MINUTES);
         }

         TimephasedWork tra = new TimephasedWork();
         tra.setStart(startDate);
         tra.setFinish(finishDate);
         tra.setTotalAmount(work);

         result.add(tra);
      }

      return result;
   }
316300
private boolean isSplit(ProjectCalendar calendar, List<TimephasedWork> list)
   {
      boolean result = false;
      for (TimephasedWork assignment : list)
      {
         if (calendar != null && assignment.getTotalAmount().getDuration() == 0)
         {
            Duration calendarWork = calendar.getWork(assignment.getStart(), assignment.getFinish(), TimeUnit.MINUTES);
            if (calendarWork.getDuration() != 0)
            {
               result = true;
               break;
            }
         }
      }
      return result;
   }
1142195
public int setCalendar(Calendar value, boolean bDisplayOption, int moveMode)
    {           // Set this field's value
        if (value != null)
        {
            value.set(Calendar.YEAR, DBConstants.FIRST_YEAR);
            value.set(Calendar.MONTH, Calendar.JANUARY);
            value.set(Calendar.DATE, 1);
        }
        return super.setCalendar(value, bDisplayOption, moveMode);
    }
865631
public static Calendar[] split(final Calendar calendar) {
        // if calendar contains one component or less, or is composed entirely of timezone
        // definitions, return the original calendar unmodified..
        if (calendar.getComponents().size() <= 1
                || calendar.getComponents(Component.VTIMEZONE).size() == calendar.getComponents().size()) {
            return new Calendar[] {calendar};
        }
        
        final ComponentList<VTimeZone> timezoneList = calendar.getComponents(Component.VTIMEZONE);
		final IndexedComponentList<VTimeZone> timezones = new IndexedComponentList<VTimeZone>(
        		timezoneList, Property.TZID);
        
        final Map<Uid, Calendar> calendars = new HashMap<Uid, Calendar>();
        for (final CalendarComponent c : calendar.getComponents()) {
            if (c instanceof VTimeZone) {
                continue;
            }
            
            final Uid uid = c.getProperty(Property.UID);
            
            Calendar uidCal = calendars.get(uid);
            if (uidCal == null) {
                uidCal = new Calendar(calendar.getProperties(), new ComponentList<CalendarComponent>());
                // remove METHOD property for split calendars..
                for (final Property mp : uidCal.getProperties(Property.METHOD)) {
                    uidCal.getProperties().remove(mp);
                }
                calendars.put(uid, uidCal);
            }
            
            for (final Property p : c.getProperties()) {
                final TzId tzid = p.getParameter(Parameter.TZID);
                if (tzid != null) {
                    final VTimeZone timezone = timezones.getComponent(tzid.getValue());
                    if (!uidCal.getComponents().contains(timezone)) {
                        uidCal.getComponents().add(timezone);
                    }
                }
            }
            uidCal.getComponents().add(c);
        }
        return calendars.values().toArray(new Calendar[0]);
    }