-5

I want to generate a sequence of time in the following format (yyyy-mm-dd hh:mm:ss) with time interval of 15 min. I will give start date and end date.

Used the below code to test the same.

public static void main(String[] args) throws ParseException {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-mm-dd HH:mm:ss");
        DateTime dt1 = formatter.parseDateTime("2017-06-21 00:00:00");
        DateTime dt2 = formatter.parseDateTime("2017-06-23 00:00:00");

        DateTime dateTime1 = new DateTime(dt1);

        DateTime dateTime2 = new DateTime(dt2);
        List<Date> allDates = new ArrayList();

        while( dateTime1.isBefore(dateTime2) ){
           allDates.add( dateTime1.toDate() );
           dateTime1 = dateTime1.plusMinutes(15);

           System.out.println(dateTime1);
        }

It generates output like below:

2017-01-21T00:15:00.000+05:30

Expected output is 2017-06-21 00:00:00 , it's not picking up the right date which I wanted.

  • 4
    Look at your pattern. Does it look normal to you that the same `mm` pattern is used both for months and minutes? – JB Nizet Jun 25 '17 at 07:53
  • I have changed the pattern to "YYYY-MM-DD HH:mm:ss" , still not getting the expected output. getting the same output. 2017-01-21T00:15:00.000+05:30 2017-01-21T00:30:00.000+05:30 2017-01-21T00:45:00.000+05:30 – Vishal Patial Jun 25 '17 at 08:03
  • 5
    Don't do random things. Read the documentation to use the **right** pattern. – JB Nizet Jun 25 '17 at 08:04

2 Answers2

1

tl;dr

Use java.time classes, which supplant the Joda-Time project. Convert input to standard format for easy parsing.

LocalDateTime.parse( 
    "2017-06-23 00:00:00".replace( " " , "T" ) 
).plus( Duration.ofMinutes( 15 ) ) 

Details

As noted by JB Nizet, you are using incorrect codes in your formatting pattern. Apparently you are guessing at the codes rather reading the documentation – an unwise practice. These codes have been covered hundreds of times on Stack Overflow, so apparently you are posting here without bothering to first search.

Joda-Time vs java.time

You are using the Joda-Time library. This project is now in maintenance mode, with the team advising migration to the java.time classes.

ISO 8601 standard

Your input strings nearly comply with the ISO 8601 standard. To fully comply, replace the SPACE in the middle with a T. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to define any formatting pattern.

Caveat about LocalDateTime

Your input lacks any indication of time zone or offset-from-UTC. So we will parse as LocalDateTime. Beware that a LocalDateTime is not a real moment, not an actual point on the timeline. Without the context of a time zone or offset, a LocalDateTime is unrealistic.

Solution

LocalDateTime start = LocalDateTime.parse( "2017-06-21 00:00:00".replace( " " , "T" ) ) ;
LocalDateTime stop = LocalDateTime.parse( "2017-06-23 00:00:00".replace( " " , "T" ) ) ;

For defensive programming, verify your start is before your stop. Something like stop.isAfter( start ).

On each loop, add your specified duration of 15 minutes.

Duration d = Duration.ofMinutes( 15 ) ;
LocalDateTime ldt = start ;
List< LocalDateTime > ldts = new ArrayList<>() ;

while( ! ldt.isAfter( stop ) ) {  // "Not after" is a shorter way of saying "is earlier than or is equal to".
    ldts.add( ldt ) ;
    // Set up the next loop.
    ldt = ldt.plus( d ) ;
}

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

First of all, read the javadoc. The lowercase mm pattern corresponds to the minutes. To get the months, you need to use uppercase MM. So, your formatter will be like this:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

And you don't need to do this:

DateTime dateTime1 = new DateTime(dt1);

It's redundant, because you're creating 2 identical objects. Just use the dates returned by parseDateTime method. Or just do:

DateTime dateTime1 = dt1;

And you've already created a DateTimeFormatter, so just use it to format the output as well. Instead of:

System.out.println(dateTime1);

Do this:

System.out.println(formatter.print(dateTime1));

The print method will return the dates in the format you want.

I'm not sure if you wanted to print the first date (2017-06-21 00:00:00). If you want this, just change the order of the plusMinutes and System.out.println lines.


New Java Date/Time API

Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".

So, if you can migrate your Joda-Time code, or starting a new project, consider using the new API. If you're using Java 8, you can use the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

The logic is very similar. The only difference is that I used LocalDateTime class, and to convert it to a java.util.Date I need to know in what timezone it is. I used the system's default timezone, which is probably what you want (as your original code also uses the default timezone):

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime1 = LocalDateTime.parse("2017-06-21 00:00:00", formatter);
LocalDateTime dateTime2 = LocalDateTime.parse("2017-06-23 00:00:00", formatter);

List<Date> allDates = new ArrayList();

while (dateTime1.isBefore(dateTime2)) {
    // get the date in the system default timezone and convert to java.util.Date
    allDates.add(Date.from(dateTime1.atZone(ZoneId.systemDefault()).toInstant()));
    dateTime1 = dateTime1.plusMinutes(15);

    System.out.println(formatter.format(dateTime1));
}

In Java 8 the Date.from method is available. In ThreeTen Backport (Java 7 and Android), you can use the org.threeten.bp.DateTimeUtils class instead:

allDates.add(DateTimeUtils.toDate(dateTime1.atZone(ZoneId.systemDefault()).toInstant()));
Community
  • 1
  • 1