论坛首页 Java企业应用论坛

好吧,既然写了就发出来——40分钟左右写的“根据currentTimeMillis和数学运算算时间”…………

浏览 17521 次
精华帖 (6) :: 良好帖 (5) :: 新手帖 (12) :: 隐藏帖 (3)
作者 正文
   发表时间:2012-04-24   最后修改:2012-04-25
正巧看到
《关于“难倒一大片人的面试题(根据系统毫秒数计算年月日时分秒,只允许通过四则运算)”被隐藏》

那个“难倒一大片人”比较扎眼,就写了……

不料那个也被投隐藏了(倒霉的娃)~~~既然写了就贴出来吧,不然就真的浪费我的半个多小时了——这个东西真心没用!

public class CalcDateProperties {
	public static void main(String[] args) {
		long timeMillis = System.currentTimeMillis();
		// 请在下面使用四则运算计算出(年、月、日、时、分、秒),不允许使用系统日期类实现
		int timeZone = 8;// 时区

		long totalSeconds = timeMillis / 1000;
		int second = (int) (totalSeconds % 60);// 秒
		long totalMinutes = totalSeconds / 60;
		int minute = (int) (totalMinutes % 60);// 分
		long totalHours = totalMinutes / 60;
		totalHours += timeZone;
		int hour = (int) (totalHours % 24);// 时
		int totalDays = (int) (totalHours / 24);

		int year = 1970;// 年
		int month = 1;// 月
		int day = 1;// 日

		boolean isLeapYear = false;
		while (totalDays > 365) {
			if (year % 100 == 0 && year % 400 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else if (year % 4 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else {
				isLeapYear = false;
				totalDays -= 365;
			}
			year++;
		}

		while (totalDays > 30) {
			switch (month) {
			case 1:
			case 3:
			case 5:
			case 7:
			case 8:
			case 10:
			case 12: {
				totalDays -= 31;
				break;
			}
			case 2: {
				if (isLeapYear) {
					totalDays -= 29;
				} else {
					totalDays -= 28;
				}
				break;
			}
			default:
				totalDays -= 30;
			}
			month++;
		}
		day = totalDays;
		System.out.print((timeZone < 0 ? "西" : "东") + timeZone + "区\t");
		System.out.print(year + "年" + month + "月" + day + "日\t");
		System.out.println(hour + "时" + minute + "分" + second + "秒");
	}
}




中间有些bug被大家发现了,在此谢谢各位~~

将计算年的部分
		while (totalDays > 365) {
			if (year % 100 == 0 && year % 400 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else if (year % 4 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else {
				isLeapYear = false;
				totalDays -= 365;
			}
			year++;
		}

改为
		while (totalDays > 364) {
			if (year % 400 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else if (year % 100 != 0 && year % 4 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else {
				isLeapYear = false;
				totalDays -= 365;
			}
			year++;
		}// 年



以及
		day = totalDays;

改为
		day = totalDays == 0 ? 1 : totalDays;// 日

就好了~~~



另外写了一个可以持续更新的类,方便测试(直接改系统时间就行)
public class CalcDateProperties implements Runnable {
	private long startTime = 0;
	private long timeTaken = 0;
	public static final int FPS = 1;

	public static void main(String[] args) {
		new Thread(new CalcDateProperties()).start();
	}

	@Override
	public void run() {
		while (true) {
			startTime = System.currentTimeMillis();
			showCurrentTime(8);
			timeTaken = System.currentTimeMillis() - startTime;
			if (timeTaken < 1000 / FPS) {
				try {
					Thread.sleep(1000 / FPS - timeTaken);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void showCurrentTime(int timeZone) {
		long timeMillis = System.currentTimeMillis();
		long totalSeconds = timeMillis / 1000;
		int second = (int) (totalSeconds % 60);// 秒

		long totalMinutes = totalSeconds / 60;
		int minute = (int) (totalMinutes % 60);// 分

		long totalHours = totalMinutes / 60;
		totalHours += timeZone;
		int hour = (int) (totalHours % 24);// 时

		int totalDays = (int) (totalHours / 24);

		int year = 1970;// 年
		int month = 1;// 月
		int day = 1;// 日
		boolean isLeapYear = false;// 闰年

		while (totalDays > 364) {
			if (year % 400 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else if (year % 100 != 0 && year % 4 == 0) {
				isLeapYear = true;
				totalDays -= 366;
			} else {
				isLeapYear = false;
				totalDays -= 365;
			}
			year++;
		}// 年

		while (totalDays > 30) {
			switch (month) {
			case 1:
			case 3:
			case 5:
			case 7:
			case 8:
			case 10:
			case 12: {
				totalDays -= 31;
				break;
			}
			case 2: {
				if (isLeapYear) {
					totalDays -= 29;
				} else {
					totalDays -= 28;
				}
				break;
			}
			default:
				totalDays -= 30;
			}
			month++;
		}// 月

		day = totalDays == 0 ? 1 : totalDays;// 日

		System.out.print((timeZone < 0 ? "西" : "东") + timeZone + "区\t");
		System.out.print(year + "年" + month + "月" + day + "日\t");
		System.out.println(hour + "时" + minute + "分" + second + "秒");
	}
}




泥泽啊泥泽,呵呵。
   发表时间:2012-04-24  
东8区 2012年4月24日 19时23分29秒
0 请登录后投票
   发表时间:2012-04-24  
有一种东西叫闰秒
0 请登录后投票
   发表时间:2012-04-24  
G_o_o 写道
有一种东西叫闰秒

貌似跟系统时间分秒不差,currentTimeMillis已经包含闰秒了吧?

电脑的是准确对时的。
0 请登录后投票
   发表时间:2012-04-25  
不错!考虑了闰年
0 请登录后投票
   发表时间:2012-04-25  
(year % 100 == 0 && year % 400 == 0)和(year % 400 == 0)有什么不一样的吗?
0 请登录后投票
   发表时间:2012-04-25  
LZ的闰年算法貌似不对
正确的闰年计算是能被4整除且不能被100整除或能被400整除
即(0 == year%400) || (0 == year%4 && 0 != year%100)
例如1900年就不是闰年,通过这里的算法是可以确认的
但是LZ的明显会进入”else if (year % 4 == 0)“的判断,并且最终认定为闰年,这是不对的。
LZ的算法之所以能得到正确的结果是因为现在年份很特别
可以推翻LZ算法的年份有1700,1800,1900,2100,2200等
从1970到2012年间不包含上面任何一年,故执行结果是正确,其实完全是巧合。
0 请登录后投票
   发表时间:2012-04-25  
虽说让楼下的看出问题了,但是还是考虑的很仔细的
0 请登录后投票
   发表时间:2012-04-25  
这种题考的就是这些细节吧, 不然真的没有实质性意义。
结果楼主还是一不小心中招了。
~~~
0 请登录后投票
   发表时间:2012-04-25  
时间在编程的时候还是挺有用的。我觉得挺不错的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics