Scrolling Dates using Calendar

4

I'm making a report on java , which passes a period specified by the user. In my%% of% I'm doing the treatment.

Here I pick up the date passed.

String data1 = DateUtil.toString(dto.getDataInicio(), "MM/yyyy");
        String data2 =  DateUtil.toString(dto.getDataFim(), "MM/yyyy");

        Calendar c1 = DateUtil.parseCal (data1);
        Calendar c2 = DateUtil.parseCal (data2);

Here I make a treatment to check the past months.

for (Calendar c = (Calendar) c1.clone(); c.compareTo (c2) <= 0; c.add (Calendar.DATE, +1)) {
           if (c.get (Calendar.MONTH) == Calendar.JANUARY  && c.get (Calendar.DAY_OF_MONTH) == 01){
                     mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-01-01', '"+c2.get(Calendar.YEAR)+"-01-01', to_char('"+c1.get(Calendar.YEAR)+"-01-01'::date, 'yyyy-mm'), cl.id_convenio) as janeiro, ";       
                       nomesMeses.add("Janeiro");
               }
             if (c.get (Calendar.MONTH) == Calendar.FEBRUARY && c.get (Calendar.DAY_OF_MONTH) == 01){
                            mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-02-01', '"+c2.get(Calendar.YEAR)+"-02-01', to_char('"+c1.get(Calendar.YEAR)+"-02-01'::date, 'yyyy-mm'), cl.id_convenio) as fevereiro, ";     
                            nomesMeses.add("Fevereiro");
               }     
             if (c.get (Calendar.MONTH) == Calendar.MARCH && c.get (Calendar.DAY_OF_MONTH) == 01){
                            mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-03-01', '"+c2.get(Calendar.YEAR)+"-03-01', to_char('"+c1.get(Calendar.YEAR)+"-03-01'::date, 'yyyy-mm'), cl.id_convenio) as marco, ";
                            nomesMeses.add("Março");
               }
             if (c.get (Calendar.MONTH) == Calendar.APRIL && c.get (Calendar.DAY_OF_MONTH) == 01){
                            mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-04-01', '"+c2.get(Calendar.YEAR)+"-04-01', to_char('"+c1.get(Calendar.YEAR)+"-04-01'::date, 'yyyy-mm'), cl.id_convenio) as abril, ";
                            nomesMeses.add("Abril");
               }
             if (c.get (Calendar.MONTH) == Calendar.MAY && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-05-01', '"+c2.get(Calendar.YEAR)+"-05-01', to_char('"+c1.get(Calendar.YEAR)+"-05-01'::date, 'yyyy-mm'), cl.id_convenio) as maio, ";
                            nomesMeses.add("Maio");
               }
             if (c.get (Calendar.MONTH) == Calendar.JUNE && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-06-01', '"+c2.get(Calendar.YEAR)+"-06-01', to_char('"+c1.get(Calendar.YEAR)+"-06-01'::date, 'yyyy-mm'), cl.id_convenio) as junho,  ";
                            nomesMeses.add("Junho");
               }
             if (c.get (Calendar.MONTH) == Calendar.JULY && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-07-01', '"+c2.get(Calendar.YEAR)+"-07-01', to_char('"+c1.get(Calendar.YEAR)+"-07-01'::date, 'yyyy-mm'), cl.id_convenio) as julho, ";
                            nomesMeses.add("Julho");
               }
             if (c.get (Calendar.MONTH) == Calendar.AUGUST && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-08-01', '"+c2.get(Calendar.YEAR)+"-08-01', to_char('"+c1.get(Calendar.YEAR)+"-08-01'::date, 'yyyy-mm'), cl.id_convenio) as agosto, ";
                            nomesMeses.add("Agosto");
               }
             if (c.get (Calendar.MONTH) == Calendar.SEPTEMBER && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-09-01', '"+c2.get(Calendar.YEAR)+"-09-01', to_char('"+c1.get(Calendar.YEAR)+"-09-01'::date, 'yyyy-mm'), cl.id_convenio) as setembro, ";
                            nomesMeses.add("Setembro");
               }
             if (c.get (Calendar.MONTH) == Calendar.OCTOBER && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-10-01', '"+c2.get(Calendar.YEAR)+"-10-01', to_char('"+c1.get(Calendar.YEAR)+"-10-01'::date, 'yyyy-mm'), cl.id_convenio) as outubro, ";
                            nomesMeses.add("Outubro");
               }
             if (c.get (Calendar.MONTH) == Calendar.NOVEMBER && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-11-01', '"+c2.get(Calendar.YEAR)+"-11-01', to_char('"+c1.get(Calendar.YEAR)+"-11-01'::date, 'yyyy-mm'), cl.id_convenio) as novembro, ";
                            nomesMeses.add("Novembro");
               }
             if (c.get (Calendar.MONTH) == Calendar.DECEMBER && c.get (Calendar.DAY_OF_MONTH) == 01){
                           mesesql += "total_faturado_mensal(cs.id_corp, '"+c1.get(Calendar.YEAR)+"-12-01', '"+c2.get(Calendar.YEAR)+"-12-01', to_char('"+c1.get(Calendar.YEAR)+"-12-01'::date, 'yyyy-mm'), cl.id_convenio) as dezembro, "; 
                            nomesMeses.add("Dezembro");
               }

            }

It is working, however when reporting a period for example from 01/2016 to 12/2016 it is not entering within DAO then only from January to November. But if I put only 11/2016 and 12/2016 the December appears. And to appear the 12 months of 2016, I have to put a month amis for example: 01/2016 á 01/2017 ai yes it brings me the month of December .... and so consequently, with larger dates. I do not understand much how Calendar works, am I doing something wrong?

    
asked by anonymous 01.02.2017 / 13:10

1 answer

5

One detail I suspect is that in for , you are increasing days, not months. On any day that is not a day 01, the iteration of for will not do anything, just hopping day by day. In addition, the amount of code repeated is immense. So let's redo your code:

String data1 = DateUtil.toString(dto.getDataInicio(), "MM/yyyy");
String data2 = DateUtil.toString(dto.getDataFim(), "MM/yyyy");

Calendar c1 = DateUtil.parseCal(data1);
Calendar c2 = DateUtil.parseCal(data2);

String[] meses = {
    "zero",
    "Janeiro", "Fevereiro", "Março", "Abril",
    "Maio", "Junho", "Julho", "Agosto",
    "Setembro", "Outubro", "Novembro", "Dezembro"
};

String template = "total_faturado_mensal(cs.id_corp, '$A-$I-01', '$B-$I-01', to_char('$A-$I-01'::date, 'yyyy-mm'), cl.id_convenio) as $M, ";

StringBuilder sb = new StringBuilder(8192);
sb.append(mesesql);

Calendar c = (Calendar) c1.clone();
while (c.compareTo(c2) <= 0) {
    int mes = c.get(Calendar.MONTH) + 1;
    sb.append(template
            .replace("$A", String.valueOf(c1.get(Calendar.YEAR)))
            .replace("$B", String.valueOf(c2.get(Calendar.YEAR)))
            .replace("$M", meses[mes])
            .replace("$I", mes < 10 ? "0" + mes : "" + mes));
    nomesMeses.add(meses[mes]);
    c.add(Calendar.MONTH, 1);
    c.set(Calendar.DATE, 1);
}

mesesql = sb.toString();

In this code above, I'm guessing that the DateUtil class works and has no bug or surprise. If this is not the case, it might go wrong, but then you'll have to post at least the toString and parseCal methods of it to take a look.

Another alternative is using package classes java.time , much better than using the appalling java.util.Calendar . Here's how the code looks:

Date a = dto.getDataInicio();
Date b = dto.getDataFim();

LocalDate c1 = a.toInstant().atOffset(ZoneOffset.UTC).toLocalDate().withDayOfMonth(1);
LocalDate c2 = b.toInstant().atOffset(ZoneOffset.UTC).toLocalDate().withDayOfMonth(1);

String[] meses = {
    "zero",
    "Janeiro", "Fevereiro", "Março", "Abril",
    "Maio", "Junho", "Julho", "Agosto",
    "Setembro", "Outubro", "Novembro", "Dezembro"
};

String template = "total_faturado_mensal(cs.id_corp, '$A-$I-01', '$B-$I-01', to_char('$A-$I-01'::date, 'yyyy-mm'), cl.id_convenio) as $M, ";

StringBuilder sb = new StringBuilder(8192);
sb.append(mesesql);

for (LocalDate c = c1; c.compareTo(c2) <= 0; c = c.plusMonths(1)) {
    int mes = c.getMonth().getValue();
    sb.append(template
            .replace("$A", String.valueOf(c1.getYear()))
            .replace("$B", String.valueOf(c2.getYear()))
            .replace("$M", meses[mes])
            .replace("$I", mes < 10 ? "0" + mes : "" + mes));
    nomesMeses.add(meses[mes]);
}

mesesql = sb.toString();

And in this code, of course, if you can change dto.getDataInicio() and dto.getDataFim() to return LocalDate instead of Date , it's easier.

    
01.02.2017 / 14:04