2

I am using a JSON file to store multiple entries for a conference. I am trying to get the current event that is on using date.before and date.after in a Calendar object in Java. My current code is returning three different events and I have no idea, I am wondering of anyone has any suggestions i've tried just about everything. I will attach the JSON and code below. I will also attach what the code puts into the console window.

Console Log

11-22 15:54:12.883 5797-5797/reloaded D/timetest:
    add event with name:Coffee Break
    time start: Tue Nov 22 15:30:00 GMT+00:00 18
    time end: Wed Nov 23 16:30:00 GMT+00:00 18
    time now: Wed Nov 23 15:45:00 GMT+00:00 18
11-22 15:54:12.885 5797-5797/reloaded D/timetest:
    add event with name:Panel Discussion
    time start: Tue Nov 22 16:30:00 GMT+00:00 18
    time end: Wed Nov 23 17:15:00 GMT+00:00 18
    time now: Wed Nov 23 15:45:00 GMT+00:00 18
11-22 15:54:12.888 5797-5797/reloaded D/timetest:
    add event with name:Turning Information into an Engaging Experience – The Design of Media Spaces
    time start: Tue Nov 22 17:15:00 GMT+00:00 18
    time end: Wed Nov 23 18:00:00 GMT+00:00 18
    time now: Wed Nov 23 15:45:00 GMT+00:00 18

JSON

{
      "eventid": "11",
      "roomid": "9",
      "type": "other",
      "name": "Coffee Break",
      "timestart": "15:30",
      "timeend": "16:30",
      "day": "1",
      "text": "Discover the Future Forum",
      "pic": "coffeecup.png",
      "speakerid": "1",
      "speaker": ""
    },
    {
      "eventid": "12",
      "roomid": "9",
      "type": "other",
      "name": "Panel Discussion",
      "timestart": "16:30",
      "timeend": "17:15",
      "day": "1",
      "text": "",
      "pic": "welcometalk.png",
      "speakerid": "1",
      "speaker": "fudged"
    },
    {
      "eventid": "13",
      "roomid": "9",
      "type": "lecture",
      "name": "Turning Information into an Engaging Experience – The Design of Media Spaces",
      "timestart": "17:15",
      "timeend": "18:00",
      "day": "1",
      "text": "fdsfsd",
      "pic": "p4.jpg",
      "speakerid": "6",
      "speaker": "test"
    },

Java

try {
    String string1 = "22/11/18 " + c.getString("timestart");
    Date time1 = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);

    String string2 = "22/11/18 " + c.getString("timeend");
    Date time2 = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(string2);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(time2);
    calendar2.add(Calendar.DATE, 1);

    String someRandomTime = "22/11/18 15:45";
    Date d = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(someRandomTime);
    Calendar calendar3 = Calendar.getInstance();
    calendar3.setTime(d);
    calendar3.add(Calendar.DATE, 1);

    Date now = calendar3.getTime();

    Date timestart = calendar1.getTime();
    Date timeend = calendar2.getTime();

    if ((now.after(timestart)) && (now.before(timeend))) {
        Log.d("timetest","add event with name:"+c.getString("name") + " time start: " + timestart+ " time end " + timeend + " time now " + now);
    }
}
catch (ParseException e) {
    e.printStackTrace();
}
MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Curtis Boylan
  • 827
  • 1
  • 7
  • 23
  • 1. Try to log the calendar objects to see time is parsed properly. 2. You can directly compare calendar objects also instead of converting to date. – viv Nov 22 '18 at 16:32
  • I did do some logs, which I attached @viv – Curtis Boylan Nov 22 '18 at 18:01
  • 2
    What exactly are you trying to do? – HB. Nov 22 '18 at 18:21
  • Your log is correct. You are getting the start time, the end time and the current time. You set the current time to 15:45. – HB. Nov 22 '18 at 18:26
  • Trying to make it return the one event that is on during that time selected so the if statement is meant to take the start time and end time and if your time is between that it will display the event information. @HB. – Curtis Boylan Nov 22 '18 at 18:29
  • You can get the time in milliseconds and check if current time is greater then the start time of the event. – HB. Nov 23 '18 at 08:36
  • 1
    You should not use the `Date` and `Calendar` classes anymore. Using them is troublesome. Use the new Java Date and Time API instead. If that's not available to you because of your Android version, you could use the ThreeTen Backport. – MC Emperor Nov 23 '18 at 10:29
  • @MCEmperor I have never had any issues using `Date` and `Calendar`. Can you please explain what the issue could be when using it like I did in my answer I provided? With the link you provided in your answer, do you mean to say that the `Date` and `Calendar` will return incorrect values? – HB. Nov 23 '18 at 11:54
  • @HB What about the fact that the `Calendar` class returns the incorrect day of week? The log says `Wed Nov 23 15:45:00 GMT+00:00 18`, but 23-11-2018 is actually a Friday. Seems "18" is not in 2018 at all. The format "yyyy" still accepts a two-digit year. – MC Emperor Nov 23 '18 at 12:36
  • 1
    This may not be the biggest problem with such code as OP currently has written, but if you're ever going to build a little bit bigger applications, it may save you time. [Here's a list of issues with these classes](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api). – MC Emperor Nov 23 '18 at 13:01
  • @MCEmperor I understand your point, but I don't agree with what you said `You should not use the Date and Calendar classes anymore` especially with what OP is trying to achieve. – HB. Nov 23 '18 at 14:23

2 Answers2

3

Like I mentioned in the comments section:

You can convert the time to millisecond, then check if current time is greater then the starting time of the event. If it is you will return the data.


Like this:

try {
    String string1 = "22/11/18 " + c.getString("timestart");
    Date time1 = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);

    //Convert event time to milliseconds
    int timestart = calendar1.get(Calendar.MILLISECOND);

    //Get current time in milliseconds
    Calendar calendarCurrent = Calendar.getInstance();
    calendarCurrent.setTime(new Date());
    int now = calendar.get(Calendar.MILLISECOND);


    //Check if the event time is greater then the current time
    if (timestart > now) {
        Log.d("timetest - ",+"Event "+c.getString("name")+" already started");
    }else{
        Log.d("timetest - ",+"Event "+c.getString("name")+" has not started yet");
    }
 } catch (ParseException e) {
     e.printStackTrace();
}

Important to note:

I would also suggest storing the date and time of the event in milliseconds in your database instead of hard coding it. In my answer I did it like you did for demonstration purposes.

If you store start time and end time to milliseconds, you will be able to determine the time remaining till the event starts, like this.

HB.
  • 4,116
  • 4
  • 29
  • 53
  • I tried this code and it does not work. When I console log it says that start is 0? – Curtis Boylan Nov 23 '18 at 15:45
  • Isn’t that just making already complicated tings more complicated? – Ole V.V. Nov 27 '18 at 05:27
  • @OleV.V. I don't think its complicated at all? – HB. Nov 27 '18 at 05:30
  • You may compare to the other answer accomplishing the same task in 9 lines instead of 20. Is also find those 9 lines much clearer to read. – Ole V.V. Nov 27 '18 at 05:34
  • 20 lines? It's 8 lines excluding the `if`/`else`. Anyway, I implemented mine this way and it working perfectly fine. I'm not finding it confusing and there is nothing wrong with how I implemented it, but thanks for the concern. – HB. Nov 27 '18 at 05:41
  • 1
    This answer is not working at all. The `Calendar.MILLISECOND` field returns the number of milliseconds *within the second*, and it always ranges from 0 to 999. – MC Emperor Nov 27 '18 at 07:47
2

You should use the new Java Date & Time API, made available in the java.time package. The old Date and Calendar classes are flawed and obsolete.

If you are only working with times, then you could use the LocalTime class to see if a certain time lies between two other times:

// First, parse the times
DateTimeFormatter f = DateTimeFormatter.ofPattern("HH:mm");
LocalTime startTime = LocalTime.parse(c.getString("timestart"), f);
LocalTime endTime = LocalTime.parse(c.getString("timeend"), f);

// Then check if now is between those two times
LocalTime now = LocalTime.now();
if (now.isAfter(startTime) && now.isBefore(endTime)) {
    ...
}

Or tell people when the event will start if it has not been started yet:

if (now.isBefore(startTime)) {
    Duration d = Duration.between(now, startTime);
    System.out.println("Event starting in about " + d);
}
else if (now.isBefore(endTime)) {
    System.out.println("Event is now going on");
}
else {
    System.out.println("Event has passed");
}

Note: I assume that the events do not repeat themselves every day at the specified time, so you might consider to store not only times, but also dates. You could store the timestamp as an integer, but formats like 2018-11-23T11:57:03+01:00 are also widely used. You can then easily parse them using the DateTimeFormatter class.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • @CurtisB See edit: simply with `LocalTime now = LocalTime.now()`. – MC Emperor Nov 23 '18 at 15:57
  • I recommend passing a time zone to `LocalTme.now` so you know what you get, even if you just pass `ZoneId.systemDefault()`. Since the times from JSON (like `15:30`) conform to ISO 8601 format, you don’t need to specify an explicit formatter for parsing them if you prefer not to. Nice answer to demonstrate how simple the job is using java.time. – Ole V.V. Nov 27 '18 at 05:31