Example usage for org.joda.time Years yearsBetween

List of usage examples for org.joda.time Years yearsBetween

Introduction

In this page you can find the example usage for org.joda.time Years yearsBetween.

Prototype

public static Years yearsBetween(ReadablePartial start, ReadablePartial end) 

Source Link

Document

Creates a Years representing the number of whole years between the two specified partial datetimes.

Usage

From source file:ar.com.zir.utils.DateUtils.java

License:Open Source License

/**
 * Method that uses Joda Library to obtain the difference between two dates
 * in the specified date part//from   w w w. j  av  a2 s.  c  o  m
 * 
 * @param datePart the datePart to use in the calculation
 * @param date1 first Date object
 * @param date2 second Date object
 * @return the result from date1 - date2 or -1 if specified datePart is not supported
 * @see java.util.Calendar
 */
public static int dateDiff(int datePart, Date date1, Date date2) {
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);
    switch (datePart) {
    case DATE_PART_SECOND:
        return Seconds
                .secondsBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getSeconds();
    case DATE_PART_MINUTE:
        return Minutes
                .minutesBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getMinutes();
    case DATE_PART_HOUR:
        return Hours.hoursBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getHours();
    case DATE_PART_DAY:
        return Days.daysBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getDays();
    case DATE_PART_MONTH:
        return Months.monthsBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getMonths();
    case DATE_PART_YEAR:
        return Years.yearsBetween(new DateTime(cal2.getTimeInMillis()), new DateTime(cal1.getTimeInMillis()))
                .getYears();
    default:
        return -1;
    }

}

From source file:ar.edu.utn.frre.dacs.sample.model.Cliente.java

License:Apache License

/**
 * Retorna la edad del cliente en base a la fecha de nacimiento y la 
 * fecha actual./*w  ww.j  a v  a 2 s  .com*/
 * @return Edad del Cliente.
 */
public int getEdad() {
    if (fechaNacimiento == null)
        return 0;

    LocalDate birthdate = new LocalDate(fechaNacimiento.getTime());
    LocalDate now = new LocalDate();
    Years age = Years.yearsBetween(birthdate, now);

    return age.getYears();
}

From source file:be.fedict.eid.idp.attribute.age.AgeAttributeService.java

License:Open Source License

public void addAttribute(Map<String, Attribute> attributeMap) {
    Attribute dobAttribute = attributeMap.get(DefaultAttribute.DATE_OF_BIRTH.getUri());
    if (null == dobAttribute) {
        return;/*from w ww. j  av  a2s .c o m*/
    }
    LOG.debug("Add age attribute");
    GregorianCalendar dobValue = (GregorianCalendar) dobAttribute.getValue();
    DateTime dob = new DateTime(dobValue.getTime());
    DateTime now = new DateTime();
    Years years = Years.yearsBetween(dob, now);
    int age = years.getYears();
    attributeMap.put(URI, new Attribute(URI, AttributeType.INTEGER, age));
}

From source file:c4a.platform.services.wsServices.java

@GET
@Path("getCareReceivers")
@Consumes("application/json")
@Produces("application/json")
public C4ACareReceiversResponse getJson() throws IOException {
    /**//w ww .  j  a  v  a2 s  .  c o m
     * ****************Variables*************
     */
    System.out.println("******************start*****************");
    C4ACareReceiversResponse response = new C4ACareReceiversResponse();
    TypedQuery query;
    TypedQuery query_crProfile;
    TypedQuery query_users;
    TypedQuery query_frailty;

    List<UserInRole> userinroleparamsList;
    List<CrProfile> crprofileparamsList;
    List<CareProfile> careprofileparamsList;
    List<FrailtyStatusTimeline> frailtyparamsList;
    ArrayList<C4ACareReceiverListResponse> itemList;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    /**
     * ****************Action*************
     */
    //        if (em == null) {
    //            init();
    //        }

    query_users = (TypedQuery) em.createQuery("SELECT u FROM UserInRole u Where u.roleId.id =1");

    userinroleparamsList = query_users.getResultList();

    if (userinroleparamsList.isEmpty()) {
        response.setMessage("No users found");
        response.setResponseCode(0);
        return response;
    } else {
        itemList = new ArrayList<C4ACareReceiverListResponse>();
        for (UserInRole users : userinroleparamsList) {
            response.setMessage("success");
            response.setResponseCode(10);
            System.out.println("id " + users.getId() + "name " + users.getUserInSystemId().getUsername());

            query_crProfile = (TypedQuery) em
                    .createQuery("SELECT c FROM CrProfile c Where c.userInRoleId.id = :userId ");
            query_crProfile.setParameter("userId", users.getId());

            //we use list to avoid "not found" exception
            crprofileparamsList = query_crProfile.getResultList();
            int age = 0;
            if (!crprofileparamsList.isEmpty()) {

                LocalDate birthDate = new LocalDate(crprofileparamsList.get(0).getBirthDate());
                Years age2 = Years.yearsBetween(birthDate, new LocalDate());
                age = age2.getYears();
                //                    System.out.println("age2 " + age2.getYears());
                //                    System.out.println("user name " + crprofileparamsList.get(0).getUserInRoleId().getId()
                //                            + " birthDate " + birthDate);
            }

            query = (TypedQuery) em.createQuery("SELECT c FROM CareProfile c WHERE c.userInRole.id = :userId ");
            query.setParameter("userId", users.getId());
            //we use list to avoid "not found" exception
            careprofileparamsList = query.getResultList();
            //**************************************
            String frailtyStatus = null;
            String frailtyNotice = null;
            char attention = 0;
            String textline = null;
            char interventionstatus = 0;
            String interventionDate = null;
            String detectionStatus = null;
            String detectionDate = null;
            if (!careprofileparamsList.isEmpty()) {
                //                    frailtyStatus = careprofileparamsList.get(0).getFrailtyStatus();
                //                    frailtyNotice = careprofileparamsList.get(0).getFrailtyNotice();
                attention = careprofileparamsList.get(0).getAttentionStatus();
                textline = careprofileparamsList.get(0).getIndividualSummary();
                interventionstatus = careprofileparamsList.get(0).getInterventionStatus();
                interventionDate = sdf.format(careprofileparamsList.get(0).getLastInterventionDate());
                //                    detectionStatus = careprofileparamsList.get(0).getDetectionStatus();
                //                    detectionDate = sdf.format(new Date(careprofileparamsList.get(0).getLastDetection() * 1000));
                //                    System.out.println("user id " + careprofileparamsList.get(0).getUserInRoleId()
                //                            + " frailty status " + careprofileparamsList.get(0).getFrailtyStatus());
            }

            query_frailty = (TypedQuery) em.createQuery(
                    "SELECT f FROM FrailtyStatusTimeline f WHERE f.frailtyStatusTimelinePK.userInRoleId = :userId ");
            query_frailty.setParameter("userId", users.getId());
            //we use list to avoid "not found" exception
            frailtyparamsList = query_frailty.getResultList();
            if (!frailtyparamsList.isEmpty()) {
                frailtyStatus = frailtyparamsList.get(0).getFrailtyStatus().getFrailtyStatus();
                frailtyNotice = frailtyparamsList.get(0).getFrailtyNotice();

                //                    System.out.println("user id " + frailtyparamsList.get(0).getFrailtyStatusTimelinePK().getUserInRoleId()
                //                            + " frailty status " + frailtyparamsList.get(0).getFrailtyStatus().getFrailtyStatus());
            }

            itemList.add(new C4ACareReceiverListResponse(users.getId(), age, frailtyStatus, frailtyNotice,
                    attention, textline, interventionstatus, interventionDate, detectionStatus, detectionDate));
        } //detectionVariables loop    
        response.setItemList(itemList);

    } //end detectionVariables is empty

    return response;

}

From source file:ch.thn.gedcom.GedcomHelper.java

License:Apache License

/**
 * Calculates the age of the person between the given birthDate and the toDate
 * /*  w w  w .  j a  va  2s  .  com*/
 * @param fromDate
 * @param toDate
 * @return
 */
public static int getAge(Date fromDate, Date toDate) {
    if (fromDate == null || toDate == null) {
        return 0;
    }

    DateMidnight bd = new DateMidnight(fromDate);
    DateTime now = new DateTime(toDate);
    Years age = Years.yearsBetween(bd, now);
    return age.getYears();
}

From source file:co.malm.mglam_reads.backend.util.DateDiffUtil.java

License:Apache License

/**
 * Calculates time differences using two dates, and stores it into a
 * {@linkplain java.util.Map} object.//  www  . j av  a2s .c  o m
 *
 * @param map calculations data
 * @param dt1 first date for diff
 * @param dt2 second date for diff
 * @see org.joda.time.DateTime
 * @see org.joda.time.Years
 * @see org.joda.time.Months
 * @see org.joda.time.Weeks
 * @see org.joda.time.Days
 * @see org.joda.time.Hours
 * @see org.joda.time.Minutes
 * @see org.joda.time.Seconds
 */
private void calculate(HashMap<String, Integer> map, DateTime dt1, DateTime dt2) {

    final int SECONDS_IN_MINUTE = 60;
    final int MINUTES_IN_HOUR = 60;
    final int HOURS_IN_DAY = 24;
    final int DAYS_IN_MONTH = 31;
    final int MONTHS_IN_YEAR = 12;
    final int WEEKS_IN_DAY = 7;

    int diffYears = Years.yearsBetween(dt1, dt2).getYears();
    if (diffYears > 0) {
        map.put("years", diffYears);
    }

    int diffMonths = Months.monthsBetween(dt1, dt2).getMonths();
    if (diffMonths >= 1 && diffMonths < MONTHS_IN_YEAR) {
        map.put("months", diffMonths);
    }

    int diffWeeks = Weeks.weeksBetween(dt1, dt2).getWeeks();
    if (diffWeeks >= 1 && diffWeeks < WEEKS_IN_DAY) {
        map.put("weeks", diffWeeks);
    }

    int diffDays = Days.daysBetween(dt1, dt2).getDays();
    if (diffDays >= 1 && diffDays < DAYS_IN_MONTH) {
        map.put("days", diffDays);
    }

    int diffHours = Hours.hoursBetween(dt1, dt2).getHours();
    if (diffHours >= 1 && diffHours < HOURS_IN_DAY) {
        map.put("hours", diffHours);
    }

    int diffMinutes = Minutes.minutesBetween(dt1, dt2).getMinutes();
    if (diffMinutes >= 1 && diffMinutes < MINUTES_IN_HOUR) {
        map.put("minutes", diffMinutes);
    }

    int diffSeconds = Seconds.secondsBetween(dt1, dt2).getSeconds();
    if (diffSeconds >= 1 && diffSeconds < SECONDS_IN_MINUTE) {
        map.put("seconds", diffSeconds);
    }
}

From source file:com.billing.ng.entities.CurrentBillingCycle.java

License:Open Source License

/**
 * Calculates the number of complete cycles between the given billing start date and
 * the given "today's" date.//from w  ww .  j av a 2 s . com
 *
 * @param period billing period
 * @param billingStart billing cycle start
 * @param today end date
 * @return number of complete cycles
 */
public static Integer calculateCycleNumber(BillingPeriod period, DateMidnight billingStart,
        DateMidnight today) {
    Integer interval = period.getInterval();

    switch (period.getType()) {
    case DAY:
        return Days.daysBetween(billingStart, today).getDays() / interval;

    case WEEK:
        return Weeks.weeksBetween(billingStart, today).getWeeks() / interval;

    case MONTH:
        return Months.monthsBetween(billingStart, today).getMonths() / interval;

    case YEAR:
        return Years.yearsBetween(billingStart, today).getYears() / interval;
    }
    return null;
}

From source file:com.boha.golfkids.util.NewGolfGroupUtil.java

private static int getPlayerAge(long date) {
    LocalDateTime birthday = new LocalDateTime(date);
    LocalDateTime start = new LocalDateTime();
    Years years = Years.yearsBetween(birthday, start);
    return years.getYears();
}

From source file:com.cisco.dvbu.ps.utils.date.DateDiffDate.java

License:Open Source License

/**
 * Called to invoke the stored procedure.  Will only be called a
 * single time per instance.  Can throw CustomProcedureException or
 * SQLException if there is an error during invoke.
 *///from ww w.j a  va2  s .c om
public void invoke(Object[] inputValues) throws CustomProcedureException, SQLException {
    java.util.Date startDate = null;
    java.util.Date endDate = null;
    Calendar startCal = null;
    Calendar endCal = null;
    DateTime startDateTime = null;
    DateTime endDateTime = null;
    String datePart = null;
    long dateLength = 0;

    try {
        result = null;
        if (inputValues[0] == null) {
            result = new Long(dateLength);
            return;
        }

        if (inputValues[1] == null) {
            result = new Long(dateLength);
            return;
        }

        if (inputValues[2] == null) {
            result = new Long(dateLength);
            return;
        }

        datePart = (String) inputValues[0];
        startDate = (java.util.Date) inputValues[1];
        startCal = Calendar.getInstance();
        startCal.setTime(startDate);

        endDate = (java.util.Date) inputValues[2];
        endCal = Calendar.getInstance();
        endCal.setTime(endDate);

        startDateTime = new DateTime(startCal.get(Calendar.YEAR), startCal.get(Calendar.MONTH) + 1,
                startCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0, 0);
        endDateTime = new DateTime(endCal.get(Calendar.YEAR), endCal.get(Calendar.MONTH) + 1,
                endCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0, 0);

        if (datePart.equalsIgnoreCase("second")) {
            Seconds seconds = Seconds.secondsBetween(startDateTime, endDateTime);
            dateLength = seconds.getSeconds();
        }

        if (datePart.equalsIgnoreCase("minute")) {
            Minutes minutes = Minutes.minutesBetween(startDateTime, endDateTime);
            dateLength = minutes.getMinutes();
        }

        if (datePart.equalsIgnoreCase("hour")) {
            Hours hours = Hours.hoursBetween(startDateTime, endDateTime);
            dateLength = hours.getHours();
        }

        if (datePart.equalsIgnoreCase("day")) {
            Days days = Days.daysBetween(startDateTime, endDateTime);
            dateLength = days.getDays();
        }

        if (datePart.equalsIgnoreCase("week")) {
            Weeks weeks = Weeks.weeksBetween(startDateTime, endDateTime);
            dateLength = weeks.getWeeks();
        }

        if (datePart.equalsIgnoreCase("month")) {
            Months months = Months.monthsBetween(startDateTime, endDateTime);
            dateLength = months.getMonths();
        }

        if (datePart.equalsIgnoreCase("year")) {
            Years years = Years.yearsBetween(startDateTime, endDateTime);
            dateLength = years.getYears();
        }

        result = new Long(dateLength);
    } catch (Throwable t) {
        throw new CustomProcedureException(t);
    }
}

From source file:com.eucalyptus.portal.Ec2ReportsService.java

License:Open Source License

public ViewInstanceUsageReportResponseType viewInstanceUsageReport(final ViewInstanceUsageReportType request)
        throws Ec2ReportsServiceException {
    final ViewInstanceUsageReportResponseType response = request.getReply();
    final Context context = checkAuthorized();
    try {//from w  w  w.  j  a  va  2s  .c  o  m
        final Function<ViewInstanceUsageReportType, Optional<Ec2ReportsServiceException>> requestVerifier = (
                req) -> {
            if (req.getGranularity() == null)
                return Optional.of(new Ec2ReportsInvalidParameterException("Granularity must be specified"));
            final String granularity = req.getGranularity().toLowerCase();
            if (request.getTimeRangeStart() == null || request.getTimeRangeEnd() == null)
                return Optional.of(
                        new Ec2ReportsInvalidParameterException("time range start and end must be specified"));

            if (!Sets.newHashSet("hourly", "hour", "daily", "day", "monthly", "month").contains(granularity)) {
                return Optional.of(new Ec2ReportsInvalidParameterException(
                        "Can't recognize granularity. Valid values are hourly, daily and monthly"));
            }

            if (granularity.equals("hourly") || granularity.equals("hour")) {
                // AWS: time range up to 7 days when using an hourly data granularity
                if (Days.daysBetween(new DateTime(request.getTimeRangeStart().getTime()),
                        new DateTime(request.getTimeRangeEnd().getTime())).getDays() > 7) {
                    return Optional.of(new Ec2ReportsInvalidParameterException(
                            "time range is allowed up to 7 days when using an hourly data granularity"));
                }
            } else if (granularity.equals("daily") || granularity.equals("day")) {
                // AWS: time range up to 3 months when using a daily data granularity
                if (Months.monthsBetween(new DateTime(request.getTimeRangeStart().getTime()),
                        new DateTime(request.getTimeRangeEnd().getTime())).getMonths() > 3) {
                    return Optional.of(new Ec2ReportsInvalidParameterException(
                            "time range is allowed up to 3 months when using a daily data granularity"));
                }
            } else {
                // AWS: time range up to 3 years when using a monthly data granularity.
                if (Years.yearsBetween(new DateTime(request.getTimeRangeStart().getTime()),
                        new DateTime(request.getTimeRangeEnd().getTime())).getYears() > 3) {
                    return Optional.of(new Ec2ReportsInvalidParameterException(
                            "time range is allowed up to 3 years when using a monthly data granularity"));
                }
            }

            if (request.getGroupBy() != null) {
                if (request.getGroupBy().getType() == null)
                    return Optional.of(new Ec2ReportsInvalidParameterException(
                            "In group by parameter, type must be specified"));
                final String groupType = request.getGroupBy().getType().toLowerCase();
                final String groupKey = request.getGroupBy().getKey();
                if (!Sets.newHashSet("tag", "tags", "instancetype", "instance_type", "platform", "platforms",
                        "availabilityzone", "availability_zone").contains(groupType)) {
                    return Optional.of(new Ec2ReportsInvalidParameterException(
                            "supported types in group by parameter are: tag, instance_type, platform, and availability_zone"));
                }
                if ("tag".equals(groupType) || "tags".equals(groupType)) {
                    if (groupKey == null) {
                        return Optional.of(new Ec2ReportsInvalidParameterException(
                                "tag type in group by parameter must also include tag key"));
                    }
                }
            }
            return Optional.empty();
        };
        final Optional<Ec2ReportsServiceException> error = requestVerifier.apply(request);
        if (error.isPresent()) {
            throw error.get();
        }

        final String granularity = request.getGranularity().toLowerCase();
        final List<InstanceHourLog> logs = Lists.newArrayList();
        if (granularity.equals("hourly") || granularity.equals("hour")) {
            logs.addAll(InstanceLogs.getInstance().queryHourly(context.getAccountNumber(),
                    request.getTimeRangeStart(), request.getTimeRangeEnd(), request.getFilters()));
        } else if (granularity.equals("daily") || granularity.equals("day")) {
            logs.addAll(InstanceLogs.getInstance().queryDaily(context.getAccountNumber(),
                    request.getTimeRangeStart(), request.getTimeRangeEnd(), request.getFilters()));
        } else {
            logs.addAll(InstanceLogs.getInstance().queryMonthly(context.getAccountNumber(),
                    request.getTimeRangeStart(), request.getTimeRangeEnd(), request.getFilters()));
        }

        Collector<InstanceHourLog, ?, Map<String, List<InstanceHourLog>>> collector = null;
        Comparator<String> keySorter = String::compareTo; // determines which column appear first
        if (request.getGroupBy() != null) {
            final String groupType = request.getGroupBy().getType().toLowerCase();
            final String groupKey = request.getGroupBy().getKey();
            if ("instancetype".equals(groupType) || "instance_type".equals(groupType)) {
                collector = groupingBy((log) -> log.getInstanceType(), toList());
                keySorter = String::compareTo; // sort by type name is natural
            } else if ("platform".equals(groupType) || "platforms".equals(groupType)) {
                collector = groupingBy((log) -> log.getPlatform(), toList());
                keySorter = String::compareTo; // linux comes before windows
            } else if ("availabilityzone".equals(groupType) || "availability_zone".equals(groupType)) {
                collector = groupingBy((log) -> log.getAvailabilityZone(), toList());
                keySorter = String::compareTo;
            } else if ("tag".equals(groupType) || "tags".equals(groupType)) {
                // map instanceId to tag value where tag key = group key
                final Map<String, String> tagValueMap = logs.stream()
                        .collect(groupingBy((log) -> log.getInstanceId(), toList())).entrySet().stream()
                        .map(e -> e.getValue().get(0))
                        .filter(l -> l.getTags().stream().filter(t -> groupKey.equals(t.getKey())).findAny()
                                .isPresent())
                        .collect(Collectors.toMap(l -> l.getInstanceId(), l -> l.getTags().stream()
                                .filter(t -> groupKey.equals(t.getKey())).findAny().get().getValue()));
                logs.stream().forEach(l -> {
                    if (!tagValueMap.containsKey(l.getInstanceId()))
                        tagValueMap.put(l.getInstanceId(), "[UNTAGGED]");
                });
                collector = groupingBy((log) -> tagValueMap.get(log.getInstanceId()), toList());
                keySorter = (s1, s2) -> {
                    if ("[UNTAGGED]".equals(s1) && "[UNTAGGED]".equals(s2))
                        return 0;
                    else if ("[UNTAGGED]".equals(s1))
                        return -1;
                    else if ("[UNTAGGED]".equals(s2))
                        return 1;
                    else
                        return s1.compareTo(s2);
                };
            } else {
                throw new Ec2ReportsInvalidParameterException(
                        "supported types in group by parameter are: tag, instance_type, platform, and availability_zone");
            }
        } else {
            collector = groupingBy((log) -> "[INSTANCE HOURS]", toList());
        }
        final Function<Date, AbstractMap.SimpleEntry<Date, Date>> ranger = (logTime) -> {
            final Calendar start = Calendar.getInstance();
            final Calendar end = Calendar.getInstance();
            start.setTime(logTime);
            end.setTime(logTime);
            if (granularity.equals("hourly") || granularity.equals("hour")) {
                end.set(Calendar.HOUR_OF_DAY, end.get(Calendar.HOUR_OF_DAY) + 1);
            } else if (granularity.equals("daily") || granularity.equals("day")) {
                end.set(Calendar.DAY_OF_MONTH, start.get(Calendar.DAY_OF_MONTH) + 1);
                start.set(Calendar.HOUR_OF_DAY, 0);
                end.set(Calendar.HOUR_OF_DAY, 0);
            } else {
                end.set(Calendar.MONTH, start.get(Calendar.MONTH) + 1);
                start.set(Calendar.DAY_OF_MONTH, 1);
                start.set(Calendar.HOUR_OF_DAY, 0);
                end.set(Calendar.DAY_OF_MONTH, 1);
                end.set(Calendar.HOUR_OF_DAY, 0);
            }
            for (final int flag : new int[] { Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) {
                start.set(flag, 0);
                end.set(flag, 0);
            }
            return new AbstractMap.SimpleEntry<Date, Date>(start.getTime(), end.getTime());
        };

        // sum over instance hours whose log_time is the same
        /* e.g.,
           INPUT:
           m1.small -> [(i-1d9eb607,2017-03-16 12:00:00), (i-1d9eb607,2017-03-16 13:00:00), (i-fe4a9384,2017-03-16 13:00:00)]
                
           OUTPUT:
           m1.small -> [2017-03-16 12:00:00: 1, 2017-03-16 13:00:00: 2]
         */
        final Map<String, List<InstanceHourLog>> logsByGroupKey = logs.stream().collect(collector);
        final Map<String, Map<Date, Long>> hoursAtLogTimeByGroupKey = logsByGroupKey.entrySet().stream()
                .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().stream()
                        .collect(groupingBy(l -> l.getLogTime(), summingLong(l -> l.getHours())) // -> Map<String, Map<Date, Long>
        )));
        // key -> [(log_time, hours)...]
        final Map<String, List<AbstractMap.SimpleEntry<Date, Long>>> instanceHoursAtLogTime = hoursAtLogTimeByGroupKey
                .entrySet().stream()
                .collect(Collectors.toMap(e -> e.getKey(),
                        e -> e.getValue().entrySet().stream()
                                .map(e1 -> new AbstractMap.SimpleEntry<Date, Long>(e1.getKey(), e1.getValue()))
                                .collect(toList())));

        final StringBuilder sb = new StringBuilder();
        sb.append("Start Time,End Time");
        for (final String key : instanceHoursAtLogTime.keySet().stream().sorted(keySorter).collect(toList())) {
            sb.append(String.format(",%s", key));
        }

        // fill-in missing logs (with 0 hours) in the table
        final Set<Date> distinctLogs = instanceHoursAtLogTime.values().stream().flatMap(e -> e.stream())
                .map(kv -> kv.getKey()).distinct().collect(toSet());
        for (final String groupKey : instanceHoursAtLogTime.keySet()) {
            final List<AbstractMap.SimpleEntry<Date, Long>> hours = instanceHoursAtLogTime.get(groupKey);
            final Set<Date> currentLogs = hours.stream().map(kv -> kv.getKey()).collect(toSet());
            final List<AbstractMap.SimpleEntry<Date, Long>> normalized = Lists.newArrayList(hours);
            for (final Date missing : Sets.difference(distinctLogs, currentLogs)) {
                normalized.add(new AbstractMap.SimpleEntry<Date, Long>(missing, 0L));
            }
            instanceHoursAtLogTime.put(groupKey, normalized);
        }

        final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        final Map<Date, String> lines = Maps.newHashMap();
        for (final String groupKey : instanceHoursAtLogTime.keySet().stream().sorted(keySorter)
                .collect(toList())) {
            for (final AbstractMap.SimpleEntry<Date, Long> hl : instanceHoursAtLogTime.get(groupKey)) {
                final Date logTime = hl.getKey();
                final Long hours = hl.getValue();
                if (!lines.containsKey(logTime)) {
                    lines.put(logTime, String.format("%s,%s,%d", df.format(ranger.apply(logTime).getKey()),
                            df.format(ranger.apply(logTime).getValue()), hours));
                } else {
                    lines.put(logTime, String.format("%s,%d", lines.get(logTime), hours));
                }
            }
        }

        lines.entrySet().stream().sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey())) // order by log time
                .map(e -> e.getValue()).forEach(s -> sb.append(String.format("\n%s", s)));
        final ViewInstanceUsageResult result = new ViewInstanceUsageResult();
        result.setUsageReport(sb.toString());
        response.setResult(result);
    } catch (final Ec2ReportsServiceException ex) {
        throw ex;
    } catch (final Exception ex) {
        handleException(ex);
    }
    return response;
}