tl;博士
holidays.add(
new Holiday(
LocalDate.of( 2018 , Month.MAY , 8 ) ,
"National Coconut Cream Pie Day"
)
)
java.time
使用现代的 java.time 类而不是过时的遗留 Calendar 类及其常用的子类 GregorianCalendar,这项工作要简单得多。
LocalDate
LocalDate 类表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
如果没有指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好将您想要/预期的时区明确指定为参数。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果你想使用 JVM 当前的默认时区,请求它并作为参数传递。如果省略,则隐式应用 JVM 的当前默认值。最好是明确的,因为默认值可能会在任何时候在运行时被 JVM 中任何应用程序的任何线程中的任何代码更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
或者指定一个日期。您可以通过数字设置月份,1 月至 12 月的编号为 1-12。
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
或者,更好的是,使用预定义的Month 枚举对象,一年中的每个月一个。提示:在整个代码库中使用这些 Month 对象,而不是仅仅使用整数,以使您的代码更具自记录性,确保有效值,并提供 type-safety。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
自定义类
您在代码中两次误用了名称 Holidays,一次是列表集合的名称,一次是单个“假期”类/对象的名称。此外,第一个用作保存静态类的变量,不太可能是一个好的设计。
我假设第二个是错字,第二个应该是 Holiday 作为代表特定日期的特定假期的类的名称。
你的Holiday 类看起来像这样。
class Holiday
{
private LocalDate localDate;
private String name;
private DayOfWeek dow;
public Holiday ( LocalDate localDateArg , String nameArg )
{
this.localDate = localDateArg;
this.name = nameArg;
}
public LocalDate getLocalDate ( )
{
return localDate;
}
public String getName ( )
{
return name;
}
// With arguments.
public String format ( Locale locale , FormatStyle style )
{
String date = this.localDate.format( DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale ) );
String output = date + " | " + this.name;
return output;
}
@Override
public String toString ( )
{
return "Holiday{ " +
"localDate=" + localDate +
", name='" + name + '\'' +
" }";
}
}
接下来,我们使用那个类。
List
实例化一个空的List。您可以选择设置ArrayList 的初始容量。
List < Holiday > holidays = new ArrayList <>( 3 );
填充该列表。
holidays.add( new Holiday( LocalDate.of( 2018 , Month.MAY , 8 ) , "National Coconut Cream Pie Day" ) );
holidays.add( new Holiday( LocalDate.of( 2018 , Month.AUGUST , 9 ) , "National Rice Pudding Day" ) );
holidays.add( new Holiday( LocalDate.of( 2018 , Month.JANUARY , 5 ) , "National Whipped Cream Day" ) );
holidays.toString():
[Holiday{ localDate=2018-05-08, name='全国椰子奶油派日'}, Holiday{ localDate=2018-08-09, name='全国大米布丁日'}, Holiday{ localDate=2018 -01-05,name='全国鲜奶油日'}]
用Comparator排序
要排序,请传递Comparator 的实现。这是经典的 Java 语法。
holidays.sort( new Comparator < Holiday >()
{
@Override
public int compare ( Holiday o1 , Holiday o2 )
{
int c = o1.getLocalDate().compareTo( o2.getLocalDate() );
return c;
}
} );
这是使用 lambda 的现代 Java 语法中相同的 Comparator。
holidays.sort( ( o1 , o2 ) ->
{
int c = o1.getLocalDate().compareTo( o2.getLocalDate() );
return c;
} );
甚至更短的 lambda 语法,但不一定更好。
holidays.sort( ( o1 , o2 ) -> o1.getLocalDate().compareTo( o2.getLocalDate() ) );
无论哪种方式,结果都是:
holidays.toString():
[Holiday{ localDate=2018-01-05, name='National Whipped Cream Day' }, Holiday{ localDate=2018-05-08, name='National Coconut Cream Pie Day'}, Holiday{ localDate=2018 -08-09, name='全国大米布丁日'}]
格式化输出
对于带有星期几的日期,请使用我们定义的 format 方法,该方法会自动本地化为我们通过 Locale 和 FormatStyle 指定的人类语言和文化规范。
for ( Holiday holiday : holidays )
{
System.out.println( holiday.format( Locale.CANADA_FRENCH , FormatStyle.FULL ) );
}
vendredi 2018 年 1 月 5 日 |全国鲜奶油日
狂欢节 2018 年 5 月 8 日 |全国椰子奶油派日
jeudi 9 août 2018 |全国大米布丁日
或者美国英语,通过Locale.US:
2018 年 1 月 5 日,星期五 |全国鲜奶油日
2018 年 5 月 8 日,星期二 |全国椰子奶油派日
2018 年 8 月 9 日,星期四 |全国大米布丁日
请注意,您可以从LocalDate 获取DayOfWeek 枚举对象。从此,您可以使用 DayOfWeek::getDisplayName 方法自动本地化当天的名称。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。