使用日历对象

时间:2017-02-06 23:11:10

标签: java date calendar

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

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 + "\n" + "Employee name: " + firstName + " "
            + lastName + "\n" + "Birth date: " + birthday + "\n";
}

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;
}

}

...和...

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("------------------------------------------");
    }
}
}

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

ID员工人数:123

员工姓名:Minh Vu

出生日期:java.util.GregorianCalendar [time =?,areFieldsSet = false,areAllFieldsSet = true,lenient = true,zone = sun.util.calendar.ZoneInfo [id =" America / Los_Angeles" ,偏移= -28800000,dstSavings = 3600000,useDaylight =真,过渡= 185,lastRule = java.util.SimpleTimeZone中[ID =美洲/洛杉矶,偏移= -28800000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 3,startMonth = 2,朝九特派= 8,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 0,endMode = 3,endMonth = 10,endday指定= 1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 0]],Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 1997,MONTH = 3,WEEK_OF_YEAR = 6,WEEK_OF_MONTH = 2,DAY_OF_MONTH = 6,DAY_OF_YEAR = 37,DAY_OF_WEEK = 2,DAY_OF_WEEK_IN_MONTH = 1,AM_PM = 1,HOUR = 2 ,HOUR_OF_DAY = 0,MINUTE = 0,SECOND = 0,微差= 0,ZONE_OFFSET = -28800000,DST_OFFSET = 0]

全职

每月薪水:$ 8000.0

ID员工人数:456

员工姓名:Mike Nguyen

出生日期:java.util.GregorianCalendar [time =?,areFieldsSet = false,areAllFieldsSet = true,lenient = true,zone = sun.util.calendar.ZoneInfo [id =" America / Los_Angeles" ,偏移= -28800000,dstSavings = 3600000,useDaylight =真,过渡= 185,lastRule = java.util.SimpleTimeZone中[ID =美洲/洛杉矶,偏移= -28800000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 3,startMonth = 2,朝九特派= 8,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 0,endMode = 3,endMonth = 10,endday指定= 1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 0]],Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 1977,MONTH = 5,WEEK_OF_YEAR = 6,WEEK_OF_MONTH = 2,DAY_OF_MONTH = 18,DAY_OF_YEAR = 37,DAY_OF_WEEK = 2,DAY_OF_WEEK_IN_MONTH = 1,AM_PM = 1,HOUR = 2 ,HOUR_OF_DAY = 0,MINUTE = 0,SECOND = 0,微差= 0,ZONE_OFFSET = -28800000,DST_OFFSET = 0]

全职

每月薪水:$ 10400.0

根据我的分析,我相信我必须使用SimpleDateFormat类创建一个对象并放置" MM / dd / yyyy"进入参数。但是,我必须通过创建Date对象来解析SimpleDateFormat对象。我想使用Calendar类来创建我的日期对象。

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

3 个答案:

答案 0 :(得分:2)

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

第二件事是你不必两次创建你的日期(你是在你的二传手中做的)。

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

这就是你的setter应该是这样的:

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);
}

甚至更好:

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

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

public String toString(){
    return "ID Employee Number: " + idNumber + "\n" + "Employee name: " + firstName + " "
            + lastName + "\n" + "Birth date: " + formatter.format(birthday) + "\n";
}

所以你还需要将它添加到你的代码中:

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

答案 1 :(得分:1)

TL;博士

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

详细

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

java.time

但你不应该使用Calendar。它是一个麻烦的旧日期时间类,现在已经遗留下来,取而代之的是java.time类。传统课程非常糟糕;避免他们。此外,java.time类使用immutable objects,因此thread-safe

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

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类的Stack Overflow。

要进行本地化,请指定:

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

示例:

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

请参阅此code run live at IdeOne.com

  

birthdate.toString():1955-03-17

     

输出:jeudi 17 mars 1955

提示:

  • 订购日期时间部分时,请始终使用递减次序:年,月,日,小时,分钟,秒。这是合乎逻辑的,易于遵循,并遵循日期时间值ISO 8601标准的样式。因此,不要将int month, int day, int year作为参数传递,而是传递int year , int month , int dayOfMonth

  • 更好的是,只需传递一个LocalDate对象,而不仅仅是整数。这样做会使您的代码更加self-documenting,确保有效值,并提供type safety

关于 java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

使用符合JDBC driver或更高版本的JDBC 4.2,您可以直接与数据库交换 java.time 对象。不需要字符串也不需要java.sql。* classes。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

因为您正在打印日历对象变量生日是。

您可能希望基于Calendar实现自己的类,但使用toString方法实际执行您期望的操作。