Java SimpleDateFormat表达式的坑

今天是2019年12月30日,登录我们线上服务器,发现日志变成了"localhost_access_log.2020-12-30.log",整整差了一年。所有根据该日志的监控图都废了,心里很慌,赶紧debug排查,发现了SimpleDateFormat 坑。
先说一下我们的环境:springboot2.1.7 && 内置tomcat 9.0.22,并且为tomcat配置了access日志,具体配置如下

server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=********
server.tomcat.accesslog.prefix=localhost_access_log
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.file-date-format=.YYYY-MM-dd
server.tomcat.accesslog.rotate=true
server.tomcat.accesslog.directory=logs
server.tomcat.basedir=./

线上日志截图
在这里插入图片描述根据日志,一路debug tomcat初始化应用,结果发现AccessLogValve中的

    @Override
    protected synchronized void startInternal() throws LifecycleException {

        // Initialize the Date formatters
        String format = getFileDateFormat();
        fileDateFormatter = new SimpleDateFormat(format, Locale.US);
        fileDateFormatter.setTimeZone(TimeZone.getDefault());
        dateStamp = fileDateFormatter.format(new Date(System.currentTimeMillis())); // **出问题的地方**
        if (rotatable && renameOnRotate) {
            restore();
        }
        open();

        super.startInternal();
    }

然后手动写了测试类,问题重现了

public static void main(String[] args) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd", Locale.US);
        long time = System.currentTimeMillis();
        time = 1577601170000l; // 2019-12-29 14:32:50
        String dateStamp = simpleDateFormat.format(new Date(time));
        System.out.println(dateStamp);
    }

在这里插入图片描述后来看了一下jdk官网发现,是时间格式化的表达式有问题
在这里插入图片描述上图有两个Year 和 Week year。Year就是正常日历上的年份,后者参考官方文档。简单来说,2019年12月30日,正好是2020 Week-year的第一周第一天。因此"YYYY"的结果是2019。
将代码修改一下,SimpleDateFormat df = new SimpleDateFormat(".yyyy.MM.dd");后,就能得到正确的结果了,
类似的还有"D"和"d"。因此大多数情况下都应该要选用"y"和"d".
如下:

public static void main(String[] args) {
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd", Locale.US);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
        long time = System.currentTimeMillis();
        time = 1577601170000l; // 2019-12-29 14:32:50
        String dateStamp = simpleDateFormat.format(new Date(time));
        System.out.println(dateStamp);
    }

在这里插入图片描述这个细节平时都没有关注,还好今天只是出现在日志名字上,否则影响无法评估了

猜你喜欢

转载自blog.csdn.net/jerry_player/article/details/103766677