如何更改 Java 中日历实例的日期?

How to change the date of a Calendar instance in Java?

我有一个 class DayOfWeek 从用户那里获取日期并打印该日期是星期几。

例如,用户将他的日期输入为:(格式为 MM DD YYYY

07 22 2016

输出应该是

FRIDAY

这是我的 class:

public class DayOfWeek{
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        Calendar cal = Calendar.getInstance();
        Date date = new Date(y, m, d);
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        System.out.println((sdf.format(dayOfWeek)).toUpperCase());
    }
}

然而,当我输入上述日期 (07 22 2016) 时,我没有得到所需的输出 (FRIDAY)。相反,输出是我系统上的当前星期几。我完全不知道问题出在哪里。

您目前正在将 int 传递给 SimpleDateFormat...您应该传递 Date 值。你根本不需要 Calendar:

// BAD CODE: DON'T USE - KEEP READING
import java.text.*;
import java.util.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        // Note the changes here
        Date date = new Date(y - 1900, m - 1, d);
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        System.out.println(sdf.format(date).toUpperCase());
    }
}

我将警告放在那里是因为您使用的是已弃用的 Date 构造函数 - 弃用它有充分的理由。基本上,java.util.Date 是一个 糟糕的 API 并且你应该尽可能避免使用它。您对 new Date(y, m, d) 的原始调用已中断,因为 java.util.Date(int, int, int) 的第一个参数代表以 1900 为基数的年份(因此值 117 表示 2017 年),第二个参数代表以 0 为基数的月份(所以值 6 表示七月)。然后是隐式时区转换,您真的不想要它。

使用 java.time,在这种情况下 LocalDate class:

import java.time.*;
import java.time.format.*;
import java.util.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        Scanner sc = new Scanner(System.in);
        String month = sc.next();
        String day = sc.next();
        String year = sc.next();
        int m = Integer.parseInt(month);
        int d = Integer.parseInt(day);
        int y = Integer.parseInt(year);
        LocalDate date = LocalDate.of(y, m, d);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
        System.out.println(formatter.format(date).toUpperCase());
    }
}

最后,您解析用户输入的方法也不理想 - 我建议也使用 DateTimeFormatter

import java.time.*;
import java.time.format.*;

public class DayOfWeek {
    public static void main(String[] args){
        System.out.println("Enter the date (Format: MM DD YYYY) :");
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM dd yyyy");
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        LocalDate date = LocalDate.parse(line, parser);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
        System.out.println(formatter.format(date).toUpperCase());
    }
}
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);

如果您需要输出为星期二而不是 3(星期几从 (1) 开始索引,而不是通过日历,只需重新格式化 string: new SimpleDateFormat("EE").format(date)(EE 意思是 "day of week, short version").

备注 正如 Jon 所指出的,尝试使用最新的 Date Time Formatter Api 为此目的 Date Api is depricated .

如果您的输入是字符串而不是日期,您应该使用 SimpleDateFormat 来解析它

: new SimpleDateFormat("dd/M/yyyy").parse(dateString)

是正确的,并且已经解释了旧 API 的所有问题以及如何使用新的。我只想添加另一种方法 java.time 类.

如果你只想得到一个 String 与星期几,你可以跳过 LocalDate 的创建并直接得到一个 java.time.DayOfWeek.

第一部分相同(从 Scanner 获取输入并创建一个 DateTimeFormatter 来解析它)。

然后我使用 from 方法从解析的输入创建一个 java.time.DayOfWeek。所以我调用 getDisplayName,使用 java.time.format.TextStyle(相当于 中的 EEEE 格式)和 java.util.Locale 来明确表示我想要周的英文名称。

// read line from input
Scanner sc = new Scanner(System.in);
// get "07 22 2016" from the scanner
String line = sc.nextLine();
// formatter to parse the input
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM dd yyyy");
// get the day of the week
DayOfWeek dow = DayOfWeek.from(parser.parse(line));
// get day of week's name
String output = dow.getDisplayName(TextStyle.FULL, Locale.ENGLISH).toUpperCase();

output 变量的值将是 FRIDAY - 注意我也调用了 toUpperCase(),因为 getDisplayName 的结果是 Friday.

Locale也很重要。如果您不指定区域设置,它将使用系统的默认设置,并且不保证始终是英语。它也可以在不通知的情况下更改,即使在运行时也是如此,因此最好在您的代码中明确说明。


备注:

  • 如果您想更改语言,上面的代码也可以使用(只需使用不同的 Locale)。但是如果你总是想要一个英文大写的名字,你可以选择调用 dow.toString(),这也会 return FRIDAY

  • 这段代码只关注星期几。如果您需要将日期用于获取 FRIDAY 以外的其他用途(例如检查日期、月份等),那么您将需要 LocalDate 并且 是首选(并且 LocalDate 有方法 getDayOfWeek(),其中 return 对应 DayOfWeek,以备不时之需。

  • java.time 仅在 Java >= 8 中可用。不过,如果您使用的是 Java <= 7,则可以使用 ThreeTen Backport。唯一的区别是包名称(org.threeten.bp 而不是 java.time),但是 类 和方法 names 是相同的。