{"record":{"id":"d9f07928cec6b076","repo":"Blankj/AndroidUtilCode","slug":"u-can-t-instantiate-me-d9f079","errorCode":null,"errorMessage":"u can't instantiate me...","messagePattern":"u can't instantiate me\\.\\.\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java","lineNumber":69,"sourceCode":"            return android.provider.Settings.System.getInt(Utils.getApp().getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0) == 1;\n        }\n    }\n    \n\n    @SuppressLint(\"SimpleDateFormat\")\n    public static SimpleDateFormat getSafeDateFormat(String pattern) {\n        Map<String, SimpleDateFormat> sdfMap = SDF_THREAD_LOCAL.get();\n        //noinspection ConstantConditions\n        SimpleDateFormat simpleDateFormat = sdfMap.get(pattern);\n        if (simpleDateFormat == null) {\n            simpleDateFormat = new SimpleDateFormat(pattern);\n            sdfMap.put(pattern, simpleDateFormat);\n        }\n        return simpleDateFormat;\n    }\n\n    private TimeUtils() {\n        throw new UnsupportedOperationException(\"u can't instantiate me...\");\n    }\n\n    /**\n     * Milliseconds to the formatted time string.\n     * <p>The pattern is {@code yyyy-MM-dd HH:mm:ss}.</p>\n     *\n     * @param millis The milliseconds.\n     * @return the formatted time string\n     */\n    public static String millis2String(final long millis) {\n        return millis2String(millis, getDefaultFormat());\n    }\n\n    /**\n     * Milliseconds to the formatted time string.\n     *\n     * @param millis  The milliseconds.\n     * @param pattern The pattern of date format, such as yyyy/MM/dd HH:mm","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java#L51-L87","documentation":"TimeUtils is a final static-only utility for date/time formatting and conversion, backed by a thread-local SimpleDateFormat cache. Its private constructor throws UnsupportedOperationException to prevent instantiation. All public methods (millis2String, getSafeDateFormat, etc.) are static.","triggerScenarios":"Reflective instantiation via TimeUtils.class.getDeclaredConstructor().setAccessible(true).newInstance(), or transitively via Gson/Jackson deserialization, Mockito/PowerMock, Kotlin reflection, or a DI classpath scan.","commonSituations":"JSON mapping a field to TimeUtils; test frameworks mocking date utilities; coverage probes; accidental construction after weakening access modifiers.","solutions":["Use static methods: TimeUtils.millis2String(millis) or TimeUtils.getSafeDateFormat(pattern) instead of constructing.","Provide a Gson InstanceCreator / Jackson mixin returning a sentinel to avoid constructor invocation.","Mock static methods with Mockito.mockStatic rather than constructing TimeUtils.","Keep the class final with a private constructor."],"exampleFix":"// before\nTimeUtils tu = new TimeUtils();\n\n// after\nString s = TimeUtils.millis2String(System.currentTimeMillis());","handlingStrategy":"validation","validationCode":"if (Modifier.isFinal(TimeUtils.class.getModifiers())) {\n  throw new IllegalStateException(\"TimeUtils is static-only.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call TimeUtils.millis2String(...) statically.","Register InstanceCreator/mixin for JSON fields typed as TimeUtils.","Use Mockito.mockStatic for mocking.","Keep final + private constructor."],"tags":["android","utility-class","reflection","instantiation","time"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}