- 创建某一个时刻:
- 2000年一月一日0时0分:
DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
该类有非常多的重载方法,具体自己查看 - 该日期后的90天后的日期:
dateTime.plusDays(90).toString("E MM/dd/yyyy HH:mm:ss.SSS");
该对象toString有3个重载方法,可以是【时间格式字符串】,【时间格式字符串,Local对象】,【DateFormater对象】 - 距离 2000.1.1日 45 天之后的某天在下一个月的当前周的最后一天的日期。
dateTime.plusDays(45).plusMonths(1).dayOfWeek().withMaximumValue().toString("E MM/dd/yyyy HH:mm:ss.SSS");
- 2000年一月一日0时0分:
- Joda对象
ReadableInstant
Joda 通过 ReadableInstant 类实现了瞬间性这一概念。表示时间上的不可变瞬间的 Joda 类都属于这个类的子类。
(将这个类命名为ReadOnlyInstant 可能更好,我认为这才是设计者需要传达的意思)。
换句话说,ReadableInstant 表示时间上的某一个不可修改的瞬间。
其中的两个子类分别为 DateTime 和 DateMidnight:-
DateTime:这是最常用的一个类。它以毫秒级的精度封装时间上的某个瞬间时刻。
DateTime 始终与 DateTimeZone 相关,如果您不指定它的话,它将被默认设置为运行代码的机器所在的时区。
可以使用多种方式构建 DateTime 对象。这个构造函数使用系统时间:
DateTime dateTime = new DateTime();
如果您创建了一个 DateTime 的实例,并且没有提供 Chronology 或 DateTimeZone,Joda将使用 ISOChronology(默认)和DateTimeZone(来自系统设置)
Joda 可以使您精确地控制创建 DateTime 对象的方式,该对象表示时间上的某个特定的瞬间。- 构造方式一
DateTime dateTime = new DateTime(
2000, //year
1, // month
1, // day
0, // hour (midnight is zero)
0, // minute
0, // second
0 // milliseconds
); - 构造方式二,指定从 epoch(1970年1月1日 子时 格林威治标准时间) 到某个时刻所经过的毫秒数。
DateTime dateTime = new DateTime(System.currentTimeMillis()); - 其他构造方式
// Use a Calendar
dateTime = new DateTime(calendar);
// Use another Joda DateTime
dateTime = new DateTime(anotherDateTime);
// Use a String (must be formatted properly)
String timeString = "2006-01-26T13:30:00-06:00";
dateTime = new DateTime(timeString);
timeString = "2006-01-26";
dateTime = new DateTime(timeString);
- 构造方式一
DateMidnight:这个类封装某个时区(通常为默认时区)在特定年/月/日的午夜时分的时刻。
它基本上类似于 DateTime,不同之处在于时间部分总是为与该对象关联的特定 DateTimeZone 时区的午夜时分。ReadablePartial
应用程序所需处理的日期问题并不全部都与时间上的某个完整时刻有关,因此您可以处理一个局部时刻。
例如,有时您比较关心年/月/日,或者一天中的时间,甚至是一周中的某天。Joda 设计者使用ReadablePartial 接口捕捉这种表示局部时间的概念,这是一个不可变的局部时间片段。用于处理这种时间片段的两个有用类分别为 LocalDate 和 LocalTime:LocalDate:该类封装了一个年/月/日的组合。当地理位置(即时区)变得不重要时,使用它存储日期将非常方便。
例如,某个特定对象的出生日期 可能为 1999 年 4 月 16 日,但是从技术角度来看,
在保存所有业务值的同时不会了解有关此日期的任何其他信息(比如这是一周中的星期几,或者这个人出生地所在的时区)。在这种情况下,应当使用 LocalDate。LocalTime:这个类封装一天中的某个时间,当地理位置不重要的情况下,可以使用这个类来只存储一天当中的某个时间。例如,晚上 11:52 可能是一天当中的一个重要时刻(比如,一个 cron 任务将启动,它将备份文件系统的某个部分),但是这个时间并没有特定于某一天,因此我不需要了解有关这一时刻的其他信息。
-
创建代码:
//方法一:取系统点间 DateTime dt1 = new DateTime(); System.out.println(dt1); //方法二:通过java.util.Date对象生成 DateTime dt2 = new DateTime(new Date()); System.out.println(dt2); //方法三:指定年月日点分秒生成(参数依次是:年,月,日,时,分,秒,毫秒) DateTime dt3 = new DateTime(2012, 5, 20, 13, 14, 0, 0); System.out.println(dt3); //方法四:ISO8601形式生成 DateTime dt4 = new DateTime("2012-05-20"); System.out.println(dt4); DateTime dt5 = new DateTime("2012-05-20T13:14:00"); System.out.println(dt5); //只需要年月日的时候 LocalDate localDate = new LocalDate(2009, 9, 6);// September 6, 2009 System.out.println(localDate); //只需要时分秒毫秒的时候 LocalTime localTime = new LocalTime(13, 30, 26, 0);// 1:30:26PM System.out.println(localTime);
- 与JDK日期对象转换
DateTime dt = new DateTime();
//转换成java.util.Date对象
Date d1 = new Date(dt.getMillis());
Date d2 = dt.toDate();
//转换成java.util.Calendar对象
Calendar c1 = Calendar.getInstance();
c1.setTimeInMillis(dt.getMillis());
Calendar c2 = dt.toCalendar(Locale.getDefault());
//对于 ReadablePartial 子类,您还需要经过额外一步
Date date = localDate.toDateMidnight().toDate();
//要创建 Date 对象,您必须首先将它转换为一个 DateMidnight 对象,然后只需要将 DateMidnight 对象作为 Date。
- 日期计算
//假设在当前的系统日期下,我希望计算上一个月的最后一天。对于这个例子,我并不关心一天中的时间,因为我只需要获得年/月/日,如所示:
LocalDate now = SystemFactory.getClock().getLocalDate();
LocalDate lastDayOfPreviousMonth = now.minusMonths(1).dayOfMonth().withMaximumValue();
首先,我从当前月份减去一个月,得到 “上一个月”。
接着,我要求获得 dayOfMonth 的最大值,它使我得到这个月的最后一天。
注意,这些调用被连接到一起(注意 Joda ReadableInstant 子类是不可变的),这样您只需要捕捉调用链中最后一个方法的结果,从而获得整个计算的结果。
您可能对dayOfMonth() 调用感兴趣。这在 Joda 中被称为属性(property)。它相当于 Java对象的属性。
属性是根据所表示的常见结构命名的,并且它被用于访问这个结构,用于完成计算目的。
属性是实现 Joda 计算威力的关键。您目前所见到的所有 4 个 Joda 类都具有这样的属性。一些例子包括:
yearOfCentury
dayOfYear
monthOfYear
dayOfMonth
dayOfWeek
获得任何一年中的第 11 月的第一个星期二的日期,而这天必须是在这个月的第一个星期一之后:
LocalDate now = SystemFactory.getClock().getLocalDate();
LocalDate electionDate = now.monthOfYear()
.setCopy(11) // November
.dayOfMonth() // Access Day Of Month Property
.withMinimumValue() // Get its minimum value
.plusDays(6) // Add 6 days
.dayOfWeek() // Access Day Of Week Property
.setCopy("Monday") // Set to Monday (it will round down)
.plusDays(1); // Gives us Tuesday
代码中的setCopy("Monday") 是整个计算的关键。不管中间LocalDate 值是多少,将其 dayOfWeek 属性设置为 Monday 总是能够四舍五入,
这样的话,在每月的开始再加上 6 天就能够让您得到第一个星期一。再加上一天就得到第一个星期二。Joda 使得执行此类计算变得非常容易。
- 格式化时间
dateTime.toString(ISODateTimeFormat.basicDateTime());
dateTime.toString(ISODateTimeFormat.basicDateTimeNoMillis());
dateTime.toString(ISODateTimeFormat.basicOrdinalDateTime());
dateTime.toString(ISODateTimeFormat.basicWeekDateTime());
DateTime dateTime = DateTime.now();
dateTime.toString("MM/dd/yyyy hh:mm:ss.SSSa");
dateTime.toString("dd-MM-yyyy HH:mm:ss");
dateTime.toString("EEEE dd MMMM, yyyy HH:mm:ssa");
dateTime.toString("MM/dd/yyyy HH:mm ZZZZ");
dateTime.toString("MM/dd/yyyy HH:mm Z"); - 案例
//获取年月日点分秒
DateTime dt = new DateTime();
//年
int year = dt.getYear();
//月
int month = dt.getMonthOfYear();
//日
int day = dt.getDayOfMonth();
//星期
int week = dt.getDayOfWeek();
//点
int hour = dt.getHourOfDay();
//分
int min = dt.getMinuteOfHour();
//秒
int sec = dt.getSecondOfMinute();
//毫秒
int msec = dt.getMillisOfSecond();
//星期的特殊处理
dt.getDayOfWeek()
DateTime dt = new DateTime();
//星期
switch(dt.getDayOfWeek()) {
case DateTimeConstants.SUNDAY:
System.out.println("星期日");
break;
case DateTimeConstants.MONDAY:
System.out.println("星期一");
break;
case DateTimeConstants.TUESDAY:
System.out.println("星期二");
break;
case DateTimeConstants.WEDNESDAY:
System.out.println("星期三");
break;
case DateTimeConstants.THURSDAY:
System.out.println("星期四");
break;
case DateTimeConstants.FRIDAY:
System.out.println("星期五");
break;
case DateTimeConstants.SATURDAY:
System.out.println("星期六");
break;
}
//与JDK日期对象的转换
DateTime dt = new DateTime();
//转换成java.util.Date对象
Date d1 = new Date(dt.getMillis());
Date d2 = dt.toDate();
//转换成java.util.Calendar对象
Calendar c1 = Calendar.getInstance();
c1.setTimeInMillis(dt.getMillis());
Calendar c2 = dt.toCalendar(Locale.getDefault());
//日期前后推算
DateTime dt = new DateTime();
//昨天
DateTime yesterday = dt.minusDays(1);
//明天
DateTime tomorrow = dt.plusDays(1);
//1个月前
DateTime before1month = dt.minusMonths(1);
//3个月后
DateTime after3month = dt.plusMonths(3);
//2年前
DateTime before2year = dt.minusYears(2);
//5年后
DateTime after5year = dt.plusYears(5);
//取特殊日期
DateTime dt = new DateTime();
//月末日期
DateTime lastday = dt.dayOfMonth().withMaximumValue();
//90天后那周的周一
DateTime firstday = dt.plusDays(90).dayOfWeek().withMinimumValue();
//时区
//默认设置为日本时间
DateTimeZone.setDefault(DateTimeZone.forID("Asia/Tokyo"));
DateTime dt1 = new DateTime();
//伦敦时间
DateTime dt2 = new DateTime(DateTimeZone.forID("Europe/London"));
//计算区间
DateTime begin = new DateTime("2012-02-01");
DateTime end = new DateTime("2012-05-01");
//计算区间毫秒数
Duration d = new Duration(begin, end);
long time = d.getMillis();
//计算区间天数
Period p = new Period(begin, end, PeriodType.days());
int days = p.getDays();
//计算特定日期是否在该区间内
Interval i = new Interval(begin, end);
boolean contained = i.contains(new DateTime("2012-03-01"));
DateTime d1 = new DateTime("2012-02-01");
DateTime d2 = new DateTime("2012-05-01");
//和系统时间比
boolean b1 = d1.isAfterNow();
boolean b2 = d1.isBeforeNow();
boolean b3 = d1.isEqualNow();
//和其他日期比
boolean f1 = d1.isAfter(d2);
boolean f2 = d1.isBefore(d2);
boolean f3 = d1.isEqual(d2);
//格式化输出
DateTime dateTime = new DateTime();
String s1 = dateTime.toString("yyyy/MM/dd hh:mm:ss.SSSa");
String s2 = dateTime.toString("yyyy-MM-dd HH:mm:ss");
String s3 = dateTime.toString("EEEE dd MMMM, yyyy HH:mm:ssa");
String s4 = dateTime.toString("yyyy/MM/dd HH:mm ZZZZ");
String s5 = dateTime.toString("yyyy/MM/dd HH:mm Z");
// 今日凌晨
Date date = DateTime.parse(DateTime.now().toString("yyyy-MM-dd")).toDate()
// 今天9点对应的日期
Date date = DateTime.parse(DateTime.now().toString("yyyy-MM-dd")).hourOfDay().addToCopy(9).toDate();
// 当前时间加1分钟
Date date = DateTime.now().minuteOfHour().addToCopy(1)).toDate()
public static DateTime getNowWeekMonday() {
DateTime date = DateTime.now();
int dayOfWeek = date.getDayOfWeek();
return DateTime.parse(date.minusDays(dayOfWeek - 1).toString("yyyy-MM-dd"));
}
private static final String DATE_FORMAT = "yyyy-MM-dd";
//每周一0点0分0秒触发,处理上上周
@Scheduled(cron = "0 0 0 ? * MON ")
public void weeklyRemind() {
logger.info("CyclePendingReminderTask.weeklyRemind");
logger.info("周期性待处理提醒任务开始");
String now = DateTime.now().toString(DATE_FORMAT);
//往前推2周,上上周周一
String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusWeeks(2).toString(DATE_FORMAT);
//上上周周日
String to = DateTime.parse(from, ISODateTimeFormat.dateElementParser())
.plusWeeks(1).minusDays(1).toString(DATE_FORMAT);
//上上周周一0点时间戳
long fromTime = DateTime.parse(from, ISODateTimeFormat.dateElementParser()).getMillis();
//上周周一0点时间戳
long toTime = DateTime.parse(to, ISODateTimeFormat.dateElementParser()).plus(1).getMillis();
List<String> userIdList = ideaService.getUserIdList();
for (String userId : userIdList) {
List<Idea> ideaList = ideaService.findIdeasByCreateAt(userId, fromTime, toTime);
//有创建想法才会有提醒
if (ideaList.size() > 0) {
CyclePendingIdeaReminder reminder = new CyclePendingIdeaReminder();
reminder.setUserId(userId);
reminder.setFrom(from);
reminder.setTo(to);
reminder.setFinished(false);
cpiReminderService.save(reminder);
}
}
logger.info("周期性待处理提醒任务完成");
}
//每月一号0点0分0秒触发
//当中再判断当前月份进行季度和年度的处理操作
@Scheduled(cron = "0 0 0 1 * ? ")
public void monthlySelectionRemind() {
logger.info("IdeaSelectionReminderTask monthlySelectionRemind start.");
DateTime nowTime = DateTime.now();
int month = nowTime.getMonthOfYear();
String now = nowTime.toString(DATE_FORMAT);
//年度处理: 1
if (month == 1) {
logger.info("年度精选任务开始");
String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusYears(1).toString(DATE_FORMAT);
String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusDays(1).toString(DATE_FORMAT);
doMonthly(from, to, OriginalityType.year);
logger.info("年度精选任务完成");
}
//季度处理: 3(4) 6(7) 9(10) 12(1)
if (month == 4 || month == 7 || month == 10 || month == 1) {
logger.info("季度精选任务开始");
String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusMonths(3).toString(DATE_FORMAT);
String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusDays(1).toString(DATE_FORMAT);
doMonthly(from, to, OriginalityType.quarter);
logger.info("季度精选任务完成");
}
//月份处理
logger.info("月精选任务开始");
String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusMonths(1).toString(DATE_FORMAT);
String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
.minusDays(1).toString(DATE_FORMAT);
doMonthly(from, to, OriginalityType.month);
logger.info("月精选任务完成");
logger.info("IdeaSelectionReminderTask monthlySelectionRemind finish.");
}
- 来自# Joda-Time 学习笔记