diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.html index e052308af3d..13162ad7891 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.html +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.html @@ -1,33 +1,59 @@ -

Using 32-bit signed integer types for timestamps can lead to serious reliability issues such as incorrect time representation, -system failures, and the Year 2038 problem.

+

This is an issue when a smaller integer type value is widened to a larger integer type and then used as an absolute timestamp, such as milliseconds +or seconds since the Unix epoch (January 1, 1970).

Why is this an issue?

-

A 32-bit signed integer can hold values from -2,147,483,648 to 2,147,483,647. While this might seem like a large range, it's insufficient for +

A 32-bit signed integer can hold values from -2,147,483,648 to 2,147,483,647. While this might seem like a large range, it’s insufficient for representing timestamps:

-

When you cast a 32-bit integer to a 64-bit integer for use as a timestamp, you're not fixing the underlying problem — the value is already -corrupted or limited by the 32-bit constraint before the cast happens.

-

Noncompliant code example

+

When you cast a 32-bit integer to a 64-bit integer for use as a timestamp, you’re not fixing the underlying problem — the value is already +corrupted or limited by the 32-bit constraint before the cast happens. The cast simply preserves the incorrect or overflowed value in a larger +container.

+

Timestamps should be stored as 64-bit integer values from the start to ensure they can represent dates far into the past and future without +overflow. A 64-bit integer type can represent timestamps for approximately 292 million years, which is more than sufficient for any practical +application.

+

Using a 32-bit integer for timestamps is almost always a bug that will cause:

+ +

In Java, 32-bit integers are represented by the int type and 64-bit integers by the long type.

+

What is the potential impact?

+

Using 32-bit signed integer types for timestamps can lead to serious reliability issues:

+ +

How to fix it

+

Change the variable type from int to long to properly represent the timestamp. This ensures the value can hold the full +range of possible timestamp values without overflow.

+

Code examples

+

Noncompliant code example

 int timestamp = 1234567890;
-Date date = new Date(timestamp);          // Noncompliant — int implicitly widened
-Date date2 = new Date((long) timestamp);  // Noncompliant — cast doesn't fix overflow
+long epochMillis = (long) timestamp; // Noncompliant
+Date date = new Date(epochMillis);
 
-

Compliant solution

+

Compliant solution

 long timestamp = 1234567890L;
-Date date = new Date(timestamp);
-Date date2 = new Date(timestamp);
+long epochMillis = timestamp;
+Date date = new Date(epochMillis);
 

Resources

Documentation

+ diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.json index 094457c0313..5c9521c8715 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.json @@ -1,21 +1,24 @@ { "title": "Integer values should not be cast to long for use as timestamps", "type": "BUG", - "code": { - "impacts": { - "RELIABILITY": "HIGH" - }, - "attribute": "LOGICAL" - }, "status": "ready", "remediation": { "func": "Constant\/Issue", - "constantCost": "5min" + "constantCost": "5 min" }, - "tags": ["pitfall", "datetime"], + "tags": [ + "pitfall", + "datetime" + ], "defaultSeverity": "Critical", "ruleSpecification": "RSPEC-9346", "sqKey": "S9346", - "scope": "All", - "quickfix": "unknown" + "scope": "Main", + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } }