Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions rules/S8228/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"title": "Time calculations should use TimeUnit or Duration instead of magic numbers",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant/Issue",
"constantCost": "5 min"
},
"tags": [
"readability",
"time"
],
"defaultSeverity": "Blocker",
"ruleSpecification": "RSPEC-8228",
"sqKey": "S8228",
"scope": "Main",
"defaultQualityProfiles": [
"Sonar way"
],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "BLOCKER"
},
"attribute": "CLEAR"
}
}
49 changes: 49 additions & 0 deletions rules/S8228/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
This rule raises an issue when manual time calculations use time-related constants like 1000 (milliseconds per second), 60 (seconds per minute), 3600 (seconds per hour), or 86400 (seconds per day) instead of Java's built-in time utilities.

== Why is this an issue?

Manual time calculations with constants like `1000`, `60`, `3600`, and `86400` are not self-documenting. Seeing `duration * 60 * 1000` requires mental calculation to understand it converts minutes to milliseconds. These calculations are also error-prone - it's easy to forget a zero or use the wrong conversion factor.

Java provides built-in utilities specifically for time operations:

* The `TimeUnit` enum offers methods like `toMillis()`, `toSeconds()`, and `convert()`
* The `Duration` class provides similar functionality with a modern API
* The `ChronoUnit` enum is available for advanced time operations

These utilities make your intent clear. `TimeUnit.MINUTES.toMillis(duration)` immediately shows you're converting minutes to milliseconds, eliminating mental math and calculation errors.

=== What is the potential impact?

Using time-related constants in manual calculations reduces code readability and increases the risk of bugs. Calculation errors in time-sensitive code can lead to incorrect timeouts, scheduling issues, or performance problems in production systems.

== How to fix it

Replace manual time calculations with TimeUnit enum methods. Use `toMillis()`, `toSeconds()`, or other conversion methods to make your intent clear.

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
int minutes = 15;
long millis = minutes * 60 * 1000; // Noncompliant
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
int minutes = 15;
long millis = TimeUnit.MINUTES.toMillis(minutes);
----

== Resources

=== Documentation

* TimeUnit (Java SE 17 & JDK 17) - https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/TimeUnit.html[Official documentation for the TimeUnit enum with conversion methods]

* Duration (Java SE 17 & JDK 17) - https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Official documentation for the Duration class in the java.time package]

* ChronoUnit (Java SE 17 & JDK 17) - https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/temporal/ChronoUnit.html[Official documentation for ChronoUnit enum for advanced time operations]
2 changes: 2 additions & 0 deletions rules/S8228/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}