【Java】有关System.currentTimeMillis()的思考

本文介绍如何在Java中获取精确到毫秒的时间戳,并解释了为何大多数编程语言选择1970年1月1日作为时间原点的历史背景。此外,文章还探讨了32位系统中可能出现的2038年问题及其潜在影响。

在Java中无须引入任何类利用System.currentTimeMillis()能够轻松地取出1970年1月1日到现在的毫秒数,利用它能够轻松产生时间戳,甚至import java.text.SimpleDateFormat; import java.util.Date;之后配合new SimpleDateFormat("yyyy年MM月dd日hh:mm:ss E").format(new Date(System.currentTimeMillis())).toString();能够清楚输出当前的系统的年月日时分秒星期几。比如:

import java.text.SimpleDateFormat;
import java.util.Date;

public class JavaDate {
	public static void main(String[] args) {
		System.out.println(new SimpleDateFormat("yyyy年MM月dd日hh:mm:ss E").format(new Date(System.currentTimeMillis())).toString());
	}
}

运行结果就是当前系统的时间,如:2015年02月05日11:32:58 星期四

其中表示月的MM必须大写,区分表示分的mm

相信很多人都会了。

不仅是Java,很多编程语言都以1970年1月1日作为原点,这里面有个故事:1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNIX,新版于1971年发布。那时的计算机操作系统是32位,时间用32位有符号数表示,则可表示 68 年,用32位无符号数表示,可表示136年。他们认为以1970年为时间原点足够可以了。 因此,C的time函数就这么定了,后来的java等也用它,微机也用它,工作站本来就是unix系统当然也用它。由于主流计算机和操作系统都用它,其他仪器,手机等也就用它了。

然而System.currentTimeMillis()的返回值为Long,问题就来了,Long是有长度的,它只能代表一个长达32位的毫秒数,1970年1月1日逝去2G毫秒,也就是2147483647毫秒之后是2038年1月19日星期二晚上03:14:07。正如IP4的地址居然用尽一样,当时的科学家根本就没有想到计算机系统的普及率在今天觉得几乎人手几台一样,他们也没想到到了2038年1月19日星期二晚上03:14:07人们还会对智能系统进行研究,计算机居然不会淘汰,而是成为了必需品!

和本世纪初的千年虫(Y2K Bug)问题类似,计算机系统千年虫问题又称为2038年问题(Y2K38 BUG)。2038年问题不仅比千年虫更隐蔽,而且比之前千年虫问题更具有破坏力,因为千年虫问题只会导致应用层的程序出现问题,比如信用卡支付系统,或者管理系统。而2038这个bug,将会影响系统最底层的时间控制的功能。当时千年虫问题,已经困扰了很多部门了,不过最后把所有用00表示的时间,改成四位数字就可以了,但是2038年问题,必须改变内部表示时间控制的长度问题,可是现在推广64系统困难,中国大部分系统还是在WinXp的现状,先别说用户了,你让程序猿写出来的软件能够不兼容IE6,WINXP再说……更不要说64位机器了,很多电脑现在还不过是Win7 32位罢了!

import java.util.HashSet; import java.util.Set; public class AttendanceSystem { private Set<Integer> checkedInEmployees; public AttendanceSystem() { this.checkedInEmployees = new HashSet<>(); } // 打卡方法 public boolean checkIn(int employeeId) { if (checkedInEmployees.contains(employeeId)) { return false; // 已打卡,打卡失败 } checkedInEmployees.add(employeeId); return true; // 打卡成功 } // 查询是否已打卡 public boolean hasCheckedIn(int employeeId) { return checkedInEmployees.contains(employeeId); } // 获取打卡总人数 public int getCheckInCount() { return checkedInEmployees.size(); } // 获取所有打卡员工 public Set<Integer> getAllCheckedInEmployees() { return new HashSet<>(checkedInEmployees); } // 测试方法 public static void main(String[] args) { AttendanceSystem system = new AttendanceSystem(); // 正常打卡 System.out.println("1001打卡: " + system.checkIn(1001)); // true System.out.println("1002打卡: " + system.checkIn(1002)); // true // 重复打卡 System.out.println("1001重复打卡: " + system.checkIn(1001)); // false // 查询打卡状态 System.out.println("1001是否打卡: " + system.hasCheckedIn(1001)); // true System.out.println("1003是否打卡: " + system.hasCheckedIn(1003)); // false System.out.println("总打卡人数: " + system.getCheckInCount()); // 2 System.out.println("所有打卡员工: " + system.getAllCheckedInEmployees()); } } // 改进版本:记录打卡时间 import java.util.HashMap; import java.util.Map; import java.time.LocalDateTime; class AdvancedAttendanceSystem { private Map<Integer, LocalDateTime> checkInRecords; public AdvancedAttendanceSystem() { this.checkInRecords = new HashMap<>(); } public boolean checkIn(int employeeId) { if (checkInRecords.containsKey(employeeId)) { return false; } checkInRecords.put(employeeId, LocalDateTime.now()); return true; } public LocalDateTime getCheckInTime(int employeeId) { return checkInRecords.get(employeeId); } public boolean hasCheckedIn(int employeeId) { return checkInRecords.containsKey(employeeId); } public int getCheckInCount() { return checkInRecords.size(); } }为什么这里用的set(HashSet - 去重与存在性判断) 业务场景:某公司需要记录每日打卡的员工工号,工号为整数,要求确保每个工号当天只记录一次(去 重),并能快速判断某员工是否已打卡。要求: 1. 使用 HashSet 存储工号(Integer 类型) 2. 实现打卡方法(checkIn,返回是否成功打卡,已打卡则返回 false) 3. 实现查询方法(hasCheckedIn,返回指定工号是否已打卡) 4. 实现获取当日打卡总人数的方法(getCheckInCount) 5. 思考:如果需要同时记录打卡时间,该如何改进数据结构*/题目要求的是hashset
最新发布
10-02
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值