当前位置 : 首页 » 文章分类 :  开发  »  Java-日期

Java-日期

Java 日期时间相关笔记


Java时区设置

TimeZone.setDefault()

System.out.println(TimeZone.getDefault());
final TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone.setDefault(timeZone);

-Duser.timezone=Asia/Shanghai

java 启动脚本中增加 jvm 参数
java -Duser.timezone=Asia/Shanghai
java -Duser.timezone=GMT+08

TZ环境变量

export TZ=Asia/Shanghai


Java8新日期和时间API

Java 8的日期和时间类包含LocalDate、LocalTime、Instant、Duration以及Period,这些类都包含在java.time包中。

Java 8新特性(四):新的时间和日期API
https://lw900925.github.io/java/java8-newtime-api.html

为什么要引入新的日期API?

Java的java.util.Date和java.util.Calendar类易用性差,不支持时区,而且他们都不是线程安全的;

用于格式化日期的类DateFormat被放在java.text包中,它是一个抽象类,所以我们需要实例化一个SimpleDateFormat对象来处理日期格式化,并且DateFormat也是非线程安全,这意味着如果你在多线程程序中调用同一个DateFormat对象,会得到意想不到的结果。

对日期的计算方式繁琐,而且容易出错,因为月份是从0开始的,从Calendar中获取的月份需要加一才能表示当前月份。

由于以上这些问题,出现了一些三方的日期处理框架,例如Joda-Time,date4j等开源项目。


LocalDate

LocalDate 类表示一个具体的日期,但不包含具体时间,也不包含时区信息。可以通过 LocalDate 的静态方法 of() 创建一个实例,LocalDate 也包含一些方法用来获取年份,月份,天,星期几等:

LocalDate localDate = LocalDate.of(2017, 1, 4);     // 初始化一个日期:2017-01-04
int year = localDate.getYear();                     // 年份:2017
Month month = localDate.getMonth();                 // 月份:JANUARY
int dayOfMonth = localDate.getDayOfMonth();         // 月份中的第几天:4
DayOfWeek dayOfWeek = localDate.getDayOfWeek();     // 一周的第几天:WEDNESDAY
int length = localDate.lengthOfMonth();             // 月份的天数:31
boolean leapYear = localDate.isLeapYear();          // 是否为闰年:false

也可以调用静态方法 now() 来获取当前日期:

LocalDate now = LocalDate.now();

LocalTime

LocalTime 包含具体时间

LocalTime localTime = LocalTime.of(17, 23, 52);     // 初始化一个时间:17:23:52
int hour = localTime.getHour();                     // 时:17
int minute = localTime.getMinute();                 // 分:23
int second = localTime.getSecond();                 // 秒:52

LocalDateTime

LocalDateTime 类是 LocalDate 和 LocalTime 的结合体,可以通过 of() 方法直接创建,也可以调用 LocalDate 的 atTime() 方法或 LocalTime 的 atDate() 方法将 LocalDate 或 LocalTime 合并成一个 LocalDateTime:

LocalDateTime ldt1 = LocalDateTime.of(2017, Month.JANUARY, 4, 17, 23, 52);
LocalDate localDate = LocalDate.of(2017, Month.JANUARY, 4);
LocalTime localTime = LocalTime.of(17, 23, 52);
LocalDateTime ldt2 = localDate.atTime(localTime);

Instant

Instant 用于表示一个时间戳,它与我们常使用的 System.currentTimeMillis() 有些类似,不过 Instant 可以精确到纳秒(Nano-Second),System.currentTimeMillis() 方法只精确到毫秒(Milli-Second)。
Instant 除了使用 now() 方法创建外,还可以通过 ofEpochSecond 方法创建:

Instant instant = Instant.ofEpochSecond(120, 100000);

ofEpochSecond() 方法的第一个参数为秒,第二个参数为纳秒,上面的代码表示从1970-01-01 00:00:00开始后两分钟的10万纳秒的时刻

LocalDateTime 转时间戳秒/毫秒

System.out.println("时间戳秒: " + dateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond());
System.out.println("时间戳毫秒: " + dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

或者

//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();

LocalDateTime 和 Date 互相转换

LocalDateTime 和 Date 的互相转换需要通过 Instant 完成。

// LocalDateTime 转 Date
Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

// Date 转 LocalDateTime
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
LocalDateTime localDateTime2 = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

Duration

Duration 的内部实现与 Instant 类似,也是包含两部分:seconds 表示秒,nanos 表示纳秒。两者的区别是 Instant 用于表示一个时间戳(或者说是一个时间点),而 Duration 表示一个时间段,所以 Duration 类中不包含 now() 静态方法。可以通过 Duration.between() 方法创建 Duration 对象:

LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 5, 10, 7, 0);    // 2017-01-05 10:07:00
LocalDateTime to = LocalDateTime.of(2017, Month.FEBRUARY, 5, 10, 7, 0);     // 2017-02-05 10:07:00
Duration duration = Duration.between(from, to);     // 表示从 2017-01-05 10:07:00 到 2017-02-05 10:07:00 这段时间

long days = duration.toDays();              // 这段时间的总天数
long hours = duration.toHours();            // 这段时间的小时数
long minutes = duration.toMinutes();        // 这段时间的分钟数
long seconds = duration.getSeconds();       // 这段时间的秒数
long milliSeconds = duration.toMillis();    // 这段时间的毫秒数
long nanoSeconds = duration.toNanos();      // 这段时间的纳秒数

Duration 对象还可以通过 of() 方法创建,该方法接受一个时间段长度,和一个时间单位作为参数:

Duration duration1 = Duration.of(5, ChronoUnit.DAYS);       // 5天
Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS);  // 1000毫秒

Period

Period 在概念上和 Duration 类似,区别在于 Period 是以年月日来衡量一个时间段,比如2年3个月6天:

Period period = Period.of(2, 3, 6);

Period对象也可以通过between()方法创建,值得注意的是,由于Period是以年月日衡量时间段,所以between()方法只能接收LocalDate类型的参数:

// 2017-01-05 到 2017-02-05 这段时间
Period period = Period.between(
                LocalDate.of(2017, 1, 5),
                LocalDate.of(2017, 2, 5));

ZoneId 时区

新的时区类java.time.ZoneId是原有的java.util.TimeZone类的替代品。ZoneId对象可以通过ZoneId.of()方法创建,也可以通过ZoneId.systemDefault()获取系统默认时区:

ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
ZoneId systemZoneId = ZoneId.systemDefault();

of() 方法接收一个“区域/城市”的字符串作为参数,你可以通过getAvailableZoneIds()方法获取所有合法的“区域/城市”字符串:

Set<String> zoneIds = ZoneId.getAvailableZoneIds();

有了ZoneId,我们就可以将一个LocalDate、LocalTime或LocalDateTime对象转化为ZonedDateTime对象:

LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, shanghaiZoneId);

日期操作

LocalDate date = LocalDate.of(2017, 1, 5);          // 2017-01-05

LocalDate date1 = date.withYear(2016);              // 修改为 2016-01-05
LocalDate date2 = date.withMonth(2);                // 修改为 2017-02-05
LocalDate date3 = date.withDayOfMonth(1);           // 修改为 2017-01-01

LocalDate date4 = date.plusYears(1);                // 增加一年 2018-01-05
LocalDate date5 = date.minusMonths(2);              // 减少两个月 2016-11-05
LocalDate date6 = date.plus(5, ChronoUnit.DAYS);    // 增加5天 2017-01-10

使用 TemporalAdjuster 调整时间

可以使用 with() 方法的另一个重载方法,它接收一个 TemporalAdjuster 参数,可以使我们更加灵活的调整日期:

LocalDate date7 = date.with(nextOrSame(DayOfWeek.SUNDAY));      // 返回下一个距离当前时间最近的星期日
LocalDate date9 = date.with(lastInMonth(DayOfWeek.SATURDAY));   // 返回本月最后一个星期六

1小时前整点

LocalDateTime timeStart = LocalDateTime.now().minusHours(1).withMinute(0).withSecond(0).withNano(0); // 前 1 小时向下取整
LocalDateTime timeEnd = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); // 当前小时向下取整

获取昨天/今天起始时间和结束时间

Java8 LocalDateTime 获取当天和昨天的起始时间和结束时间

LocalDateTime yesterdayStart = LocalDateTime.now().plusDays(-1).with(LocalTime.MIN);// 昨天零点
LocalDateTime yesterdayEnd = LocalDateTime.now().plusDays(-1).with(LocalTime.MAX);// 昨天结束时间
LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);//当天零点
LocalDateTime todayStart2 = LocalDateTime.now().with(LocalTime.MIN);//当天零点
LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);//当天结束时间
LocalDateTime todayEnd2 = LocalDateTime.now().with(LocalTime.MAX);//当天结束时间
System.out.println(yesterdayStart);
System.out.println(yesterdayEnd);
System.out.println(todayStart);
System.out.println(todayStart2);
System.out.println(todayEnd);
System.out.println(todayEnd2);

抹去秒

@Test
public void testCeilFloor() {
    LocalDateTime now = LocalDateTime.now();
    System.out.println("当前时间: " + now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    // 5分钟前向下取整(抹去秒)
    System.out.println("5分钟前抹去秒: " + now.minusMinutes(5).withSecond(0).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    // 当前时间按分钟向下取整(抹去秒)
    System.out.println("当前时间抹去秒: " + now.withSecond(0).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}

DateTimeFormatter 日期时间格式化

新的日期 API 中提供了一个 DateTimeFormatter 类用于处理日期格式化操作,它被包含在 java.time.format 包中,Java 8 的日期类有一个 format() 方法用于将日期格式化为字符串,该方法接收一个 DateTimeFormatter 类型参数:

// 格式化
@Test
public void testFormatter() {
    LocalDateTime dateTime = LocalDateTime.now();
    System.out.println("时间戳秒: " + dateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond());
    System.out.println("时间戳毫秒: " + dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
    System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
    System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE));
    System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME));
    System.out.println(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    System.out.println(dateTime.format(DateTimeFormatter.ofPattern("今天是:yyyy年 MM月 dd日 E", Locale.CHINESE)));
}

结果

时间戳秒: 1587357985
时间戳秒: 1587357985393
20200420
2020-04-20
12:46:25.393
2020-04-20
今天是:2020年 04月 20日 星期一

同样,日期类也支持将一个字符串解析成一个日期对象,例如:

String strDate6 = "2017-01-05";
String strDate7 = "2017-01-05 12:30:05";

LocalDate date = LocalDate.parse(strDate6, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime dateTime1 = LocalDateTime.parse(strDate7, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

Date

java.util.Date
public class Date extends Object implements Serializable, Cloneable, Comparable<Date>
类 Date 表示特定的瞬间,精确到毫秒。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和分析日期字符串。Date 中的把日期解释为年、月、日、小时、分钟和秒值的方法已废弃。

Date() 当前时间

public Date()
构造方法,分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
例如:Date date = new Date(); //以当前的日期和时间作为其初始值

Date(long) 毫秒时间戳指定的时间

public Date(long date)
分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。
参数:date - 自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。


获取当前日期+23:59:59对应的时间

sdf的日志格式字符串中直接写入固定时间即可

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
String s = sdf.format(new Date());
Date date =  sdf.parse(s);

Date去掉时分秒

方法一,用 SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String s = sdf.format(new Date());
Date date =  sdf.parse(s);

或者

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
String s = sdf.format(new Date());
Date date =  sdf.parse(s);

方法二,用 Calendar

Calendar calender = Calendar.getInstance();
calender.setTime(new Date());
// 将时分秒,毫秒域清零
calender.set(Calendar.HOUR_OF_DAY, 0);
calender.set(Calendar.MINUTE, 0);
calender.set(Calendar.SECOND, 0);
calender.set(Calendar.MILLISECOND, 0);
System.out.printf("%1$tF %1$tT\n", calender.getTime());// calender.getTime()返回的Date已经是更新后的对象

java 8:只取年月日的java.util.Date(时分秒清零)对象
https://blog.csdn.net/10km/article/details/53906993


获取当前毫秒时间戳

获取当前时间戳,单位毫秒:

//方法 一
System.currentTimeMillis();
//方法 二
Calendar.getInstance().getTimeInMillis();
//方法 三
new Date().getTime();

其中 Calendar.getInstance().getTimeInMillis() 这种方式速度最慢,这是因为Canlendar要处理时区问题会耗费较多的时间。

注意System.currentTimeMillis()潜在的性能问题

其实 System.currentTimeMillis() 在调用频次高时也会有性能问题,
public static native long currentTimeMillis();
是个 native 方法,调用了 hotspot/src/os/linux/vm/os_linux.cpp 中的 javaTimeMillis() 方法,此方法中
调用gettimeofday()需要从用户态切换到内核态;
1、gettimeofday()的表现受Linux系统的计时器(时钟源)影响,在HPET计时器下性能尤其差;HPET计时器性能较差的原因是会将所有对时间戳的请求串行执行
2、系统只有一个全局时钟源,高并发或频繁访问会造成严重的争用。
3、基于以上几点,所以 System.currentTimeMillis() 在调用频次高时也会有性能问题

解决方法:用一个守护线程专门来获取时间戳并存入内存缓存中

public class CurrentTimeMillisClock {
    private volatile long now;

    private CurrentTimeMillisClock() {
        this.now = System.currentTimeMillis();
        scheduleTick();
    }

    private void scheduleTick() {
        new ScheduledThreadPoolExecutor(1, runnable -> {
            Thread thread = new Thread(runnable, "current-time-millis");
            thread.setDaemon(true);
            return thread;
        }).scheduleAtFixedRate(() -> {
            now = System.currentTimeMillis();
        }, 1, 1, TimeUnit.MILLISECONDS);
    }

    public long now() {
        return now;
    }

    public static CurrentTimeMillisClock getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final CurrentTimeMillisClock INSTANCE = new CurrentTimeMillisClock();
    }
}

使用的时候,直接CurrentTimeMillisClock.getInstance().now()就可以了。不过,在System.currentTimeMillis()的效率没有影响程序整体的效率时,就不必忙着做优化

注意System.currentTimeMillis()潜在的性能问题
https://www.jianshu.com/p/d2039190b1cb


Unix时间戳和Date互相转换

http://www.cnblogs.com/killbug/archive/2013/04/08/3008764.html
时间戳转Date

request.setStartTime(new Date(1530720000 * 1000L));
request.setEndTime(new Date(1531238400L * 1000L));

Date转时间戳

params.put("start_time", (request.getStartTime().getTime() / 1000) + "");
params.put("end_time", (request.getEndTime().getTime() / 1000) + "");

Timestamp 和 Date 互相转换

java.util.Date 和 java.sql.Timestamp 互转

// Timestamp 转 Date
Timestamp ts = new Timestamp(System.currentTimeMillis());
Date date = new Date(ts.getTime());

// Date 转 Timestamp
Timestamp ts = new Timestamp(new Date().getTime());

SimpleDateFormat

java.text.SimpleDateFormat
public class SimpleDateFormat extends DateFormat
SimpleDateFormat 是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期 -> 文本)、分析(文本 -> 日期)和规范化。
SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来新的创建日期-时间格式化程序。

构造方法

public SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。注:此构造方法可能不支持所有语言环境。要覆盖所有语言环境,请使用 DateFormat 类中的工厂方法。

  • 参数:pattern - 描述日期和时间格式的模式
  • 抛出:
    • NullPointerException - 如果给定的模式为 null
    • IllegalArgumentException - 如果给定的模式无效

parse()

Date parse(String text, ParsePosition pos)
解析字符串的文本,生成 Date。 此方法试图解析从 pos 给定的索引处开始的文本。

format()

StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos)
将给定的 Date 格式化为日期/时间字符串,并将结果添加到给定的 StringBuffer。格式为类 DateFormat 中的 format。返回格式化的日期-时间字符串。

Date转String

Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);

String转Date

Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-12-25 19:01:12");

注意 SimpleDateFormat.parse() 方法会抛出 ParseException 受检异常,必须捕获或抛出处理。


SimpleDateFormat与线程安全

如下面代码中,将 SimpleDateFormat 声明为 static ,开多个线程并发去parse日期

package concurrent_test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SimpleDateFormatConcurrentTest {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String format(Date date) {
        return sdf.format(date);
    }

    public static Date parse(String dateStr) throws ParseException {
        return sdf.parse(dateStr);
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i=0; i < 20; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(parse(format(new Date())));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            });
        }
        // 等待线程池中的线程执行完毕
        executorService.shutdown();
        // 阻塞当前线程,等待线程池执行完毕
        executorService.awaitTermination(10, TimeUnit.SECONDS);
    }
}

执行结果如下图,直接异常退出


SimpleDateFormat并发问题

原因:
SimpleDateFormat 以及其实现的抽象类 DateFormat 都是使用了内部的成员变量 protected Calendar calendar; 来做转换,多线程情况下共享 SimpleDateFormat 对象会导致线程间数据互相影响,导致出错。

阿里巴巴Java开发手册中强制禁止将 SimpleDateFormat 定义为static

【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。

解决方法:
1、只在需要的时候创建新实例,不用static修饰

public static String format(Date date) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return sdf.format(date);
}

public static Date parse(String strDate) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return sdf.parse(strDate);
}

不过会 会频繁地创建和销毁对象,效率较低。

2、synchronized对象锁

private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public static String format(Date date) throws ParseException {
    synchronized(sdf){
        return sdf.format(date);
    }
}

public static Date parse(String strDate) throws ParseException {
    synchronized(sdf){
        return sdf.parse(strDate);
    }
}

并发量大的时候会对性能有影响,线程阻塞

3、ThreadLocal线程间隔离

private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
};

public static Date parse(String dateStr) throws ParseException {
    return threadLocal.get().parse(dateStr);
}

public static String format(Date date) {
    return threadLocal.get().format(date);
}

ThreadLocal可以确保每个线程都可以得到单独的一个SimpleDateFormat的对象,那么自然也就不存在竞争问题了。

4、使用Java8的DateTimeFormatter

private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public static String format2(LocalDateTime date) {
    return formatter.format(date);
}

public static LocalDateTime parse2(String dateNow) {
    return LocalDateTime.parse(dateNow, formatter);
}

还在使用SimpleDateFormat?你的项目崩没?


DateTimeFormatter


Calendar

java.util.Calendar
public abstract class Calendar extends Object implements Serializable, Cloneable, Comparable<Calendar>
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:Calendar rightNow = Calendar.getInstance();

字段摘要

int DATE,get 和 set 的字段数字,指示一个月中的某天。它与 DAY_OF_MONTH 是同义词。一个月中第一天的值为 1。

getInstance()

public static Calendar getInstance()
使用默认时区和语言环境获得一个日历对象。返回的 Calendar已初始化为当前日期和时间,使用了默认时区和默认语言环境。
例如:Calendar rightNow = Calendar.getInstance();

setTime()

public final void setTime(Date date)
使用给定的 Date 设置此 Calendar 的时间。

getTime()

public final Date getTime()
返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移量)的 Date 对象。
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

get()

int get(int field)
返回给定日历字段的值。

add()

public abstract void add(int field, int amount)
根据日历的规则,为给定的日历字段添加或减去指定的时间量。
add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:
Add 规则 1:调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
例如,要从当前日历时间减去 5 天,可以通过调用以下方法做到这一点:
add(Calendar.DAY_OF_MONTH, -5);

获取今天前n天的日期

public static Integer getNdaysBeforeNow(int n){
    Calendar cal=Calendar.getInstance();
    cal.add(Calendar.DAY_OF_MONTH, -n);
    SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
    return Integer.parseInt(sdf.format(cal.getTime()));
}

获取指定日期的下一天

输入和输出参数都是Integer

public static Integer getNextDay(Integer datein) {
    String dateinStr = Integer.toString(datein);
    SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
    java.util.Date date=null;
    try {
        date = sdf.parse(dateinStr);
    }catch(java.text.ParseException e) {
        e.printStackTrace();
    }
    Calendar cal=Calendar.getInstance();
    cal.setTime(date);
    cal.add(cal.DATE, 1); //日期加1天
    String dateoutStr = sdf.format(cal.getTime());
    return Integer.valueOf(dateoutStr);
}

上一篇 MyBatis Generator 使用笔记

下一篇 Java-集合框架基础

阅读
评论
4,649
阅读预计21分钟
创建日期 2015-08-18
修改日期 2020-07-26
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论