【问题标题】:Convert string to day of week (not exact date)将字符串转换为星期几(不是确切的日期)
【发布时间】:2013-08-16 10:35:42
【问题描述】:

我收到String,这是一周中的某一天,例如周一。现在我想得到那天的常量整数表示,在java.util.Calendar中使用。

我真的必须自己做if(day.equalsIgnoreCase("Monday")){...}else if(...){...}吗?有什么巧妙的方法吗?如果我挖掘 SimpleDateFormat 并将其与 Calendar 混合,我产生的行数几乎与键入丑陋的 if-else-to-infitity 语句一样多。

【问题讨论】:

  • 这在尖叫enum。
  • 提示:与其在星期几中传递这些字符串,不如传递在该枚举中预定义的 java.time.DayOfWeek 对象。

标签: java date calendar simpledateformat dayofweek


【解决方案1】:

你可以这样做:

    private static String getDayOfWeek(final Calendar calendar){
    assert calendar != null;
    final String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    return days[calendar.get(Calendar.DAY_OF_WEEK)-1];
}

虽然声明星期几可能是个好主意,这样您就不必在每次调用方法时都声明它们。

反过来说,是这样的:

    private static int getDayOfWeek(final String day){
    assert day != null;
    final String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    for(int i = 0; i < days.length; i++)
        if(days[i].equalsIgnoreCase(day))
            return i+1;
    return -1;
}

【讨论】:

  • 我想我需要它的另一种方式:-) String to int
【解决方案2】:

为什么不初始化一次你想要的?

private static final Map<String, Integer> weekDays;
static
{
    weekDays= new HashMap<String, Integer>();
    weekDays.put("Monday", Calendar.MONDAY);
    weekDays.put("Tuesday", Calendar.TUESDAY);
    // etc
}

【讨论】:

    【解决方案3】:

    您可以使用SimpleDateFormat,它也可以将日期解析为特定的Locale

    public class Main {
    
        private static int parseDayOfWeek(String day, Locale locale)
                throws ParseException {
            SimpleDateFormat dayFormat = new SimpleDateFormat("E", locale);
            Date date = dayFormat.parse(day);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            return dayOfWeek;
        }
    
        public static void main(String[] args) throws ParseException {
            int dayOfWeek = parseDayOfWeek("Sunday", Locale.US);
            System.out.println(dayOfWeek);
    
            dayOfWeek = parseDayOfWeek("Tue", Locale.US);
            System.out.println(dayOfWeek);
    
            dayOfWeek = parseDayOfWeek("Sonntag", Locale.GERMANY);
            System.out.println(dayOfWeek);
        }
    
    }
    

    【讨论】:

    【解决方案4】:

    为什么不声明一个地图:

    Map<String, Integer> daysMap = new HashMap<String, Integer>();
    
    daysMap.add("monday", 0);
    daysMap.add("tuesday", 1);
    //etc.
    

    那么,当你需要搜索时:

    int dayId = daysMap.get(day.toLowerCase());
    

    这应该可以满足您的需要。您甚至可以从某个文件/数据库等加载数据。

    【讨论】:

    • 我不相信这会编译。如果你修复它,它实际上将与 Tala 的答案相同。
    【解决方案5】:

    考虑使用类似的辅助方法

    public static int getDayOfWeekAsInt(String day) {
        if (day == null) {
            return -1;
        }
        switch (day.toLowerCase()) {
            case "monday":
                return Calendar.MONDAY;
            case "tuesday":
                return Calendar.TUESDAY;
            case "wednesday":
                return Calendar.WEDNESDAY;
            case "thursday":
                return Calendar.THURSDAY;
            case "friday":
                return Calendar.FRIDAY;
            case "saturday":
                return Calendar.SATURDAY;
            case "sunday":
                return Calendar.SUNDAY;
            default: 
                return -1;
        }
    }
    

    请注意,仅 Java 7 及更高版本支持将字符串与 switch-case 一起使用。

    【讨论】:

      【解决方案6】:

      我通常使用枚举,但在这种情况下,您的输入必须是正确的。

      public enum DayOfWeek {
          Sunday(1),Monday(2),Tuesday(3),Wednesday(4),Thursday(5),Friday(6),Saturday(7);
      
          private final int value;
      
          DayOfWeek(int value) {
      
              this.value = value;
          }
      
          public int getValue() {
      
              return value;
          }
      
          @Override
          public String toString() {
      
              return value + "";
          }
      }
      

      现在,您可以按如下方式获取星期几:

      String sunday = "Sunday";
      System.out.println(DayOfWeek.valueOf(sunday));
      

      这将为您提供以下输出:

      1
      

      【讨论】:

      • 这样的枚举现在已内置到 Java 8 及更高版本中,java.util.DayOfWeek。根据ISO 8601 标准,周一至周日运行 1-7。
      【解决方案7】:

      java.time

      对于任何对 Java 8 解决方案感兴趣的人,都可以通过类似的方式来实现:

      import static java.util.Locale.forLanguageTag;
      
      import java.time.format.DateTimeFormatter;
      import java.time.temporal.TemporalAccessor;
      
      import java.time.DayOfWeek;
      import org.junit.Test;
      
      public class sarasa {
      
          @Test
          public void test() {
              DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE", forLanguageTag("es"));
              TemporalAccessor accessor = formatter.parse("martes"); // Spanish for Tuesday.
              System.out.println(DayOfWeek.from(accessor));
          }
      }
      

      输出是:

      TUESDAY
      

      【讨论】:

        【解决方案8】:

        有关非英语星期几的名称,请参阅Answer by tete。

        tl;博士

         DayOfWeek.valueOf( "Monday".toUppercase() )  // `DayOfWeek` object. Works only for English language.
                  .getValue()                         // 1
        

        java.time

        如果您的星期几名称恰好是英文全长名称(Monday、Tuesday 等),那恰好与 DayOfWeek 枚举中定义的枚举对象的名称一致。

        将您的输入全部转换为大写,并解析以获取该星期几的常量对象。

        String input = "Monday" ;
        String inputUppercase = input.toUppercase() ;  // MONDAY
        DayOfWeek dow = DayOfWeek.valueOf( inputUppercase );  // Object, neither a string nor a number.
        

        现在我们有了一个全功能对象而不是一个字符串,请询问星期几的整数,其中星期一是 1,星期日是 7(标准 ISO 8601 定义)。

        int dayOfWeekNumber = dow.getValue() ;
        

        使用DayOfWeek 对象而不是字符串

        我敦促您尽量减少使用星期几的名称或数字。相反,请尽可能使用DayOfWeek 对象。

        顺便说一句,您可以自动本地化星期几的名称。

        String output = DayOfWeek.MONDAY.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );
        

        这种本地化只能通过DayOfWeek 类进行。要使用英语以外的其他语言,请参阅Answer by tete。


        关于java.time

        java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。

        Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

        要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

        从哪里获得 java.time 类?

        ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。

        【讨论】:

          【解决方案9】:

          如果您使用的是 java 8:

          import java.time.DayOfWeek;
          

          然后简单地使用:DayOfWeek.[DAY].getValue()

          System.out.println(DayOfWeek.MONDAY.getValue());
          System.out.println(DayOfWeek.TUESDAY);
          System.out.println(DayOfWeek.FRIDAY.getValue());
          

          对于旧版本,请检查此答案: Convert string to day of week (not exact date)

          【讨论】:

            【解决方案10】:

            使用DateFormatSymbols 类中内置的名称,如下所示。这将返回 0 代表星期日,6 代表星期六,以及 -2 代表任何无效的一天。添加您自己认为合适的错误处理。

            private static final List dayNames = Arrays.asList(new DateFormatSymbols().getWeekdays());
            
            public int dayNameToInteger(String dayName) {
                return dayNames.indexOf(dayName) - 1;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-01-29
              • 2014-01-11
              • 1970-01-01
              • 2012-12-21
              • 2020-12-14
              • 1970-01-01
              • 2011-11-28
              相关资源
              最近更新 更多