关于Java:使用日历对象显示日期

displaying date using calendar object

我希望使用日历对象显示日期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public abstract class Employee implements EmployeeInfo {

protected String firstName;
protected String lastName;
protected String idNumber;
Calendar birthday = Calendar.getInstance();
protected char gender;

public Employee()
{
    firstName ="";
    lastName ="";
    idNumber ="";
    gender = ' ';
    birthday.set(Calendar.MONTH, 0);
    birthday.set(Calendar.DAY_OF_MONTH, 00);
    birthday.set(Calendar.YEAR, 0000);
}

public Employee(String first, String last, String id, char gen, int month, int day, int year)
{
    firstName = first;
    lastName = last;
    idNumber = id;
    gender = gen;
    birthday.set(Calendar.MONTH, month);
    birthday.set(Calendar.DAY_OF_MONTH, day);
    birthday.set(Calendar.YEAR, year);
}

public Calendar getBirthday() {

    return birthday;
}

public void setBirthday(int month, int day, int year, Calendar birthday) throws ParseException {
    birthday = Calendar.getInstance();
    birthday.set(Calendar.MONTH, month);
    birthday.set(Calendar.DAY_OF_MONTH, day);
    birthday.set(Calendar.YEAR, year);
    SimpleDateFormat formatted = new SimpleDateFormat("MM/dd/yyyy");
    String date = month +"/" + day +"/" + year;
    Date birth = formatted.parse(date);
    birthday.setTime(birth);
    this.birthday = birthday;
}

public String toSring()
{
    return"ID Employee Number:" + idNumber +"
"
+"Employee name:" + firstName +""
            + lastName +"
"
+"Birth date:" + birthday +"
"
;
}

public abstract double getMonthlyEarning();

public class Staff extends Employee {
protected double hourlyRate;

public Staff()
{
    super();
    hourlyRate = 0.0;
}

public Staff(String first, String last, String ID, char gen1, int month, int day, int year, double rate)
{
    super(first, last, ID, gen1, month, day, year);
    hourlyRate = rate;
}

}

…还有…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {

public static void main(String[] args) {

    Employee[] employees = new Employee[2];
    employees[0] = new Staff("Minh","Vu","123", 'M', 3,06,1997, 50.00);
    employees[1] = new Staff("Mike","Nguyen","456", 'M', 5,18,1977, 65.00);

    for(Employee member : employees)
    {
        System.out.println(member);
        System.out.println("------------------------------------------");
    }
}
}

我面临的问题是,为什么以下输出中的出生日期给了我一条未知的、荒谬的长线:

身份证号:123

员工姓名:Minh Vu

出生日期:Java.UTI.GRGGORICONALDENAR[时间=?[1]"AuthFieldStase= true,Pale= Sun.Unj.LoopyGales,偏移量=28800000,dSTAsLe=真,过渡=185,Lastrue= Java.UTI.SimuleMeTeal[ID]=美国/LoSoChanes,偏移=-28800000,DSTealSt==3600000,UsDayAyLoe= true,StistyValid=0,StistalMeod=3,StistalQue= 2,StestDay= 8,StasDayFoWeek=1,starttime=7200000,starttimemode=0,endmode=3,endmonth=10,endday=1,enddayOfWew=1,endtime=7200000,endtimemode=0]],firstdayOfWew=1,mindayInFirstWew=1,era=1,1997年年年月月=3,_年周=6,_月周_=2,_月日_=6,_月日_=6,_年日_=37,_周日_=2,_周日_周日_月日_月日_=1,am_pm=pm=1,am_pm=pm=1,am_pm=1,am_pm=1 1,小时=2,小时日=0,分钟=0,秒=0,毫秒=0,区域 Offset=-28800000,dst_offset=0]

充分的时间

月薪:8000.0美元

身份证号:456

员工姓名:Mike Nguyen

出生日期:Java.UTI.GRGGORICONALDENAR[时间=?[1]"AuthFieldStase= true,Pale= Sun.Unj.LoopyGales,偏移量=28800000,dSTAsLe=真,过渡=185,Lastrue= Java.UTI.SimuleMeTeal[ID]=美国/LoSoChanes,偏移=-28800000,DSTealSt==3600000,UsDayAyLoe= true,StistyValid=0,StistalMeod=3,StistalQue= 2,StestDay= 8,StasDayFoWeek=1,starttime=7200000,starttimemode=0,endmode=3,endmonth=10,endday=1,enddayOfWew=1,endtime=7200000,endtimemode=0]],第一天ofWew=1,最小天sin第一周=1,era=1,年=1977,月=5,年u年_年_的第6周,月u月_的第2周,月_的第18天,年u的第37天,周_的第2天,周u周的第u周_的第u天,月\_的第_周,小时=2,小时/天=0,分钟=0,秒=0,毫秒=0,区域_偏移量=-28800000,dst_偏移量=0]

充分的时间

月薪:10400.0美元

根据我的分析,我认为我必须使用SimpleDateFormat类创建一个对象,并将"mm/dd/yyyy"放入参数中。但是,我必须通过创建一个日期对象来解析simpledateformat对象。我想使用日历类创建我的日期对象。

在调试时,我注意到生日的显示是错误的;它打印了我生日对象中的所有内容。我不知道该怎么办。我们将非常感谢您的帮助。:)


首先,你应该使用java.time,而不是Calendar

第二件事是你不必两次创建你的约会对象(你是在你的设定器中创建的)。

最后但并非最不重要的是,您必须在打印日期之前格式化日期(使用toString()方法)

这就是您的setter应该是什么样子:

1
2
3
4
5
public void setBirthday(int month, int day, int year) {
    this.birthday.set(Calendar.MONTH, month);
    this.birthday.set(Calendar.DAY_OF_MONTH, day);
    this.birthday.set(Calendar.YEAR, year);
}

或者更好:

1
2
3
public void setBirthday(Calendar birthday) {
    this.birthday = birthday;
}

你的toString()方法应该是这样的:

1
2
3
4
5
6
7
public String toString(){
    return"ID Employee Number:" + idNumber +"
"
+"Employee name:" + firstName +""
            + lastName +"
"
+"Birth date:" + formatter.format(birthday) +"
"
;
}

因此,您还需要将此添加到代码中:

1
private final static SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");


DR

1
2
3
LocalDate birthdate;

this.birthdate = LocalDate.of( 1955 , 3 , 17 ); // March 17, 1955.

细节

qwerty1423的答案是正确的,应该被接受。您将看到toString方法的结果。如果您坚持使用Calendar,请学习以所需格式生成字符串。

Java.时间

但您不应该使用Calendar。它是一个麻烦的旧日期时间类,现在是遗留类,被java.time类所取代。遗留类是一个可怕的混乱;避免它们。另外,java.time类使用不可变的对象,因此是线程安全的。

LocalDate类表示没有时间和时区的仅日期值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public abstract class Employee implements EmployeeInfo {

    protected String firstName;
    protected String lastName;
    protected String idNumber;
    LocalDate birthday;

    // Constructor
    public Employee() {
        this.firstName ="";
        this.lastName ="";
        this.idNumber ="";
        this.birthday = LocalDate.MIN ;  // Or some other arbitrary default value.
    }

    // Constructor
    public Employee( String first, String last, String id, int month, int day, int year )
    {
        this.firstName = first;
        this.lastName = last;
        this.idNumber = id;
        this.birthdate = LocalDate.of( year , month , day ) ;
    }

调用LocalDate::toString生成标准ISO 8601格式的字符串:YYYY-MM-DD。对于其他格式,搜索java.time.format.DateTimeFormatter类的堆栈溢出。

要本地化,请指定:

  • FormatStyle决定字符串的长度或缩写。
  • Locale确定(a)翻译日名、月名等的人类语言;(b)决定缩写、大写、标点、分隔符等问题的文化规范。

例子:

1
2
3
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = this.birthdate.format( f );

请在ideone.com上查看此代码。

birthdate.toString(): 1955-03-17

output: jeudi 17 mars 1955

提示:

  • 在订购日期-时间部分时,请始终使用降序意义:年、月、日、小时、分钟、秒。这是合乎逻辑的,易于理解,并且遵循日期时间值的ISO 8601标准的样式。因此,不要将int month, int day, int year作为论据传递,而是传递int year , int month , int dayOfMonth

  • 更好的是,只传递一个LocalDate对象,而不只是整数。这样做可以使代码更具自记录性,确保有效值,并提供类型安全性。

关于JavaTimes

JavaTimeFr框架是在Java 8和之后构建的。这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendar、&SimpleDateFormat

现在处于维护模式的joda time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程。以及搜索堆栈溢出以获得许多示例和解释。规格为JSR 310。

使用符合JDBC4.2或更高版本的JDBC驱动程序,可以直接与数据库交换java.time对象。不需要字符串,也不需要Java.SQL.*类。

在哪里获取java.time类?

  • Java SE 8、Java SE 9及以后
    • 内置的。
    • 标准JAVA API的一部分与捆绑实现。
    • Java 9添加了一些小的特性和修复。
  • Java SE 6和Java SE 7
    • 大部分JavaTimeActudio都被移植到TealEnter后端的Java 6和7中。
  • 安卓
    • java.time类的Android包实现的更高版本。
    • 对于早期的android,threetenabp项目适应threeten backport(如上所述)。看看如何使用三连珠……

threeten额外项目使用额外的类扩展java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。


因为您正在打印日历对象,所以变量birthday是。

您可能希望基于日历实现自己的类,但是使用一个ToString方法来实现您所期望的。