引用文章:
快速入门指南(英文)
官方API(2.9.7)
以 Joda 的方式处理时间
日期计算
如果您只是需要对日期/时间信息使用占位符,那么 JDK 完全可以胜任,但是它在日期/时间计算方面的表现十分糟糕,而这正是 Joda 的长处。我将向您展示一些简单的例子。
假设在当前的系统日期下,我希望计算上一个月的最后一天。对于这个例子,我并不关心一天中的时间,因为我只需要获得年/月/日。
//获取当前日期
LocalDate now = new LocalDate();
System.out.println(now.toString());
//1.减去一个月。2.得到月的天数属性。3.得到最后一天
LocalDate lastDayOfPreviousMonth = now.minusMonths(1).dayOfMonth().withMaximumValue();
System.out.println(lastDayOfPreviousMonth.toString());
您可能对dayOfMonth() 调用感兴趣。这在 Joda 中被称为属性(property)。它相当于 Java 对象的属性。属性是根据所表示的常见结构命名的,并且它被用于访问这个结构,用于完成计算目的。属性是实现 Joda 计算威力的关键。您目前所见到的所有 4 个 Joda 类都具有这样的属性。一些例子包括:
yearOfCentury
dayOfYear
monthOfYear
dayOfMonth
dayOfWeek
首先,我从当前月份减去一个月,得到 “上一个月”。接着,我要求获得 dayOfMonth 的最大值,它使我得到这个月的最后一天。注意,这些调用被连接到一起(注意 Joda ReadableInstant 子类是不可变的),这样您只需要捕捉调用链中最后一个方法的结果,从而获得整个计算的结果。
当计算的中间结果对我不重要时,我经常会使用这种计算模式。(我以相同的方式使用 JDK 的 BigDecimal(高精度数值计算))
假设您希望获得任何一年中的第 11 月的第一个星期二的日期,而这天必须是在这个月的第一个星期一之后。
LocalDate now = new LocalDate();
System.out.println("Now:" + now.toString());
LocalDate electionDate = now.monthOfYear()
.setCopy(11) // 11月
.dayOfMonth() // 获取dayOfMonth属性
.withMinimumValue() // 获取它的第一天
.plusDays(6) // 接着增加六天
.dayOfWeek() // 获取Day Of Week属性
.setCopy("1") // 设置11月1日至7日中星期一的那天为日期
.plusDays(1); // 增加一天就是星期二了
System.out.println("Then:" + electionDate.toString());
在上面例子中,setCopy()需要根据系统时间所在的时区来设置不同的值。在国外 周一 可能需要用“Monday”,在中国,“1”表示周一,以此类推。如果在中国使用“Monday”将会抛出 org.joda.time.IllegalFieldValueException。
.setCopy("1") 是整个计算的关键。不管中间 LocalDate 值是多少,将其 dayOfWeek属性设置为 1总是能够从7天中获取到,这样的话,在每月的开始再加上 6 天就能够让您得到第一个星期一。再加上一天就得到第一个星期二。
DateTime now = new LocalDate();
System.out.println("example3_4-Now:" + now.toString());
DateTime then = now.plusWeeks(2);
System.out.println("example3_4-Then:" + then.toString());
DateTime now = new DateTime();
System.out.println("example3_3-Now:" + now.toString());
DateTime tomorrow = now.plusDays(1);
DateTime then = tomorrow.plusDays(90);
System.out.println("example3_3-Then:" + then.toString());
DateTime now = new DateTime();
DateTime then = now.plusSeconds(156);
JDK 互操作性
我的许多代码都使用了 JDK Date 和 Calendar 类。但是幸亏有 Joda,我可以执行任何必要的日期算法,然后再转换回 JDK 类。这将两者的优点集中到一起。您在本文中看到的所有 Joda 类都可以从 JDK Calendar 或 Date 创建,正如您在 创建 Joda-Time 对象 中看到的那样。出于同样的原因,可以从您所见过的任何 Joda 类创建 JDK Calendar 或 Date。
从 Joda ReadableInstant 子类转换为 JDK 类有多么简单:
DateTime dateTime = new DateTime();
System.out.println("DateTime:" + dateTime.toString());
Calendar calendar = dateTime.toCalendar(Locale.getDefault());
SimpleDateFormat sdf = new SimpleDateFormat();
System.out.println("作为 Calendar:" + sdf.format(calendar.getTime()));
Date date = dateTime.toDate();
System.out.println("作为 Date:" + sdf.format(date));
DateMidnight dateMidnight = SystemFactory.getClock()
.getDateMidnight();
date = dateMidnight.toDate();
System.out.println("作为 Date (from DateMidnight):" + sdf.format(date));
LocalDate localDate = new LocalDate();
Date date = localDate.toDateMidnight().toDate();
以 Joda 方式格式化时间
使用 JDK 格式化日期以实现打印是完全可以的,但是我始终认为它应该更简单一些。这是 Joda 设计者进行了改进的另一个特性。要格式化一个 Joda 对象,调用它的 toString() 方法,并且如果您愿意的话,传递一个标准的 ISO-8601(标准日期表示法) 或一个 JDK 兼容的控制字符串,以告诉 JDK 如何执行格式化。不需要创建单独的 SimpleDateFormat 对象(但是 Joda 的确为那些喜欢自找麻烦的人提供了一个 DateTimeFormatter类)。调用 Joda 对象的 toString() 方法,仅此而已。我将展示一些例子。
使用 ISO-8601
DateTime dateTime = new DateTime();
//基本日期时间
System.out.println("Using ISODateTimeFormat.basicDateTime: " +
dateTime.toString(ISODateTimeFormat.basicDateTime())
);
//不包含毫秒的日期时间
System.out.println("Using ISODateTimeFormat.basicDateTimeNoMillis: " +
dateTime.toString(ISODateTimeFormat.basicDateTimeNoMillis())
);
//基本的原始日期时间
System.out.println("Using ISODateTimeFormat.basicOrdinalDateTime: " +
dateTime.toString(ISODateTimeFormat.basicOrdinalDateTime())
);
//基本的年和周组合时间
System.out.println("Using ISODateTimeFormat.basicWeekDateTime: " +
dateTime.toString(ISODateTimeFormat.basicWeekDateTime())
);
使用与 JDK 兼容的格式字符串
DateTime dateTime = new DateTime();
System.out.println("Using yyyy/MM/d hh:mm:ss.SSSa: " +
dateTime.toString("yyyy/MM/dd hh:mm:ss.SSSa")
);
System.out.println("Using yyyy.MM.dd HH:mm:ss: " +
dateTime.toString("yyyy.MM.dd HH:mm:ss")
);
System.out.println("Using yyyy-MM-dd, yyyy HH:mm:ss: " +
dateTime.toString("yyyy-MM-dd, yyyy HH:mm:ss")
);
System.out.println("Using yyyy-MM-dd HH:mm ZZZZ: " +
dateTime.toString("yyyy-MM-dd HH:mm ZZZZ")
);
System.out.println("Using yyyy-MM-dd HH:mm Z: " +
dateTime.toString("yyyy-MM-dd HH:mm Z")
);
System.out.println("Using yyyy-MM-dd HH:mm Z: " +
dateTime.toString("yyyy-MM-dd HH:mm Z")
);