【问题标题】:SimpleDateFormat how to set a format only contain weekday name, hour and minutes?SimpleDateFormat 如何设置格式只包含工作日名称、小时和分钟?
【发布时间】:2021-07-10 04:21:26
【问题描述】:

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

2.这是我定义日期格式的代码,下面的代码只能包含小时和分钟,当我尝试输入“Tue:21:30”时,不会存储“Tue”。如何定义像“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())

【问题讨论】:

  • 你不能改用较新的DateTimeFormatter 吗?另外,“Tue:21:30”是什么意思?是下周二还是上周二还是本周的周二?
  • 我的意思是日期应该只包含工作日名称、小时和分钟。格式"Tue:21:30",请忽略。格式无关紧要,只要时间包含 n 个工作日名称、小时和分钟即可。
  • hh 是“12 小时小时值”,即 01-12。对于 21,您需要 HH。 (但我强烈建议改用 java.time。)

标签: java date simpledateformat


【解决方案1】:

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 接口。

【讨论】:

  • 您能告诉我如何创建只包含工作日名称、小时和分钟的数据吗?
  • @JayParkkk 你不能。
【解决方案2】:

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

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

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
}

解析它:

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

【讨论】:

    【解决方案3】:

    Do not usejava.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()

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

    【讨论】:

      猜你喜欢
      • 2013-07-03
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多