-1

I have "Monday, 9:30" as String, and I want a Date of next Monday with time 9:30 as java.util.Date. How do I do that?

blubb
  • 9,510
  • 3
  • 40
  • 82

2 Answers2

2

You can create a SimpleDateFormat matching your string. Then you'll use the .parse() method from that class to convert your String to a Date. See this question for a more detailed answer.

Alternately, you can create a Calendar object, and parse your string to set its appropriate fields and then use .getTime() to extract the Date.

EDIT Inspired by Gilbert Le Blanc's answer, I produced his test case much more simply. The steps I used were:

  1. Use SimpleDateFormat to parse the given string including the date, producing a date in 1970.
  2. Adjust for any DST offsets
  3. Calculate how many weeks in the past the parsed date was.
  4. Add this number of weeks to the past date in order to make it the next future date.

Test output of my program matches Gilbert's (in my time zone):

Monday, 9:30 --> Mon May 23 09:30:00 PDT 2016
Friday, 16:45 --> Fri May 20 16:45:00 PDT 2016
Wednesday, 22:15 --> Wed May 18 22:15:00 PDT 2016

You can tweak the approach based on what you really mean by "next". Here's my complete code:

package foo.bar;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DayTime {

    public static final long MILLISECONDS_PER_WEEK = 7L * 24 * 60 * 60 * 1000;

    public static void main(String[] args) {
        getDate("Monday, 9:30");
        getDate("Friday, 16:45");
        getDate("Wednesday, 22:15");
    }

    private static void getDate(String input) {
        // Parse given date. Convert this to milliseconds since epoch. This will
        // result in a date during the first week of 1970.
        SimpleDateFormat sdf = new SimpleDateFormat("E, H:mm");
        Date date = sdf.parse(input, new ParsePosition(0));

        // Convert to millis and adjust for offset between today's Daylight
        // Saving Time (default for the sdf) and the 1970 date
        Calendar c = Calendar.getInstance();
        int todayDSTOffset = c.get(Calendar.DST_OFFSET);
        c.setTime(date);
        int epochDSTOffset = c.get(Calendar.DST_OFFSET);

        long parsedMillis = date.getTime() + (epochDSTOffset - todayDSTOffset);

        // Calculate how many weeks ago that was
        long millisInThePast = System.currentTimeMillis() - parsedMillis;
        long weeksInThePast = millisInThePast / MILLISECONDS_PER_WEEK;
        // Add that number of weeks plus 1
        Date output = new Date(parsedMillis + (weeksInThePast + 1) * MILLISECONDS_PER_WEEK);

        System.out.println(input + " --> " + output);
    }
}
Community
  • 1
  • 1
Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
2

I wrote a conversion program. Here are the test results.

Monday, 9:30 --> Mon May 23 09:30:00 MDT 2016
Friday, 16:45 --> Fri May 20 16:45:00 MDT 2016
Wednesday, 22:15 --> Wed May 18 22:15:00 MDT 2016

I assumed that the input time is 24 hour time. I'm in the mountain time zone (MDT). The date results will be in whichever time zone you run this code.

I also assumed that if today's weekday is the same as the input weekday, I output today's date. Feel free to add code to check the current time to see if the appointment is today or next week. I considered that beyond the scope of the requirement.

Here's how I created the Date output.

  1. I split the input by ", ".

  2. I created a Calendar object with the current date and time.

  3. I converted the weekday text to a weekday integer.

  4. I added the number of days necessary to get to the next weekday integer.

  5. I parsed the time part using the SimpleDateFormat, and copied the time to the Calendar object.

Here's the code. This was not simple.

package com.ggl.testing;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DayTime {

    public static void main(String[] args) {
        getDate("Monday, 9:30");
        getDate("Friday, 16:45");
        getDate("Wednesday, 22:15");
    }

    private static void getDate(String input) {
        DayTime dayTime = new DayTime();
        Date output = dayTime.createDate(input);
        System.out.println(input + " --> " + output);
    }

    public Date createDate(String input) {
        String[] parts = input.split(", ");
        Calendar now = Calendar.getInstance();
        setDate(parts, now);
        setTime(parts[1], now);
        return now.getTime();
    }

    private void setDate(String[] parts, Calendar now) {
        int weekday;
        switch (parts[0]) {
        case "Sunday":
            weekday = Calendar.SUNDAY;
            break;
        case "Monday":
            weekday = Calendar.MONDAY;
            break;
        case "Tuesday":
            weekday = Calendar.TUESDAY;
            break;
        case "Wednesday":
            weekday = Calendar.WEDNESDAY;
            break;
        case "Thursday":
            weekday = Calendar.THURSDAY;
            break;
        case "Friday":
            weekday = Calendar.FRIDAY;
            break;
        default:
            weekday = Calendar.SATURDAY;
            break;
        }

        int currentWeekday = now.get(Calendar.DAY_OF_WEEK);

        if (weekday == currentWeekday) {
            return;
        }

        int difference = (weekday - currentWeekday + 7) % 7;
        now.add(Calendar.DAY_OF_MONTH, difference);
    }

    @SuppressWarnings("deprecation")
    private void setTime(String part, Calendar now) {
        Date date = getTime(part);
        if (date != null) {
            now.set(Calendar.HOUR_OF_DAY, date.getHours());
            now.set(Calendar.MINUTE, date.getMinutes());
            now.set(Calendar.SECOND, date.getSeconds());
        }
    }

    private Date getTime(String part) {
        SimpleDateFormat sdf = new SimpleDateFormat("H:mm");
        try {
            return sdf.parse(part);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • A little overkill since `SimpleDateFormat` uses Calendar internally, with defaults (which happen to be in the year 1970). Just parse to the date in 1970 and advance by enough weeks to make it "next week" and you're done. – Daniel Widdis May 18 '16 at 23:18