最近做过这样一个题目:
对电话账单来说,春季和秋季的标准时间与夏时制时间的转换会带来有意思的问题。春季,这种转换发生在(3 月末,4 月初的)星期日凌晨 2:00 时,这时时钟要设置为凌晨 3: 00 时。对称的转换通常发生在 10 月最后一个星期日,时钟要从 2:59:59 调回到 2:00:00。
请为采用以下费率计算用户的每月通话费:
(1)通话时间<=20 分钟时,每分钟收费 0.05 美元,通话时间不到 1 分钟时按 1 分钟计算。
(2)通话时间>20 分钟时,收费 1.00 美元,外加每分钟 0.10 美元,超过 20 分钟的部分,不到 1 分钟时按 1 分钟计算。假设:
(1)通话计费时间从被叫方应答开始计算,到呼叫方挂机时结束。
(2)通话时间的秒数四舍五入到分钟。
(3)没有超过 20 个小时的通话。
这道题中,通话在发生时制转换的那一天的情况是比较复杂的,下面是本人自己写的程序:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class HoldingTime {
private String startingTime;
private String endingTime;
private long minute;//通话时长
public Date startT;
public Date endT;
public HoldingTime(String startingTime,String endingTime){
this.startingTime = startingTime;
this.endingTime = endingTime;
this.startT = StrToDate(this.startingTime);
this.endT = StrToDate(this.endingTime);
}
public Date StrToDate(String str) {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = null;
try {
date = format.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public String DateFormate(Date date){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
String sdate = format.format(date);
return sdate;
}
public long getHoldingTime(){
long between;
Calendar cal1 = Calendar.getInstance();
cal1.setTime(startT);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(endT);
between = cal2.getTime().getTime()-cal1.getTime().getTime();
if(between<0)
minute =( (cal2.getTime().getTime()-cal1.getTime().getTime())/1000)/60;//得到通话时长
else
minute = (between/1000+59)/60;
//判断接通时间是否在发生转换的日期
if((cal1.get(Calendar.MONTH) ==Calendar.MARCH && cal1.get(Calendar.DATE) >= 29 && cal1.get(Calendar.DATE) <= 31 && cal1.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)
|| ((cal1.get(Calendar.MONTH) ==Calendar.APRIL && cal1.get(Calendar.DATE) >= 1 && cal1.get(Calendar.DATE) <= 4 && cal1.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)))
{
System.out.println("需要转换1");
if(cal1.get(Calendar.HOUR_OF_DAY)<2 && cal2.get(Calendar.HOUR_OF_DAY)>=3)
minute -=60;//时间从2点转换到3点减去1h
}else{
if((cal2.get(Calendar.MONTH) ==3 && cal2.get(Calendar.DATE) >= 29 && cal2.get(Calendar.DATE) <= 31 && cal2.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)
|| ((cal2.get(Calendar.MONTH) ==4 && cal2.get(Calendar.DATE) >= 1 && cal2.get(Calendar.DATE) <= 4 && cal2.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)))
//判断结束时间是否在转换的日期
{
if(cal2.get(Calendar.HOUR_OF_DAY)>3 )
minute -=60;
}
}
//将位于转换的时间段内的时间都看作已经转换之后的
if(cal1.get(Calendar.MONTH) ==Calendar.OCTOBER && cal1.get(Calendar.DATE) >= 25 && cal1.get(Calendar.DATE) <= 31 && cal1.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)
{
if(cal1.get(Calendar.HOUR_OF_DAY) ==2){
minute +=60;
}
}else{
if(cal2.get(Calendar.MONTH) ==Calendar.OCTOBER && cal2.get(Calendar.DATE) >= 25 && cal2.get(Calendar.DATE) <= 31 && cal2.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY)
{
if(cal2.get(Calendar.HOUR_OF_DAY)==2)
{
minute +=60;
}
}
}
if(minute>1200 || minute <0){
System.out.println("时间错误,时限范围不对!");
return 0;
}else{
//System.out.println("间隔正确");
return minute;
}
}
}
这段代码是判断时间并且返回通话时长的
-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
public class TelFee {
public static void main(String[] args) {
double telFee;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//字符输入流
try {
System.out.println("请输入起始时间(如20170102030405):");
String sd1=br.readLine();//按行读入
System.out.println("请输入截止时间(如20170102030405):");
String sd2=br.readLine();
HoldingTime ht = new HoldingTime(sd1,sd2);
System.out.println("电话接通时间:"+ht.DateFormate(ht.startT));
System.out.println("电话结束时间:"+ht.DateFormate(ht.endT));
DecimalFormat df = new DecimalFormat("######0.00");
long minute = ht.getHoldingTime();
//计算话费
if(minute <= 20){
telFee = 0.05*minute;
}else{
telFee = 1.00 + (minute - 20)*0.1;
}
System.out.println("通话时间为:"+minute+"分钟");
System.out.println("本次通话话费为:"+df.format(telFee)+"美元");
}catch (IOException e) {
e.printStackTrace();
}
}
}
这段则是相应的输入输出代码。
做这道题的时候调用了Calendar类的一些方法,相较于Date类来说,个人觉得Calendar类使用起来更加的方便。