【问题标题】:displaying date using calendar object使用日历对象显示日期
【发布时间】:2017-06-24 01:18:39
【问题描述】:

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

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",offset=-28800000 ,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth= 2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=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,MILLISECOND=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",offset=-28800000 ,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth= 2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=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,MILLISECOND=0,ZONE_OFFSET=-28800000,DST_OFFSET=0]

全职

月薪:$10400.0


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

我在调试的时候发现出生日期显示错误;它打印了我生日对象中的所有内容。我不知道该怎么办。非常感谢您的帮助。 :)

【问题讨论】:

    标签: java date calendar


    【解决方案1】:

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

    您可能希望基于 Calendar 实现自己的类,但使用 toString 方法实际上可以满足您的期望。

    【讨论】:

      【解决方案2】:

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

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

      最后但同样重要的是,您必须在打印之前格式化日期(在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");
      

      【讨论】:

      • SimpleDateFormat 不是线程安全的,所以最好不要将此字段声明为静态字段。最好的解决方案是使用 JodaTime 格式化程序,因为它是线程安全的。如果没有 joda time,更好的方法是每次需要在方法上下文中使用它时创建 SimpleDateFormat 实例,或者在格式化程序的静态实例上同步。
      • 或者只是将格式化程序声明为实例成员。但将其设为本地对象的建议更好。
      【解决方案3】:

      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。对于其他格式,请在 Stack Overflow 中搜索 java.time.format.DateTimeFormatter 类。

      要本地化,请指定:

      • 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.DateCalendarSimpleDateFormat

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

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

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

      从哪里获得 java.time 类?

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

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 2011-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多