SimpleDateFormat 如何设置只包含工作日名称、小时和分钟的格式?

问题描述

1.现在我试图创建一个只包含工作日名称、小时和分钟的 SimpleDateFormat。 我刚刚定义了一个这样的模式: DateFormat sdf = new SimpleDateFormat("EEE:hh:mm");然而,这种模式似乎根本不起作用;

2.这是我定义日期格式的代码,下面的代码只能包含小时和分钟,当我尝试输入“Tue:21:30”时,“Tue”不会被存储。如何定义像““Tue 21:30”这样的时间格式?

description & company

解决方法

java.util.Date 类表示日期与 UTC 时间的组合。

您只有星期几,没有日期。而且您没有偏移量或时区指标。你只有一个需要的部分,一个时间。所以解析"Tue:21:30"这样的字符串是没有意义的。

另一件事:您正在使用糟糕的日期时间类。这些类在多年前被 JSR 310 中定义的现代 java.time 类取代。

要将星期几与一天中的某个时间配对,请编写一个类。在 Java 16 中,我将使用新的 records 特性来简要地编写这样一个类。编译器隐式创建构造函数、getter、equals & hashCodetoString

record DayOfWeekTime ( DayOfWeek dayOfWeek,LocalTime localTime ) {}

用法。

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

如果您想以这种方式限制数据,或者使用一对 int 值表示小时和分钟,而不是 LocalTime。我也会添加一个显式构造函数,以验证这些 int 输入的允许值范围。

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

添加方法以解析和生成所需格式的字符串。

如果需要排序,您可能需要添加一个 compareTo 方法来实现 Comparable 接口。

,

Date 代表一个瞬间。 “周二晚上 9 点 30 分”不是一个瞬间 - 哪个周二?晚上 9:30 在哪个时区?如果您使用 DateTimeFormatter,您可以假设这些东西的默认值,但从评论看来,您似乎不想假设任何东西。您只想存储解析的内容。

您可以编写自己的类,表示一周中的某天 + 小时 + 分钟。如果您实现 TemporalAccessor,您将能够使用 DateTimeFormatter 对其进行解析和格式化。下面是一个例子:

final class DayOfWeekLocalTime implements TemporalAccessor {

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

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

  public static DayOfWeekLocalTime of(DayOfWeek dow,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
}

解析:

DayOfWeekLocalTime.parse("Tue:21:30",DateTimeFormatter.ofPattern("EEE:HH:mm"));
,

Do not use java.util.date,因为它有几个消极方面。

使用更新的(自 Java 8 起)JSR 310: Date Time API

你可以这样做:

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

或者,使用任何其他日期对象代替 LocalDateTime API 中的 .now()

可以在herehereherehere 中找到有关为什么不使用java.util.date 的其他一些参考资料。