0

1.Now I was trying to create a SimpleDateFormat that only contain weekday name, hour and minutes. I just defined a schema like this: DateFormat sdf = new SimpleDateFormat("EEE:hh:mm"); However, it seems like this pattern did not work at all;

2.Here is my code to define a date format, the code below can only contain hours and minutes, When I try to input "Tue:21:30", "Tue" will not be stored. How can defined a time format just like ""Tue 21:30""?

             DateFormat sdf = new SimpleDateFormat("EEE:hh:mm");
          
             Date date = sdf.parse("Tue:21:30");
             Calendar cal = Calendar.getInstance();
             cal.setTime(date);
             int hours = 8;
             int minutes =3000;
             cal.add(Calendar.HOUR_OF_DAY, hours);
             cal.add(Calendar.MINUTE, minutes);
             date = cal.getTime();
             System.out.println(date);
             System.out.println(date.getDay());
             System.out.println(date.getHours())
Jay Park
  • 308
  • 1
  • 6
  • 14
  • 3
    Can't you use the newer `DateTimeFormatter` instead? Also, what do you mean by "Tue:21:30"? Is that the coming Tuesday or the previous Tuesday or the Tuesday that is in this week? – Sweeper Apr 15 '21 at 06:25
  • I mean the date should only contain weekday name,hour, and minutes. The format"Tue:21:30",please just ignore it. The format does not matter, as long as the time contain n weekday name,hour, and minutes. – Jay Park Apr 15 '21 at 06:28
  • 3
    `hh` is "12 hour hour-of-day value", i.e. 01-12. For 21, you'd need `HH`. (But I would very strongly recommend using java.time instead.) – Jon Skeet Apr 15 '21 at 06:41

3 Answers3

2

The java.util.Date class represents the combination of a date with with a time-of-day as seen in UTC.

You have only a day-of-week, not a date. And you have no indicator of offset or time zone. You have only one of the pieces needed, a time-of-day. So it makes no sense to parse a string such as "Tue:21:30".

Another thing: You are using terrible date-time classes. These classes were supplanted years ago by the modern java.time classes defined in JSR 310.

To pair a day-of-week with a time-of-day, write a class. In Java 16, I would use the new records feature to briefly write such a class. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.

record DayOfWeekTime ( DayOfWeek dayOfWeek , LocalTime localTime ) {}

Usage.

DayOfWeekTime dowTime = new DayOfWeekTime( DayOfWeek.TUESDAY , LocalTime.of( 21 , 30 ) ) ;

Or use a pair of int values for hour and minute instead of LocalTime if you want to restrict the data that way. I would add an explicit constructor too, to validate the range of allowed values on those int inputs.

record DayOfWeekTime ( DayOfWeek dayOfWeek , int hour , int minute ) {}

Add methods to parse and generate strings in your desired format.

You might want to add a compareTo method to implement the Comparable interface, if you need sorting.

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

Date represents an instant in time. "9:30 pm on Tuesday" is not an instant in time - which Tuesday do you mean? 9:30 pm in what timezone? You can assume default values for these things if you use DateTimeFormatter, but from the comments it seems like you don't want to assume anything. You just want to store what is parsed.

You can write your own class that represents a day-of-week + hour + minutes only. If you implement TemporalAccessor, you will be able to parse and format it with DateTimeFormatter. Here is an example:

final class DayOfWeekLocalTime implements TemporalAccessor {

  private final DayOfWeek dow;
  private final int hour;
  private final int minute;

  private DayOfWeekLocalTime(DayOfWeek dow, int hour, int minute) {
    this.dow = dow;
    this.hour = hour;
    this.minute = minute;
  }

  public static DayOfWeekLocalTime of(DayOfWeek dow, int hour, int minute) {
    return new DayOfWeekLocalTime(dow, hour, minute);
  }

  public static DayOfWeekLocalTime parse(String s, DateTimeFormatter formatter) {
    TemporalAccessor ta = formatter.parse(s);
    return new DayOfWeekLocalTime(
        DayOfWeek.of(ta.get(ChronoField.DAY_OF_WEEK)),
        ta.get(ChronoField.HOUR_OF_DAY),
        ta.get(ChronoField.MINUTE_OF_HOUR)
    );
  }

  @Override
  public String toString() {
    // a default format
    return DateTimeFormatter.ofPattern("EEE:HH:mm").format(this);
  }

  @Override
  public boolean isSupported(TemporalField field) {
    return field == ChronoField.DAY_OF_WEEK ||
        field.getBaseUnit() == ChronoUnit.HOURS ||
        field.getBaseUnit() == ChronoUnit.MINUTES ||
        field == ChronoField.AMPM_OF_DAY;
  }

  @Override
  public long getLong(TemporalField field) {
    if (!isSupported(field)) {
      throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }
    if (field == ChronoField.DAY_OF_WEEK) {
      return dow.getValue();
    }
    return field.getFrom(LocalTime.of(hour, minute));
  }

  // equals and hashcode omitted for brevity
}

To parse it:

DayOfWeekLocalTime.parse("Tue:21:30", DateTimeFormatter.ofPattern("EEE:HH:mm"));
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

Do not use java.util.date, as it has several negative aspects.

Use newer (since Java 8) JSR 310: Date Time API.

You can do:

DateTimeFormatter format1 = DateTimeFormatter.ofPattern("EEE HH:mm");
DateTimeFormatter format2 = DateTimeFormatter.ofPattern("EEEE HH:mm"); //gives you full name of the day

LocalDateTime ldt = LocalDateTime.now();

//if it's Thursday, 10:30
System.out.println(ldt.format(format1)); //prints Thu 10:30
System.out.println(ldt.format(format2)); //prints Thursday 10:30

Alternatively, use any other date object instead of .now() from the LocalDateTime API.

Some other references on why not to use java.util.date can be found here, here, here, and here.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66