Java 8中引入了java.time API,不仅弥补了过去Date和Calendar的诸多不足,还修复了很多错误(如时区转换)。现在处理日期和时间就简单得多了。我写了一些常用的处理方法供大家参考,代码如下:
package dateAndTime;
import java.io.File;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
import javax.swing.Timer;
public class TestClass
{
public static void main(String[] args)
{
// 测试某算法所用的时间
Instant start = Instant.now();
testAlgo(); // 开始运行算法
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
System.out.println("Milliseconds: " + timeElapsed.toMillis()); // 输出毫秒时间(long型)
// 你可以新建不存在的时期,但是电脑不会那么傻
//LocalDate aDate = LocalDate.of(1965, 2, 31); // 会抛出异常
LocalDate anotherDate = LocalDate.of(1965, 1, 31).plusMonths(1); // 日期会变成当前年份2月的最后一天,即1965年2月28日
System.out.println(anotherDate.getMonthValue() + " " + anotherDate.getDayOfMonth());
// 计算生日至今的天数
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1903, 6, 14); // 月份可表示为Month.JUNE
System.out.print("Today is " + today.getDayOfWeek()); // 今天(2018年3月1日)是THURSDAY
System.out.println(" and you were born in a " + (birthday.isLeapYear() ? "leap year." : "common year.")); // 判断平闰年
System.out.println("You have been living for " + birthday.until(today, ChronoUnit.DAYS) + " days.");
System.out.println("1000 days later, it will be " + today.plusDays(1000) + "."); // 1000天过后是2020年11月25日
// 处理诸如“某个月的第三个星期二”的日期
int year = 2018, month = 9;
LocalDate thirdTuesday = LocalDate.of(year, month, 1).with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.TUESDAY));
System.out.println(thirdTuesday); // 日期为2018年9月18日
// 自己制作调整器:比如获得下一个工作日的日期(周一至周五)
TemporalAdjuster NEXT_WORKDAY = w -> // w是要被调整的日期;Java 9版本请去掉下划线
{
LocalDate result = (LocalDate) w;
do {
result = result.plusDays(1);
} while(result.getDayOfWeek().getValue() >= 6); // 如果是周六或周日就继续+1天
return result; // 必须返回调整后的日期
};
LocalDate nextWorkday = LocalDate.of(2018, 3, 2).with(NEXT_WORKDAY);
System.out.println(nextWorkday); // 日期为2018年3月5日(周一)
// 不断显示实时时间(本地时间)
Timer t = new Timer(899, event ->
{
System.out.println(LocalTime.now());
});
t.start();
try {Thread.sleep(6000);} catch(InterruptedException e) {e.printStackTrace();}
t.stop();
// 时间间隔的计算
LocalTime rightNow = LocalTime.now();
LocalTime nextDay = LocalTime.of(23, 59, 59);
Duration d = Duration.between(rightNow, nextDay);
System.out.println(d.getSeconds() + 1); // 这样做是因为小时被限制在0-23之间
/*
* 令人头疼的时区计算。中国横跨四个时区但使用同一时间,这让问题简单了许多。然而在其他地方,
* 时区管理很复杂,甚至还有夏令时、冬令时等时间规则。比如:阿波罗11号的发射时间是美国/纽约
* 时间1969年7月16日上午9时32分整(UTC):
*/
ZonedDateTime apolloElevenLaunch = ZonedDateTime.of(1969, 7, 16, 9, 32, 00, 00,
ZoneId.of("America/New_York"));
// 还可以将日期的格式修改为中国使用的格式:
String formatted = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(apolloElevenLaunch);
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
formatted = formatter.withLocale(Locale.CHINA).format(apolloElevenLaunch);
System.out.println(formatted);
// 注意:如果调整日期时跨越了夏令时的边界日期,应该使用Period类
ZonedDateTime fiveMonthsLater = apolloElevenLaunch.plus(Period.ofMonths(5));
System.out.println(fiveMonthsLater); // 将会打印“1969-12-16T09:32-05:00[America/New_York]”
// 更多内容需要参考官方API文档。
}
/**
* 一个瞎编的专门用于浪费时间的算法。
*/
public static void testAlgo()
{
for(int i = 0; i < 558000; i++)
{
if(i % 2 + i / 2 > 400)
if(new File("" + i).exists())
break;
i += 25;
}
}
}
如有错误,以官方API文档为准。