国际化项目开发中关于时间的问题二

为什么没有传入指定时区情况下new Date会正确显示当地时间

Date date = new Date();
log.info(date.toString())

默认构造方法
public Date() {
	this(System.currentTimeMillis());
}

public Date(long date) {
	fastTime = date;
}

System.currentTimeMillis()是jvm通过c语言实现的获取UTC时间戳的方法,看到这里还是没看到时区,继续往下看.
我们是通过toString()打印当地时间信息的,我们看代码

    public String toString() {
        // "EEE MMM dd HH:mm:ss zzz yyyy";
        BaseCalendar.Date date = normalize();
        StringBuilder sb = new StringBuilder(28);
        int index = date.getDayOfWeek();
        if (index == BaseCalendar.SUNDAY) {
            index = 8;
        }
        convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
        convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
        CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

        CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
        CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
        CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
        TimeZone zi = date.getZone();
        if (zi != null) {
            sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
        } else {
            sb.append("GMT");
        }
        sb.append(' ').append(date.getYear());  // yyyy
        return sb.toString();
    }

继续看normalize方法

    private final BaseCalendar.Date normalize() {
        if (cdate == null) {
            BaseCalendar cal = getCalendarSystem(fastTime);
            cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
                                                            TimeZone.getDefaultRef());
            return cdate;
        }

        // Normalize cdate with the TimeZone in cdate first. This is
        // required for the compatible behavior.
        if (!cdate.isNormalized()) {
            cdate = normalize(cdate);
        }

        // If the default TimeZone has changed, then recalculate the
        // fields with the new TimeZone.
        TimeZone tz = TimeZone.getDefaultRef();
        if (tz != cdate.getZone()) {
            cdate.setZone(tz);
            CalendarSystem cal = getCalendarSystem(cdate);
            cal.getCalendarDate(fastTime, cdate);
        }
        return cdate;
    }

TimeZone.getDefaultRef()方法返回时区,继续看

	static TimeZone getDefaultRef() {
		TimeZone defaultZone = defaultTimeZone;
		if (defaultZone == null) {
			// Need to initialize the default time zone.
			defaultZone = setDefaultZone();
			assert defaultZone != null;
		}
		// Don't clone here.
		return defaultZone;
    }

setDefaultZone方法

	private static synchronized TimeZone setDefaultZone() {
        TimeZone tz;
        // get the time zone ID from the system properties
        String zoneID = AccessController.doPrivileged(
                new GetPropertyAction("user.timezone"));

        // if the time zone ID is not set (yet), perform the
        // platform to Java time zone ID mapping.
        if (zoneID == null || zoneID.isEmpty()) {
            String javaHome = AccessController.doPrivileged(
                    new GetPropertyAction("java.home"));
            try {
                zoneID = getSystemTimeZoneID(javaHome);
                if (zoneID == null) {
                    zoneID = GMT_ID;
                }
            } catch (NullPointerException e) {
                zoneID = GMT_ID;
            }
        }

        // Get the time zone for zoneID. But not fall back to
        // "GMT" here.
        tz = getTimeZone(zoneID, false);

        if (tz == null) {
            // If the given zone ID is unknown in Java, try to
            // get the GMT-offset-based time zone ID,
            // a.k.a. custom time zone ID (e.g., "GMT-08:00").
            String gmtOffsetID = getSystemGMTOffsetID();
            if (gmtOffsetID != null) {
                zoneID = gmtOffsetID;
            }
            tz = getTimeZone(zoneID, true);
        }
        assert tz != null;

        final String id = zoneID;
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            @Override
                public Void run() {
                    System.setProperty("user.timezone", id);
                    return null;
                }
            });

        defaultTimeZone = tz;
        return tz;
    }

最终看到通过jvm系统属性user.timezone获取当前时区,并结合时间戳,转换为当地正确的时间

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-18 03:06:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-18 03:06:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-18 03:06:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-18 03:06:02       18 阅读

热门阅读

  1. Linux知识汇总

    2024-06-18 03:06:02       6 阅读
  2. Flink集群运行模式

    2024-06-18 03:06:02       8 阅读
  3. 617作业

    617作业

    2024-06-18 03:06:02      7 阅读
  4. k8s_DaemonSet和Deployment区别

    2024-06-18 03:06:02       10 阅读
  5. 细说MCU定时器中断的实现方法

    2024-06-18 03:06:02       8 阅读
  6. webpack之HMR

    2024-06-18 03:06:02       6 阅读
  7. kali - 配置静态网络地址 + ssh 远程连接

    2024-06-18 03:06:02       5 阅读
  8. 【Prometheus】自动化效率脚本

    2024-06-18 03:06:02       6 阅读