一 Jode-Time 介绍

任何企业应用程序都需要处理时间问题。应用程序需要知道当前的时间点和下一个时间点,有时它们还必须计算这两个
时间点之间的路径。使用 JDK 完成这项任务将非常痛苦和繁琐。
既然无法摆脱时间,为何不设法简化时间处理?现在来看看 Joda Time,一个面向 Java™ 平台的易于
使用的开源时间/日期库。正如您在本文中了解的那样,JodaTime轻松化解了处理日期和时间的痛苦和繁琐。

Joda-Time 令时间和日期值变得易于管理、操作和理解。事实上,易于使用是 Joda 的主要设计目标。其他目标包括可扩展性、完整的特性集以及对多种日历系统的支持。
并且 Joda 与 JDK 是百分之百可互操作的,因此您无需替换所有 Java 代码,只需要替换执行日期/时间计算的那部分代码。
Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time。可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成。

为什么要使用 Joda?
考虑创建一个用时间表示的某个随意的时刻 — 比如,2000 年 1 月 1 日 0 时 0 分。
我如何创建一个用时间表示这个瞬间的 JDK 对象?使用 java.util.Date?
事实上这是行不通的,因为自 JDK 1.1 之后的每个 Java 版本的 Javadoc 都声明应当使用 java.util.Calendar。
Date 中不赞成使用的构造函数的数量严重限制了您创建此类对象的途径。

那么 Calendar 又如何呢?我将使用下面的方式创建必需的实例:

  1. Calendar calendar = Calendar.getInstance();
  2. calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);

使用 Joda,代码应该类似如下所示:

  1. DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);

这一行简单代码没有太大的区别。但是现在我将使问题稍微复杂化。
假设我希望在这个日期上加上 90 天并输出结果。使用 JDK,我需要使用清单 1 中的代码:

  1. // 以 JDK 的方式向某一个瞬间加上 90 天并输出结果
  2. Calendar calendar = Calendar.getInstance();
  3. calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
  4. SimpleDateFormat sdf =
  5. new SimpleDateFormat("E MM/dd/yyyy HH:mm:ss.SSS");
  6. calendar.add(Calendar.DAY_OF_MONTH, 90);
  7. System.out.println(sdf.format(calendar.getTime()));
  1. // 以 Joda 的方式向某一个瞬间加上 90 天并输出结果
  2. DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
  3. System.out.println(dateTime.plusDays(90).toString("E MM/dd/yyyy HH:mm:ss.SSS");

两者之间的差距拉大了(Joda 用了两行代码,JDK 则是 5 行代码)。
现在假设我希望输出这样一个日期:距离 2000.1.1日 45 天之后的某天在下一个月的当前周的最后一天的日期。
坦白地说,我甚至不想使用 Calendar 处理这个问题。
使用 JDK 实在太痛苦了,即使是简单的日期计算,比如上面这个计算。
正是多年前的这样一个时刻,我第一次领略到 JodaTime的强大。使用 Joda,用于计算的代码所示:

  1. DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
  2. System.out.println(dateTime.plusDays(45).plusMonths(1).dayOfWeek()
  3. .withMaximumValue().toString("E MM/dd/yyyy HH:mm:ss.SSS");
  4.  
  5. 输出为:
  6. Sun 03/19/2000 00:00:00.000

如果您正在寻找一种易于使用的方式替代 JDK 日期处理,那么您真的应该考虑 Joda。

创建Joda-Time对象

现在,我将展示在采用该库时会经常遇到的一些 Joda 类,并展示如何创建这些类的实例。

ReadableInstant
Joda 通过 ReadableInstant 类实现了瞬间性这一概念。表示时间上的不可变瞬间的 Joda 类都属于这个类的子类。
(将这个类命名为ReadOnlyInstant 可能更好,我认为这才是设计者需要传达的意思)。
换句话说,ReadableInstant 表示时间上的某一个不可修改的瞬间。
其中的两个子类分别为 DateTime 和 DateMidnight

DateTime:这是最常用的一个类。它以毫秒级的精度封装时间上的某个瞬间时刻。
DateTime 始终与 DateTimeZone 相关,如果您不指定它的话,它将被默认设置为运行代码的机器所在的时区。
可以使用多种方式构建 DateTime 对象。这个构造函数使用系统时间:

  1. DateTime dateTime = new DateTime();

如果您创建了一个 DateTime 的实例,并且没有提供 Chronology 或 DateTimeZone,Joda将使用 ISOChronology(默认)和DateTimeZone(来自系统设置)

Joda 可以使您精确地控制创建 DateTime 对象的方式,该对象表示时间上的某个特定的瞬间。

  1. DateTime dateTime = new DateTime(
  2. 2000, //year
  3. 1, // month
  4. 1, // day
  5. 0, // hour (midnight is zero)
  6. 0, // minute
  7. 0, // second
  8. 0 // milliseconds
  9. );

下一个构造函数将指定从 epoch(1970年1月1日 子时 格林威治标准时间) 到某个时刻所经过的毫秒数。
它根据 JDK Date 对象的毫秒值创建一个DateTime 对象,其时间精度用毫秒表示,因为 epoch 与 Joda 是相同的:

  1. java.util.Date jdkDate = new Date();
  2. long timeInMillis = jdkDate.getTime();
  3. DateTime dateTime = new DateTime(timeInMillis);
  1. 或者Date 对象直接传递给构造函数:
  1. dateTime = new DateTime(new Date());
  1. Joda 支持使用许多其他对象作为构造函数的参数,用于创建 DateTime:
  1. // Use a Calendar
  2. dateTime = new DateTime(calendar);
  3.  
  4. // Use another Joda DateTime
  5. dateTime = new DateTime(anotherDateTime);
  6.  
  7. // Use a String (must be formatted properly)
  8. String timeString = "2006-01-26T13:30:00-06:00";
  9. dateTime = new DateTime(timeString);
  10. timeString = "2006-01-26";
  11. dateTime = new DateTime(timeString);

注意,如果您准备使用 String(必须经过解析),您必须对其进行精确地格式化。

DateMidnight:这个类封装某个时区(通常为默认时区)在特定年/月/日的午夜时分的时刻。
它基本上类似于 DateTime,不同之处在于时间部分总是为与该对象关联的特定 DateTimeZone 时区的午夜时分。

ReadablePartial
应用程序所需处理的日期问题并不全部都与时间上的某个完整时刻有关,因此您可以处理一个局部时刻。
例如,有时您比较关心年/月/日,或者一天中的时间,甚至是一周中的某天。Joda 设计者使用ReadablePartial 接口捕捉这种表示局部时间的概念,
这是一个不可变的局部时间片段。用于处理这种时间片段的两个有用类分别为 LocalDate 和 LocalTime

LocalDate:该类封装了一个年/月/日的组合。当地理位置(即时区)变得不重要时,使用它存储日期将非常方便。
例如,某个特定对象的出生日期 可能为 1999 年 4 月 16 日,但是从技术角度来看,
在保存所有业务值的同时不会了解有关此日期的任何其他信息(比如这是一周中的星期几,或者这个人出生地所在的时区)。
在这种情况下,应当使用 LocalDate。

LocalTime:这个类封装一天中的某个时间,当地理位置不重要的情况下,可以使用这个类来只存储一天当中的某个时间。
例如,晚上 11:52 可能是一天当中的一个重要时刻(比如,一个 cron 任务将启动,它将备份文件系统的某个部分),
但是这个时间并没有特定于某一天,因此我不需要了解有关这一时刻的其他信息。

创建对象代码:

  1. package com.jt.joda;
  2.  
  3. import java.util.Date;
  4.  
  5. import org.joda.time.DateTime;
  6. import org.joda.time.LocalDate;
  7. import org.joda.time.LocalTime;
  8. import org.junit.Test;
  9.  
  10. public class Demo {
  11.  
  12. @Test
  13. public void test1(){
  14.  
  15. //方法一:取系统点间
  16. DateTime dt1 = new DateTime();
  17. System.out.println(dt1);
  18.  
  19. //方法二:通过java.util.Date对象生成
  20. DateTime dt2 = new DateTime(new Date());
  21. System.out.println(dt2);
  22.  
  23. //方法三:指定年月日点分秒生成(参数依次是:年,月,日,时,分,秒,毫秒)
  24. DateTime dt3 = new DateTime(2012, 5, 20, 13, 14, 0, 0);
  25. System.out.println(dt3);
  26. //方法四:ISO8601形式生成
  27. DateTime dt4 = new DateTime("2012-05-20");
  28. System.out.println(dt4);
  29. DateTime dt5 = new DateTime("2012-05-20T13:14:00");
  30. System.out.println(dt5);
  31.  
  32. //只需要年月日的时候
  33. LocalDate localDate = new LocalDate(2009, 9, 6);// September 6, 2009
  34. System.out.println(localDate);
  35.  
  36. //只需要时分秒毫秒的时候
  37. LocalTime localTime = new LocalTime(13, 30, 26, 0);// 1:30:26PM
  38. System.out.println(localTime);
  39.  
  40. }
  41. /*
  42. 2015-09-25T17:51:12.900+08:00
  43. 2015-09-25T17:51:12.977+08:00
  44. 2012-05-20T13:14:00.000+08:00
  45. 2012-05-20T00:00:00.000+08:00
  46. 2012-05-20T13:14:00.000+08:00
  47. 2009-09-06
  48. 13:30:26.000
  49. */
  50.  
  51. }

三 与JDK日期对象转换

许多代码都使用了 JDK Date 和 Calendar 类。但是幸亏有 Joda,可以执行任何必要的日期算法,然后再转换回 JDK 类。
这将两者的优点集中到一起。您在本文中看到的所有 Joda 类都可以从 JDK Calendar 或 Date 创建,正如您在 创建 JodaTime对象 中看到的那样。
出于同样的原因,可以从您所见过的任何 Joda 类创建 JDK Calendar 或 Date。

  1. 1. DateTime dt = new DateTime();
  2. 2.
  3. 3. //转换成java.util.Date对象
  4. 4. Date d1 = new Date(dt.getMillis());
  5. 5. Date d2 = dt.toDate();
  6. 6.
  7. 7. //转换成java.util.Calendar对象
  8. 8. Calendar c1 = Calendar.getInstance();
  9. 9. c1.setTimeInMillis(dt.getMillis());
  10. 10. Calendar c2 = dt.toCalendar(Locale.getDefault());

对于 ReadablePartial 子类,您还需要经过额外一步,如所示:

  1. 1 Date date = localDate.toDateMidnight().toDate();

要创建 Date 对象,您必须首先将它转换为一个 DateMidnight 对象,然后只需要将 DateMidnight 对象作为 Date。
(当然,产生的 Date 对象将把它自己的时间部分设置为午夜时刻)。
JDK 互操作性被内置到 Joda API 中,因此您无需全部替换自己的接口,如果它们被绑定到 JDK 的话。比
如,您可以使用 Joda 完成复杂的部分,然后使用 JDK 处理接口。

四 日期计算

现在,您已经了解了如何创建一些非常有用的 Joda 类,我将向您展示如何使用它们执行日期计算。

假设在当前的系统日期下,我希望计算上一个月的最后一天。对于这个例子,我并不关心一天中的时间,因为我只需要获得年/月/日,如所示:

  1. LocalDate now = SystemFactory.getClock().getLocalDate();
  2. LocalDate lastDayOfPreviousMonth = now.minusMonths(1).dayOfMonth().withMaximumValue();

首先,我从当前月份减去一个月,得到 “上一个月”。
接着,我要求获得 dayOfMonth 的最大值,它使我得到这个月的最后一天。
注意,这些调用被连接到一起(注意 Joda ReadableInstant 子类是不可变的),这样您只需要捕捉调用链中最后一个方法的结果,从而获得整个计算的结果。

您可能对dayOfMonth() 调用感兴趣。这在 Joda 中被称为属性(property)。它相当于 Java对象的属性。
属性是根据所表示的常见结构命名的,并且它被用于访问这个结构,用于完成计算目的。
属性是实现 Joda 计算威力的关键。您目前所见到的所有 4 个 Joda 类都具有这样的属性。一些例子包括:
yearOfCentury
dayOfYear
monthOfYear
dayOfMonth
dayOfWeek

假设您希望获得任何一年中的第 11 月的第一个星期二的日期,而这天必须是在这个月的第一个星期一之后。

  1. LocalDate now = SystemFactory.getClock().getLocalDate();
  2. LocalDate electionDate = now.monthOfYear()
  3. .setCopy(11) // November
  4. .dayOfMonth() // Access Day Of Month Property
  5. .withMinimumValue() // Get its minimum value
  6. .plusDays(6) // Add 6 days
  7. .dayOfWeek() // Access Day Of Week Property
  8. .setCopy("Monday") // Set to Monday (it will round down)
  9. .plusDays(1); // Gives us Tuesday

.setCopy("Monday") 是整个计算的关键。不管中间LocalDate 值是多少,将其 dayOfWeek 属性设置为 Monday 总是能够四舍五入,
这样的话,在每月的开始再加上 6 天就能够让您得到第一个星期一。再加上一天就得到第一个星期二。Joda 使得执行此类计算变得非常容易。

下面是其他一些因为使用 Joda 而变得超级简单的计算:

  1. 1. DateTime dt = new DateTime();
  2. 2.
  3. 3. //昨天
  4. 4. DateTime yesterday = dt.minusDays(1);
  5. 5. //明天
  6. 6. DateTime tomorrow = dt.plusDays(1);
  7. 7. //1个月前
  8. 8. DateTime before1month = dt.minusMonths(1);
  9. 9. //3个月后
  10. 10. DateTime after3month = dt.plusMonths(3);
  11. 11. //2年前
  12. 12. DateTime before2year = dt.minusYears(2);
  13. 13. //5年后
  14. 14. DateTime after5year = dt.plusYears(5);

  

五 格式化时间

使用 JDK 格式化日期以实现打印是完全可以的,但是我始终认为它应该更简单一些。
这是 Joda 设计者进行了改进的另一个特性。要格式化一个 Joda 对象,调用它的 toString() 方法,
并且如果您愿意的话,传递一个标准的 ISO8601或一个 JDK 兼容的控制字符串,以告诉 JDK 如何执行格式化。
不需要创建单独的 SimpleDateFormat 对象
(但是 Joda 的确为那些喜欢自找麻烦的人提供了一个DateTimeFormatter 类)。
调用 Joda 对象的 toString() 方法,仅此而已。

  1. dateTime.toString(ISODateTimeFormat.basicDateTime());
  2. dateTime.toString(ISODateTimeFormat.basicDateTimeNoMillis());
  3. dateTime.toString(ISODateTimeFormat.basicOrdinalDateTime());
  4. dateTime.toString(ISODateTimeFormat.basicWeekDateTime());
  5.  
  6. 20090906T080000.000-0500
  7. 20090906T080000-0500
  8. 2009249T080000.000-0500
  9. 2009W367T080000.000-0500
  1. DateTime dateTime = DateTime.now();
  2. dateTime.toString("MM/dd/yyyy hh:mm:ss.SSSa");
  3. dateTime.toString("dd-MM-yyyy HH:mm:ss");
  4. dateTime.toString("EEEE dd MMMM, yyyy HH:mm:ssa");
  5. dateTime.toString("MM/dd/yyyy HH:mm ZZZZ");
  6. dateTime.toString("MM/dd/yyyy HH:mm Z");
  7.  
  8. 09/06/2009 02:30:00.000PM
  9. 06-Sep-2009 14:30:00
  10. Sunday 06 September, 2009 14:30:00PM
  11. 09/06/2009 14:30 America/Chicago
  12. 09/06/2009 14:30 -0500

结束语

谈到日期处理,Joda 是一种令人惊奇的高效工具。无论您是计算日期、打印日期,或是解析日期,Joda都将是工具箱中的便捷工具。
在本文中,我首先介绍了 Joda,它可以作为 JDK 日期/时间库的替代选择。然后介绍了一些 Joda 概念,以及如何使用 Joda 执行日期计算和格式化。

六 使用代码案例

  1. 2、获取年月日点分秒
  2. 1. DateTime dt = new DateTime();
  3. 2. //年
  4. 3. int year = dt.getYear();
  5. 4. //月
  6. 5. int month = dt.getMonthOfYear();
  7. 6. //日
  8. 7. int day = dt.getDayOfMonth();
  9. 8. //星期
  10. 9. int week = dt.getDayOfWeek();
  11. 10. //点
  12. 11. int hour = dt.getHourOfDay();
  13. 12. //分
  14. 13. int min = dt.getMinuteOfHour();
  15. 14. //秒
  16. 15. int sec = dt.getSecondOfMinute();
  17. 16. //毫秒
  18. 17. int msec = dt.getMillisOfSecond();
  19.  
  20. 3 星期的特殊处理
  21.  
  22. dt.getDayOfWeek()
  23.  
  24. 1. DateTime dt = new DateTime();
  25. 2.
  26. 3. //星期
  27. 4. switch(dt.getDayOfWeek()) {
  28. 5. case DateTimeConstants.SUNDAY:
  29. 6. System.out.println("星期日");
  30. 7. break;
  31. 8. case DateTimeConstants.MONDAY:
  32. 9. System.out.println("星期一");
  33. 10. break;
  34. 11. case DateTimeConstants.TUESDAY:
  35. 12. System.out.println("星期二");
  36. 13. break;
  37. 14. case DateTimeConstants.WEDNESDAY:
  38. 15. System.out.println("星期三");
  39. 16. break;
  40. 17. case DateTimeConstants.THURSDAY:
  41. 18. System.out.println("星期四");
  42. 19. break;
  43. 20. case DateTimeConstants.FRIDAY:
  44. 21. System.out.println("星期五");
  45. 22. break;
  46. 23. case DateTimeConstants.SATURDAY:
  47. 24. System.out.println("星期六");
  48. 25. break;
  49. 26. }
  50.  
  51. 4、与JDK日期对象的转换
  52. 1. DateTime dt = new DateTime();
  53. 2.
  54. 3. //转换成java.util.Date对象
  55. 4. Date d1 = new Date(dt.getMillis());
  56. 5. Date d2 = dt.toDate();
  57. 6.
  58. 7. //转换成java.util.Calendar对象
  59. 8. Calendar c1 = Calendar.getInstance();
  60. 9. c1.setTimeInMillis(dt.getMillis());
  61. 10. Calendar c2 = dt.toCalendar(Locale.getDefault());
  62.  
  63. 5、日期前后推算
  64.  
  65. 1. DateTime dt = new DateTime();
  66. 2.
  67. 3. //昨天
  68. 4. DateTime yesterday = dt.minusDays(1);
  69. 5. //明天
  70. 6. DateTime tomorrow = dt.plusDays(1);
  71. 7. //1个月前
  72. 8. DateTime before1month = dt.minusMonths(1);
  73. 9. //3个月后
  74. 10. DateTime after3month = dt.plusMonths(3);
  75. 11. //2年前
  76. 12. DateTime before2year = dt.minusYears(2);
  77. 13. //5年后
  78. 14. DateTime after5year = dt.plusYears(5);
  79.  
  80. 6、取特殊日期
  81.  
  82. 1. DateTime dt = new DateTime();
  83. 2.
  84. 3. //月末日期
  85. 4. DateTime lastday = dt.dayOfMonth().withMaximumValue();
  86. 5.
  87. 6. //90天后那周的周一
  88. 7. DateTime firstday = dt.plusDays(90).dayOfWeek().withMinimumValue();
  89.  
  90. 7、时区
  91.  
  92. 1. //默认设置为日本时间
  93. 2. DateTimeZone.setDefault(DateTimeZone.forID("Asia/Tokyo"));
  94. 3. DateTime dt1 = new DateTime();
  95. 4.
  96. 5. //伦敦时间
  97. 6. DateTime dt2 = new DateTime(DateTimeZone.forID("Europe/London"));
  98.  
  99. 8、计算区间
  100.  
  101. 1. DateTime begin = new DateTime("2012-02-01");
  102. 2. DateTime end = new DateTime("2012-05-01");
  103. 3.
  104. 4. //计算区间毫秒数
  105. 5. Duration d = new Duration(begin, end);
  106. 6. long time = d.getMillis();
  107. 7.
  108. 8. //计算区间天数
  109. 9. Period p = new Period(begin, end, PeriodType.days());
  110. 10. int days = p.getDays();
  111. 11.
  112. 12. //计算特定日期是否在该区间内
  113. 13. Interval i = new Interval(begin, end);
  114. 14. boolean contained = i.contains(new DateTime("2012-03-01"));
  115.  
  116. 9、日期比较
  117.  
  118. 1. DateTime d1 = new DateTime("2012-02-01");
  119. 2. DateTime d2 = new DateTime("2012-05-01");
  120. 3.
  121. 4. //和系统时间比
  122. 5. boolean b1 = d1.isAfterNow();
  123. 6. boolean b2 = d1.isBeforeNow();
  124. 7. boolean b3 = d1.isEqualNow();
  125. 8.
  126. 9. //和其他日期比
  127. 10. boolean f1 = d1.isAfter(d2);
  128. 11. boolean f2 = d1.isBefore(d2);
  129. 12. boolean f3 = d1.isEqual(d2);
  130.  
  131. 10、格式化输出
  132.  
  133. 1. DateTime dateTime = new DateTime();
  134. 2.
  135. 3. String s1 = dateTime.toString("yyyy/MM/dd hh:mm:ss.SSSa");
  136. 4. String s2 = dateTime.toString("yyyy-MM-dd HH:mm:ss");
  137. 5. String s3 = dateTime.toString("EEEE dd MMMM, yyyy HH:mm:ssa");
  138. 6. String s4 = dateTime.toString("yyyy/MM/dd HH:mm ZZZZ");
  139. 7. String s5 = dateTime.toString("yyyy/MM/dd HH:mm Z");

 

案例:

  1. public static DateTime getNowWeekMonday() {
  2. DateTime date = DateTime.now();
  3. int dayOfWeek = date.getDayOfWeek();
  4. return DateTime.parse(date.minusDays(dayOfWeek - 1).toString("yyyy-MM-dd"));
  5. }
  1. private static final String DATE_FORMAT = "yyyy-MM-dd";
  2.  
  3. //每周一0点0分0秒触发,处理上上周
  4. @Scheduled(cron = "0 0 0 ? * MON ")
  5. public void weeklyRemind() {
  6. logger.info("CyclePendingReminderTask.weeklyRemind");
  7. logger.info("周期性待处理提醒任务开始");
  8. String now = DateTime.now().toString(DATE_FORMAT);
  9. //往前推2周,上上周周一
  10. String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  11. .minusWeeks(2).toString(DATE_FORMAT);
  12. //上上周周日
  13. String to = DateTime.parse(from, ISODateTimeFormat.dateElementParser())
  14. .plusWeeks(1).minusDays(1).toString(DATE_FORMAT);
  15. //上上周周一0点时间戳
  16. long fromTime = DateTime.parse(from, ISODateTimeFormat.dateElementParser()).getMillis();
  17. //上周周一0点时间戳
  18. long toTime = DateTime.parse(to, ISODateTimeFormat.dateElementParser()).plus(1).getMillis();
  19. List<String> userIdList = ideaService.getUserIdList();
  20. for (String userId : userIdList) {
  21. List<Idea> ideaList = ideaService.findIdeasByCreateAt(userId, fromTime, toTime);
  22. //有创建想法才会有提醒
  23. if (ideaList.size() > 0) {
  24. CyclePendingIdeaReminder reminder = new CyclePendingIdeaReminder();
  25. reminder.setUserId(userId);
  26. reminder.setFrom(from);
  27. reminder.setTo(to);
  28. reminder.setFinished(false);
  29. cpiReminderService.save(reminder);
  30. }
  31. }
  32. logger.info("周期性待处理提醒任务完成");
  33. }
  1. //每月一号0点0分0秒触发
  2. //当中再判断当前月份进行季度和年度的处理操作
  3. @Scheduled(cron = "0 0 0 1 * ? ")
  4. public void monthlySelectionRemind() {
  5. logger.info("IdeaSelectionReminderTask monthlySelectionRemind start.");
  6. DateTime nowTime = DateTime.now();
  7. int month = nowTime.getMonthOfYear();
  8. String now = nowTime.toString(DATE_FORMAT);
  9. //年度处理: 1
  10. if (month == 1) {
  11. logger.info("年度精选任务开始");
  12. String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  13. .minusYears(1).toString(DATE_FORMAT);
  14. String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  15. .minusDays(1).toString(DATE_FORMAT);
  16. doMonthly(from, to, OriginalityType.year);
  17. logger.info("年度精选任务完成");
  18. }
  19. //季度处理: 3(4) 6(7) 9(10) 12(1)
  20. if (month == 4 || month == 7 || month == 10 || month == 1) {
  21. logger.info("季度精选任务开始");
  22. String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  23. .minusMonths(3).toString(DATE_FORMAT);
  24. String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  25. .minusDays(1).toString(DATE_FORMAT);
  26. doMonthly(from, to, OriginalityType.quarter);
  27. logger.info("季度精选任务完成");
  28. }
  29. //月份处理
  30. logger.info("月精选任务开始");
  31. String from = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  32. .minusMonths(1).toString(DATE_FORMAT);
  33. String to = DateTime.parse(now, ISODateTimeFormat.dateElementParser())
  34. .minusDays(1).toString(DATE_FORMAT);
  35. doMonthly(from, to, OriginalityType.month);
  36. logger.info("月精选任务完成");
  37. logger.info("IdeaSelectionReminderTask monthlySelectionRemind finish.");
  38. }
  1. // 今日凌晨
  2. Date date = DateTime.parse(DateTime.now().toString("yyyy-MM-dd")).toDate()
  1. // 今天9点对应的日期
  2. Date date = DateTime.parse(DateTime.now().toString("yyyy-MM-dd")).hourOfDay().addToCopy(9).toDate();
  1. // 当前时间加1分钟
  2. Date date = DateTime.now().minuteOfHour().addToCopy(1)).toDate()

Joda-Time 学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  10. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

随机推荐

  1. Android-Java卖票案例-推荐此方式Runnable

    上一篇博客 Android-卖票案例static-不推荐此方式,讲解了卖票案例是 private static int ticket = 10;,static静态的这种方式来解决卖票多卖30张的问题, ...

  2. JavaScript中Ajax的使用

    AJAX全称为“Asynchronous javascript and XML”(异步javascript和XML),是指一种创建交互式网页应用的网页开发技术.通过在后台与服务器进行少量数据交换,AJ ...

  3. 利用backtrace和backtrace_symbols函数打印调用栈信息

    在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h>  int backtrace(void * ...

  4. 数据库选项--ALTER DATABASE WITH 选项

    指定当数据库从一种状态转换到另一种状态时,何时回滚未完成的事务. 如果终止子句被忽略,则当数据库中存在任何锁时,ALTER DATABASE 语句将无限期等待. 只能指定一条终止子句,而且该子句应跟在 ...

  5. jvm linux 时区设置

    # 背景 在接入集团一个平台的时候,发现录制某个接口到测试环境回放,发现接口入参一致,一个start_day 一个end_day,但回放的时候会多调用一次数据库查询,很是奇怪: 查阅业务代码,发现确实 ...

  6. C#数组的定义,不定长的数组?

    首先,在这里我要说明的是,C#中,定义了数组,那么就必须为其指定长度,且他的长度确定,不能够更改.一旦定义一个数组,那么操作系统就在内存中给这个数组指定了一块内存,他是不支持动态分配存储空间的.能够动 ...

  7. 浏览器对HTTP请求的编码行为

    浏览器对请求的URL编码行为 浏览器会对请求的URL中非ASCII码字符进行编码.这里不是指对整个URL进行编码,而是仅仅对非ASCII码字符部分进行编码,详情请看下面的实验记录. 实验一:在URL参 ...

  8. 在QT中用git做版本管理时遇到的一些问题

    1. 安装git sudo apt-get install git 2. 安装gitk sudo apt-get install gitk 要提交代码,点击  工具->git->local ...

  9. 配置阿里yum源,设置命令

    配置阿里yum源 #linux的软件包管理 安装 软件的方式有三种 .源代码编译安装() .下载python3的源代码 .解压缩源代码 .进入源代码目录,开始编译安装 .配置环境变量 .yum方式安装 ...

  10. “全栈2019”Java多线程第十八章:同步代码块双重判断详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...