日期和时间

1、日期和时间表示

    Date是老的用于处理日期和时间的类,现在只建议对其进行时间戳转换的使用:

import java.util.Calendar;
import java.util.Date;

public class Test
{
	public static void main(String[] args)
		throws Exception
	{	
		Date date1 = new Date(); //获得当前日期时间
        long times = System.currentTimeMillis(); //获得当前毫秒级别的unix时间戳
        long l = date1.getTime(); //获得对应的毫秒级的unix时间戳
		Date date2 = new Date(times); //传入一个毫秒级的unix时间戳
	}
}

  TimeZone表示时区:

import java.util.*;

public class Test
{	
	public static void main(String[] args)
	{		
		//
		TimeZone zone = TimeZone.getDefault(); //获得当前默认时区
		String str = zone.getDisplayName(); //"中国标准时间"
		str = zone.getID(); //"Asia/Shanghai"
		int dst = zone.getDSTSavings(); //夏令时数:0
		
		TimeZone zone2 = TimeZone.getTimeZone("Asia/Taipei"); //获得台湾时区
		String[] ary = TimeZone.getAvailableIDs(); //获得所有时区的ID
	}
}

  LocalDateTime、Instant等是新的处理时间的类,它们是线程安全的,推荐使用。对于LocalDateTime,如果设定了不存在的日期,如LocalDateTime.of(2018, 2, 29, 12, 3, 3)会抛出DateTimeException,因为2018年不是闰年,所以对于用户设置日期的功能,为了避免用户设定不存咋的时间,我们应该提供一个日期时间选择器(Date Time Picker)组件,而不是直接让用户输入时间。

import java.time.*;
import java.time.temporal.ChronoField;

public class Test
{	
	public static void main(String[] args)
	{		
		//LocalDateTime:表示本地日期时间
		LocalDateTime dt = LocalDateTime.now(); //获得本机当前日期时间
		String str = "" + dt; //2018-06-14T10:47:56.231352700

        long d = dt.getYear(); //获得年,同 lldd1.getLong(ChronoField.YEAR);
		d = dt.getMonthValue(); //12, 获得月份,同 lldd1.getLong(ChronoField.MONTH_OF_YEAR);
		d = dt.getDayOfMonth(); //获得日,同lldd1.getLong(ChronoField.DAY_OF_MONTH)
		d = dt.getDayOfWeek().getValue(); //获得星期几,同 lldd1.getLong(ChronoField.DAY_OF_WEEK);
		d = dt.getDayOfYear(); //获得一年中的第几天,同lldd1.getLong(ChronoField.DAY_OF_YEAR)
		
		LocalDateTime dt2 = dt.plusDays(5)
                              .plusHours(3)
                              .plusMinutes(10); //增加5天3小时10分钟
		
		d = dt2.getLong(ChronoField.EPOCH_DAY/*1970到现在的天数*/) - dt.getLong(ChronoField.EPOCH_DAY); //5
		long h = dt2.getLong(ChronoField.HOUR_OF_DAY/*0-23*/) - dt.getLong(ChronoField.HOUR_OF_DAY); //3
		long m = dt2.getLong(ChronoField.MINUTE_OF_HOUR/*0-59*/) - dt.getLong(ChronoField.MINUTE_OF_HOUR); //10
		long seconds = dt2.toInstant(ZoneOffset.of("+8")).getEpochSecond() - 
						dt.toInstant(ZoneOffset.of("+8")).getEpochSecond(); //dt2和dt1总共相差的秒数
        
        //LocalDateTime	LocalDateTime::plus​(long amountToAdd, TemporalUnit unit)
		//ChronoUnit是TemporalUnit接口的实现类,并且是一个Enum枚举类
		LocalDateTime lldd2 = LocalDateTime.of(1999, 10, 1, 8, 5, 20).plus(5, ChronoUnit.DAYS) //增加5天
											   .plus(1, ChronoUnit.MONTHS); //增加1个月
		
		LocalDateTime dt3 = LocalDateTime.of(2020, 2, 1, 13, 35, 10); //2020年2月1号13点35分10秒
        str = "" + dt; //2020-02-1T13:35:10
		int hour = dt3.getHour(); //13
		LocalDateTime dt4 = dt3.withDayOfMonth(2); //获得一个新的日期时间,重新设置了日,2020年2月2号13点35分10秒
		int nDays = dt4.getDayOfYear(); // 33
		
		long second = dt3.toEpochSecond(ZoneOffset.of("+8")); //LocalDateTime转时间戳(秒)
		long milliSecond = dt3.toInstant(ZoneOffset.of("+8")).toEpochMilli(); //LocalDateTime转时间戳(毫秒)
		LocalDateTime ldt = LocalDateTime.ofEpochSecond(second/*秒*/, 500 * 1000 * 1000/*纳秒*/, ZoneOffset.of("+8")); //时间戳(秒+纳秒)转LocalDateTime
		System.out.println("" + ldt); //2020-12-11T13:24:17.500
		

		//获得本机当前毫秒级别的unix时间戳
		long ti = System.currentTimeMillis();


        //LocalDate:表示本地日期
		LocalDate ld = LocalDate.now(); //获取当前日期
		str = "" + ld; //2018-06-14
		LocalDate ld3 = LocalDate.of(2014, Month.MAY, 21); //设为2014年5月21号
		LocalDate ld2 = LocalDate.ofYearDay(2014, 146); //获取2014年的第146天
		
		
		//LocalTime:表示本地时间
		LocalTime lt = LocalTime.now(); //获取当前时间
		str = "" + lt; //10:43:29.463094400
		lt = LocalTime.of(10, 30); //设为10点30分
		lt = LocalTime.ofSecondOfDay(5000); //获得一天中的第5000秒的时间
		
		LocalDateTime localDT = LocalDateTime.of(ld, lt);
}
import java.time.*;
import java.time.temporal.ChronoField;

public class Test
{	
	public static void main(String[] args)
	{		
		//Instant:表示一个UTC时间
		Instant it = Instant.now(); //获得的是当前UTC时间而不是本地时间 
		String str = "" + it; //2020-12-10T08:49:14.112409200Z
		
		Instant it2 = Instant.parse("2014-02-23T13:12:35.341Z");
		str = "" + it2; //2014-02-23T13:12:35.341Z

		long tim = it2.getEpochSecond(); //Instant转时间戳,这里的时间戳加了8小时,也就是是本地时间2014-02-23 21:12:35.341对应的时间戳,如下所示:
		LocalDateTime dt = LocalDateTime.ofEpochSecond(tim, 0, ZoneOffset.of("+8"));
		str = "" + dt; //2014-02-23T21:12:35
		Instant inst = Instant.ofEpochSecond(tim); //时间戳转Instant,这里的时间戳使用了上面本地时间对应的时间戳,但转成Instant的话还是原来的UTC时间,所下所示:
		str = "" + inst; //2014-02-23T13:12:35Z
		
		ZonedDateTime zdt = it2.atZone(ZoneId.systemDefault()); //Instant转换为本地时间ZonedDateTime
		str = "" + zdt; //2014-02-23T21:12:35.341+08:00[Asia/Shanghai]
		
		LocalDateTime localDT = LocalDateTime.now();
		Instant ins = localDT.toInstant(ZoneOffset.of("+8")); //LocalDateTime转Instant
		LocalDateTime localNewDT = LocalDateTime.ofInstant(ins, ZoneId.of("+8")); //Instant转LocalDateTime
	}
}
import java.time.*;

public class Test
{	
	public static void main(String[] args)
	{		
		//YearMonth、MonthDay、Year分别表示年月、月日、年、月
		Year year = Year.now(); //获取当前年份
		String str = "" + year; //2018
		year = year.plusYears(10); //年份再加上10年
		
		YearMonth ym = year.atMonth(10); //月份设为10月
		ym = ym.plusYears(2).plusMonths(5); //加上2年5个月
        YearMonth ym1 = YearMonth.now();
		System.out.println(ym1); // 2020-12
		YearMonth ym2 = ym1.plus(1, ChronoUnit.MONTHS);
		System.out.println("" + ym2); // 2021-01
		
        //MonthDay不存在plus()、minus()方法(只实现了TemporalAccessor,plus()、minus()是TemporalAccessor的子接口Temporal上的方法),因为MonthDay不存在年的信息,如果是2月28号再加1天的话不确定是2月29还是3月1日
		MonthDay md = MonthDay.now(); //获取当前月日
		str = "" + md; //--06-14
		md.with(Month.MAY).withDayOfMonth(23); //设为5月23日

        for(Month month : Month.values())
		{
			System.out.printf("%d\t%s, ", month.getValue(), month);
			//输出为 1	JANUARY, 2	FEBRUARY, 3	MARCH, ...
		}
		
		
		//Clock:获取指定时区的现在时间
		Clock clock = Clock.systemUTC(); //获得UTC时间
		System.out.println("" + clock); // SystemClock[Z]
		Clock clo = Clock.systemDefaultZone();
		System.out.println("" + clo); // SystemClock[Asia/Shanghai]


        //Duration:表示一段时间
		Duration du = Duration.ofSeconds(7200); //7200秒的时间段
		long l = du.toMinutes(); //120,7200秒是120分钟
		long h = du.toHours(); //2,7200秒是2小时
		Clock clock2 = Clock.offset(clock, du); //在clock的基础上增加7200秒
		
		
		//Period表示日期间隔,如果想要表示比日更小的单位应该使用Duration
		LocalDate ld1 = LocalDate.of(1975, 5, 25).plus(Period.ofDays(5)) //加5天
								 				.plus(Period.ofMonths(1)); //加1个月
		LocalDate ld2 = LocalDate.now();
		Period per = Period.between(ld1, ld2); //两个日期的间隔值
		int y = per.getYears();
		int m = per.getMonths();
		int d = per.getDays();
		System.out.printf("两个日期相差了%d年 %d个月, %d天", y, m, d); //两个日期相差了45年 5个月, 11天
		
	}
}

  Calendar是一个抽象日历类,GregorianCalendar是其子类,表示公历,也可以通过实现Calendar来实现其它的历法,如农历(网上有对农历的实现)。

import java.util.Calendar;
import java.util.Date;

public class Test
{	
	public static void main(String[] args)
	{		
		Calendar calendar1 = Calendar.getInstance(); //使用默认的TimeZone和Locale获取GregorianCalendar对象
        //Calendar calendar2 = Calendar.getInstance(TimeZone.getTimeZone("Europe/Copenhagen")); //获得哥本哈根的日历对象
		Date date = calendar1.getTime(); //通过Calendar获得Date
		
		Calendar calendar2 = Calendar.getInstance(); 
		calendar2.setTime(date); //通过Date设置Calendar
		
		boolean b = calendar2.after(calendar1); //判断日期前后
		
		Calendar calendar3 = Calendar.getInstance(); 
		calendar3.set(2000, 10, 1, 10, 0, 0); //设置年月日时分秒
		int day = calendar1.get(Calendar.DATE);  //获得日,从1开始
		calendar1.add(Calendar.DATE, 1); //日加1,如果超过日期的最大会自动进位,如果不想进位的话使用roll()
        calendar1.add(calendar.MONTH, 1); //月加1
		calendar1.set(Calendar.MONTH, 11); //设置月份为12,月份从0开始,设置的数字超过范围的话会向前进位,不想自动进位的话调用setLenient()进行设置
		
		//Calendar的set()具有延时性,直到再次调用get()或add()等方法的时候才会重新设置当前的时间
		Calendar calendar4 = Calendar.getInstance(); 
		calendar4.set(2000, 4, 31);
		calendar4.set(Calendar.MONTH, 8); //设置月份为9,但9月31号不存在,将变为2000-10-1
		calendar4.set(Calendar.DATE, 5);
		Date d = calendar4.getTime(); //2000-9-5

	}
}

  夏令时:

import java.util.*;

public class Test
{	
	public static void main(String[] args)
	{		
		Calendar cal = Calendar.getInstance();
		cal.set(1975, Calendar.MARCH, 31, 23, 59, 59); // 1975年3月31号23点59分59秒
		cal.add(Calendar.SECOND, 1); //增加1秒
		Date d = cal.getTime(); //当前是中国的话是1975年4月1号0点0分0秒,如果当前是实行夏令时的地区的话为1975年4月1号1点0分0秒
	}
}

2、格式化

    DateFormat、SimpleDateFormat是老的用来对日期和时间进行格式化的类:

import java.util.Date;
import java.text.*;

public class Test
{
	public static void main(String[] args)throws ParseException
	{	
		Date dNow = new Date( );
	    SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss:SS");
	    String str = "当前时间为: " + ft.format(dNow); //当前时间为: 2020-09-29 15:25:20:962
		
		String strTime = "2010##三月#21";
		SimpleDateFormat ft2 = new SimpleDateFormat("y##MMM#d");
		Date d = ft2.parse(strTime);
		str = "" + d; // Sun Mar 21 00:00:00 CST 2010
	}
}

     还可以使用printf、String.format()来格式化日期,模式通过"%t"加下面表格的字符来控制:

import java.util.Date;

public class Test
{
	public static void main(String[] args)
		throws Exception
	{	
		LocalDateTime dt = LocalDateTime.now(); 
		String s = String.format("%tF", dt) + " " + String.format("%tT", dt);
		System.out.println(s); //2020-12-11 14:41:03
	}
}

 java8中增加了功能更强大的DateTimeFormatter类,而且它是线程安全的,推荐使用:

import java.time.*; 
import java.time.format.*;

public class Test
{
	public static void main(String[] args)
	{	
		//格式化字符串
		LocalDateTime date = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 E a HH:mm:ss:SSS");
		String str = date.format(formatter); //等价于formatter.format(date),2018年06月15日 周五 下午 16:31:05:452
		
		//解析字符串
		str = "2014-04-12 01时06分23秒";
		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH时mm分ss秒");
		date = LocalDateTime.parse(str, formatter);
		str = "" + date; //2014-04-12T01:06:23


        //格式化字符串
        String strIns = Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneId.systemDefault())
                .format(DateTimeFormatter.ISO_INSTANT); //"2023-10-30T08:51:09.574Z"

        //解析字符串
        Instant ist = Instant.parse(strIns);
        strIns = "" + ist; //"2023-10-30T08:51:09.574Z"
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值