有人能建议当前的“最佳实践”围绕日期和日历类型。

在编写新代码时,最好总是使用Calendar而不是Date,还是在某些情况下Date是更合适的数据类型?


当前回答

如果可能的话,我通常使用Date。虽然它是可变的,但实际上不推荐使用突变器。最后,它基本上包装了一个表示日期/时间的long。相反,如果我必须操作这些值,我会使用calendar。

您可以这样想:只在需要可以轻松操作的字符串时使用StringBuffer,然后使用toString()方法将它们转换为字符串。同样,我只在需要操作时态数据时使用Calendar。

为了实现最佳实践,我倾向于在域模型之外尽可能多地使用不可变对象。它极大地降低了任何副作用的可能性,并且它是由编译器代替JUnit测试完成的。可以通过在类中创建私有final字段来使用这种技术。

回到StringBuffer的类比。下面是一些代码,向您展示如何在日历和日期之间进行转换

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);

其他回答

如果可能的话,我通常使用Date。虽然它是可变的,但实际上不推荐使用突变器。最后,它基本上包装了一个表示日期/时间的long。相反,如果我必须操作这些值,我会使用calendar。

您可以这样想:只在需要可以轻松操作的字符串时使用StringBuffer,然后使用toString()方法将它们转换为字符串。同样,我只在需要操作时态数据时使用Calendar。

为了实现最佳实践,我倾向于在域模型之外尽可能多地使用不可变对象。它极大地降低了任何副作用的可能性,并且它是由编译器代替JUnit测试完成的。可以通过在类中创建私有final字段来使用这种技术。

回到StringBuffer的类比。下面是一些代码,向您展示如何在日历和日期之间进行转换

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);

日期应该用作不可变的时间点;日历是可变的,如果您需要与其他类协作以得出最终日期,则可以传递和修改日历。把它们看作类似于String和StringBuilder,您就会理解我认为应该如何使用它们。

(是的,我知道Date实际上在技术上不是不可变的,但目的是它不应该是不可变的,如果没有调用已弃用的方法,那么它就是不可变的。)

顺便说一句,“日期”通常被标记为“过时/弃用”(我不知道确切的原因)-关于它的一些东西写在那里 Java:为什么日期构造函数弃用,我用什么代替?

看起来这是一个构造函数的问题-方法通过新日期(int年,int月,int日),推荐的方法是通过日历和设置参数分开。(Calendar cal = Calendar. getinstance (); )

日期应该重新开发。它不应该是一个长整数,而应该包含年、月、日、小时、分钟、秒作为单独的字段。甚至还可以存储这个日期所关联的日历和时区。

在我们平常的谈话中,如果你安排的约会时间是纽约时间2013年11月1日下午1点,这就是“约会时间”。它不是日历。所以我们在Java中也应该能够像这样交谈。

当Date存储为一个长整数(自1970年1月1日以来的毫秒数)时,计算其当前日期取决于日历。不同的日历会给出不同的日期。这是从给出绝对时间(如大爆炸后1万亿秒)的角度出发的。但通常我们也需要一种方便的对话方式,比如一个对象可以封装年、月等。

我想知道Java中是否有新的进展来协调这两个目标。也许我的java知识太老了。

当我需要对日期进行一些特定的操作时,我使用日历,但当你需要格式化日期以适应你的需求时,我发现它很有帮助,最近我发现Locale有很多有用的操作和方法。我现在使用Locale !