Bootstrap

【笔试题】Java实现格式化 Unix 时间戳

以东八区时间为例,用Java语言实现。

法一:使用内置的SimpleDateFormat类和Date类

import java.text.SimpleDateFormat;
import java.util.Date;
public class timerT1{
    // 定义一个常量,用于格式化日期时间
    public static final String GSTIME = "yyyy-MM-dd HH:mm:ss";

    public static void main(String[] args) {
        // 获取当前系统时间的毫秒数
        long time = System.currentTimeMillis();

        // 使用当前时间的毫秒数创建一个Date对象
        Date date = new Date(time);

        // 创建一个SimpleDateFormat对象,用于格式化日期时间
        SimpleDateFormat format = new SimpleDateFormat(GSTIME);

        // 使用SimpleDateFormat对象将Date对象格式化为字符串
        String nowDateString = format.format(date);

        // 输出格式化后的日期时间字符串
        System.out.println(nowDateString);
    }

}

法二:手动实现

public class timerT2 {
    public static void main(String[] args) {
        // 获取当前Unix时间戳(秒)
       long unixTimestamp = System.currentTimeMillis() / 1000;
        int year = 1970;
        int secondsPerMinute = 60;
        int secondsPerHour = secondsPerMinute * 60;
        int secondsPerDay = secondsPerHour * 24;

        // 计算完整的年和剩余的Unix时间戳
        int daysInYear;
        while (true) {
            // 判断是否为闰年,并设置对应的天数
            daysInYear = isLeapYear(year) ? 366 : 365;
            // 如果当前Unix时间戳小于一年的秒数,跳出循环
            if (unixTimestamp < daysInYear * secondsPerDay) {
                break;
            }
            // 减去一年的秒数,继续循环判断下一年
            unixTimestamp -= daysInYear * secondsPerDay;
            year++;
        }

        // 计算日期
        int day = 1; // 直接从1开始,避免后续的day++
        while (unixTimestamp >= secondsPerDay) {
            unixTimestamp -= secondsPerDay;
            day++;
        }

        // 计算月份
        int month = 1;
        int daysInMonth;
        while (true) {
            // 获取当前月份的天数
            daysInMonth = daysInMonth(month, year);
            // 如果当前日期小于等于当前月份的天数,跳出循环
            if (day <= daysInMonth) {
                break;
            }
            // 减去当前月份的天数,继续循环判断下一个月
            day -= daysInMonth;
            month++;
        }

        // 计算小时、分钟和秒,并考虑时区差异
        long totalSeconds = unixTimestamp % secondsPerDay; // 只考虑一天的剩余时间
        totalSeconds += 8 * 3600; // 加上8小时的秒数,以转换为东八区时间
        int hours = (int) totalSeconds / 3600; // 将秒数转换为小时数
        int remainingMinutes = (int) ((totalSeconds % 3600) / 60); // 剩余的秒数转换为分钟数
        int remainingSeconds = (int) totalSeconds % 60; // 最后的秒数

        // 处理小时数超过24的情况
        if (hours >= 24) {
            hours -= 24; // 减去24小时,以回到当前天的时间范围内
            day++; // 日期加1,因为已经跨到了下一天
            // 注意:如果day超过了当月的天数,还需要进一步处理月份和年份的变化
            while (day > daysInMonth(month, year)) {
                day -= daysInMonth(month, year); // 减去当前月份的天数
                month++; // 月份加1
                if (month > 12) { // 如果月份超过了12,年份加1,月份回到1
                    month = 1;
                    year++;
                }
            }
        }

        // 输出结果
        System.out.printf("%d年%d月%d日%d时%d分%d秒%n", year, month, day, hours, remainingMinutes, remainingSeconds);
    }

    // 返回指定月份的天数
    static int daysInMonth(int month, int year) {
        // 使用switch语句根据月份来判断天数
        switch (month) {
            // 对于1月、3月、5月、7月、8月、10月和12月,每月有31天
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            // 对于4月、6月、9月和11月,每月有30天
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            // 对于2月,根据是否为闰年来判断天数
            case 2:
                // 如果是闰年,返回29天;否则返回28天
                return (isLeapYear(year)) ? 29 : 28;
            // 如果月份不在1到12的范围内,返回0表示错误
            default:
                return 0;
        }
    }


    // 判断是否为闰年
    // 定义一个静态方法,接收一个整型参数表示年份,返回一个布尔值表示是否为闰年
    static boolean isLeapYear(int year) {
        // 如果年份能被4整除且不能被100整除,或者年份能被400整除,则为闰年
        // 否则,不是闰年
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }

}

;