Java编程——Calendar类学习及相关日期运算

  1. Calendar类是抽象类,且Calendar类的构造方法是protected的,所以无法使用Calendar类的构造方法来创建对象,API中提供了getInstance方法用来创建对象。
    使用Calendar类的static方法getInstance()可以初始化一个日历对象,如:
    Calendar cal = Calendar.getInstance。
  2. Calendar对象可以调用set方法将日历翻到任何一个时间,如:
    public final void set(int year , int month , int date) //设置年、月、日的时间。
    。。。
    不过,注意,月份的起始值是0而不是1,所以cal.set(2016,2,19)代表的时间是2016.3.19。
    3.calendar对象调用方法public int get(int field)可以获取有关年份、月份、小时、星期等信息,注意:参数field的有效值由Calendar的静态常量指定。
    • Calendar.MONTH 获取月份
    • Calendar.YEAR 获取年份
    • Calendar.DAY_OF_MONTH 获取当前日期是该月的第几天
    • Calendar.DAY_OF_YEAR 获取当前日期是该年的第几天
    • Calendar.DAY_OF_WEEK 获取当前日期是一个星期的那一天。cal.get(Calendar.DAY_OF_WEEK)返回一个整数,如果该整数是1表示星期日,2表示星期一。。。如果是7表示星期六
      4.日历对象调用public long getTimeInMills()可以将时间表示为毫秒。通过将两个日历对象x,y调用getTimeInMills()方法转换为毫秒,做差,再转换为天,可以获得x,y两个日期的相差天数。
      example:
      long t1 = x.getTimeInMills();
      long t2 = x.getTimeInMills();
      long sub = (t2-t1)/(24*60*60*1000);//将毫秒转换为天!

Problem Description
给定一个日期,输出这个日期是该年的第几天。

Input
输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input ,另外,可以向你确保所有的输入数据是合
法的。

Output
对于每组输入数据,输出一行,表示该日期是该年的第几天。

Sample Input
1985/1/20
2006/3/12

Sample Output
20
71


import java.util.Calendar;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String date = in.next();
            String[] t = date.split("/");
            //for(String x:t) System.out.println(x);
            Calendar x = Calendar.getInstance();
            x.set(Integer.parseInt(t[0]), Integer.parseInt(t[1])-1, Integer.parseInt(t[2]));
            System.out.println(x.get(Calendar.DAY_OF_YEAR));
        }
    }

}

这道题是C语言的入门题,如果用C或C++来写的话,需要几十行代码,可是如果用Java写:先用正则表达式将日期年月日提取出来,然后定义Calendar对象,在调用get(Calendar.DAY_OF_YEAR)就直接得到了。

Ps:一开始是想通过定义两个Calendar对象(一个xxxx.1.0,一个是输入的)做差来求得天数的,但是总是wa!

// 日期模板(转自浙大ACM)
//日期函数
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
struct Date{
  int year, month, day;
};

//判闰年
inline int leap(int year){
  return (year%4==0&&year%100!=0)||year%400==0;
}

//判合法性
inline int legal(Date a){
  if(a.month<0||a.month>12)
    return 0;
  if(a.month==2)
    return a.day>0 && a.day<=28+leap(a.year);
  return a.day>0 && a.day<=days[a.month-1];
}

//比较日期大小
inline int datecmp(Date a, Date b){
   if(a.year != b.year)
     return a.year - b.year;
   if(a.month != b.month)
     return a.month - b.month;
   return a.day - b.day;
}

//返回指定日期是星期几
int weekday(Date a){
  int tm = a.month>=3 ? (a.month-2) : (a.month+10);
  int ty = a.month>=3 ? a.year : (a.year-1);
  return (ty+ty/4-ty/100+ty/400+(int)(2.6*tm-0.2)+a.day)%7;
}

//日期转天数偏移,直接转换为与公元元年的比较,写成一个函数,两次调用就好了
/*可以用于求两个指定日期之间相差的天数。*/
int date2int(Date a){
  int ret=a.year*365+(a.year-1)/4-(a.year-1)/100+(a.year-1)/400;
  days[1]+=leap(a.year);
  for(int i=0; i<a.month-1; ret+=days[i++]);
  days[1]=28;
  return ret+a.day;
}

//天数偏移转日期
/*
历法上又规定,每400年中只存在97个闰年,这样400年中共有365*400+97=146097天,而地球绕太阳公转400周历时146096天21小时6分40秒,较好的弥补了这一缺陷,这样几乎3300年才产生一天的误差。
*/
Date int2date(int a){
  Date ret;
  //确定年
  ret.year = a/146097*400;//400年共有146097天
  for(a%=146097; a>=365+leap(ret.year); a-=365+leap(ret.year),ret.year++);        
  //确定月
  days[1] += leap(ret.year);
  for(ret.month=1; a>=days[ret.month-1]; a-=days[ret.month-1],ret.month++);
  days[1]=28;
  //确定日
  ret.day=a+1;
  return ret;
}

Amc模板的简洁美观性,没有一点废话,充分利用变量

这是很漂亮的代码,可是用Java写的话,通过调用已有的函数库,可以很方便的实现几个功能,所以把重心放到最后一个上!
要注意ACM模板的整体架构及细节实现:存放12个月的天数的数组是从下标0开始的;闰年的判断是返回0、1值,而不管是否闰年都可以将其加和到days[1]上(注意最后要还原),这是一个小技巧;转换为与公元元年的比较。

/**每400年有97个闰年,*/
//Java伪代码实现最后一个功能!
//天数偏移转日期!
public static Date int2Date(int a){
        Data ret ;
        ret.year = a/(365*400+97);
        for(a%=(365*400+97);a>=leap(ret.year)+365;a-=leap(ret.year)+365,ret.year++);
        days[1]+=leap(ret.year);
        for(ret.month=1;a>=days[ret.month-1];a-=days[ret.month-1],ret.month++);
        days[1]=28;
        ret.day = a+1;
        return ret;

    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值