最近在学习 Java,并且公司一部分服务已经在从 Ruby 向 Java 做迁移,自己对 Java 及 Ruby 的时间相关的格式化及一些用法做了一些总结。
Java
LocalDate 用于表示当天日期,与 java.util.Date 不同,只有日期,不包含时间。
LocalDate now = LocalDate.now();
System.out.println(now);
输出:
2018-06-20
Ruby
[8] pry(main)> Date.today
=> Fri, 29 Jun 2018
[9] pry(main)> Date.today.to_s
=> "2018-06-29"
Java
LocalDate 提供了年/月/日的快捷方法,不需要再以来 java.util.Calendar 类了。
LocalDate now = LocalDate.now();
int year = now.getYear();
int monthValue = now.getMonthValue();
int dayOfMonth = now.getDayOfMonth();
System.out.printf("year = %d, month = %d, day = %d", year, monthValue, dayOfMonth);
输出:
year = 2018, month = 6, day = 29
Ruby
[1] pry(main)> Date.today.year
=> 2018
[2] pry(main)> Date.today.month
=> 6
[3] pry(main)> Date.today.day
=> 29
Java
可以调用另一个有用的工厂方法 LocalDate.of() 创建任意日期,该方法需要传入年、月、日做参数,返回对应的 LocalDate 实例。
LocalDate date = LocalDate.of(2018, 06, 29);
System.out.println(date);
输出:
2018-06-29
Ruby
[5] pry(main)> Date.new(2018, 06, 29)
=> Fri, 29 Jun 2018
Java
Java 8 提供了 equals 方法来判断是否是否相等,LocalDate 重载了 equals 方法
LocalDate now = LocalDate.now();
LocalDate date = LocalDate.of(2018, 06, 29);
if (date.equals(now)) {
System.out.println("同一天");
}
输出:
同一天
Ruby
[10] pry(main)> date = Date.new(2018, 06, 29)
=> Fri, 29 Jun 2018
[11] pry(main)> date == Date.today
=> true
Java
Java 8 中有一个类来检查每月账单/生日/结婚纪念日这些周期性事件=>MonthDay 类,这个类组合了月份和日,去掉了年,与此类似还有一个 YearMonth 类。
LocalDate now = LocalDate.now();
LocalDate dateOfBirth = LocalDate.of(2018, 06, 29);
MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(now);
if (currentMonthDay.equals(birthday)) {
System.out.println("Happy Birthday");
} else {
System.out.println("Sorry, today is not your birthday");
}
输出:
Happy Birthday
Ruby
[20] pry(main)> Date.today
=> Fri, 29 Jun 2018
[21] pry(main)> now = Date.today
=> Fri, 29 Jun 2018
[22] pry(main)> date_of_birth = Date.new(2018, 06, 29)
=> Fri, 29 Jun 2018
[23] pry(main)> birth_month, birth_day = date_of_birth.month, date_of_birth.day
=> [6, 29]
[24] pry(main)> current_month, current_day = now.month, now.day
=> [6, 29]
[25] pry(main)> if (current_month == birth_month && birth_day == current_day)
[25] pry(main)* p "Happy Birthday"
[25] pry(main)* else
[25] pry(main)* p "Sorry, today is not your birthday"
[25] pry(main)* end
"Happy Birthday"
=> "Happy Birthday"
Java
Java 8 中获取时间使用的是 LocalTime 类,可以调用静态工厂方法 now() 来获取当前时间,默认格式是“hh:mm:ss:nnn”
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
输出:
13:35:56.155
Ruby
[36] pry(main)> Time.now.strftime("%H:%M:%S.%L")
=> "17:20:36.447"
Java
通过增加小时、分、秒来计算将来的时间很常见。Java 8 除了不变类型和线程安全的好处之外,还提供了更好的 plusHours() 方法替换 add(),并且是兼容的。注意,这些方法返回一个全新的 LocalTime 实例,由于其不可变性,返回后一定要用变量赋值。
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
LocalTime localTime1 = localTime.plusHours(2);//增加2小时
System.out.println(localTime1);
输出:
17:28:22.812
19:28:22.812
增加一周,LocalDate 的日期不包含时间信息,它的 plus() 方法用来增加天/周/月
LocalDate now = LocalDate.now();
LocalDate plusDate = now.plus(1, ChronoUnit.WEEKS);
System.out.println(now);
System.out.println(plusDate);
输出:
2018-06-29
2018-07-06
LocalDate now = LocalDate.now();
LocalDate minusDate = now.minus(1, ChronoUnit.YEARS);
LocalDate plusDate1 = now.plus(1, ChronoUnit.YEARS);
System.out.println(minusDate);
System.out.println(plusDate1);
输出:
2017-06-29
2019-06-29
Ruby
增加 2 小时/增加一周/增加一年/减少一年
[41] pry(main)> DateTime.now
=> Fri, 29 Jun 2018 17:57:25 +0800
[42] pry(main)> DateTime.now + 2.hours
=> Fri, 29 Jun 2018 19:57:31 +0800
[44] pry(main)> DateTime.now + 1.weeks
=> Fri, 06 Jul 2018 17:57:48 +0800
[45] pry(main)> DateTime.now + 1.year
=> Sat, 29 Jun 2019 17:57:53 +0800
[46] pry(main)> DateTime.now - 1.year
=> Thu, 29 Jun 2017 17:58:00 +0800
Java
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
输出:
1530267881396
1530267881
Ruby
[49] pry(main)> DateTime.now.strftime('%s')
=> "1530267924"
[50] pry(main)> DateTime.now.strftime('%Q')
=> "1530267928882"
Java
LocalDateTime arrivalDate = LocalDateTime.now();
try {
DateTimeFormatter format = DateTimeFormatter.ofPattern("MMMdd yyyy hh:mm a");
String landing = arrivalDate.format(format);
System.out.printf("Arriving at : %s %n", landing);
}catch (DateTimeException ex) {
System.out.printf("%s can't be formatted!%n", arrivalDate);
ex.printStackTrace();
}
输出:
Arriving at : 六月30 2018 09:12 下午
Ruby
[51] pry(main)> DateTime.now.to_s
=> "2018-06-30T21:15:41+08:00"
另外在 Rails 可以在 config/initializers 定义 time_formats.rb 文件,然后在整个 Rails 项目中都可以使用类似 DateTime.now.to_s(:ll) 这样的写法来格式化输出时间
# time_formats.rb
Time::DATE_FORMATS[:od] = "%Y-%m-%d"
Time::DATE_FORMATS[:odb] = "%Y-%m-%d"
Time::DATE_FORMATS[:ss] = "%Y-%m-%d %k:%M "
Time::DATE_FORMATS[:ll] = "%Y-%m-%d %H:%M:%S"
Time::DATE_FORMATS[:lll] = "%Y-%m-%d %H:%M:%S.%L"
Time::DATE_FORMATS[:ot] = "%H:%M "
Time::DATE_FORMATS[:lt] = "%H:%M:%S "
Time::DATE_FORMATS[:month_and_year] = "%B %Y"
Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
Time::DATE_FORMATS[:md] = "%m-%d"
Time::DATE_FORMATS[:ww] = "%Y-%m-%d (%A)" # day with week day
Time::DATE_FORMATS[:year_month] = "%Y-%m"
Time::DATE_FORMATS[:ms] = lambda{|time| time.to_datetime.strftime "%Q" }
通过这些例子,你肯定已经掌握了 Java 8 日期时间 API 的新知识点。现在来回顾一下这个优雅 API 的使用要点:
关于 java 的部分参考了:http://www.54tianzhisheng.cn/2018/06/20/java-8-date/