diff --git a/src/creature.cpp b/src/creature.cpp
index ad5bd25cb4c4a..2f1223cb13b71 100644
--- a/src/creature.cpp
+++ b/src/creature.cpp
@@ -1759,8 +1759,8 @@ void Creature::add_effect( const effect_source &source, const efftype_id &eff_id
 
         // Force intensity if it is duration based
         if( e.get_int_dur_factor() != 0_turns ) {
-            // + 1 here so that the lowest is intensity 1, not 0
-            e.set_intensity( e.get_duration() / e.get_int_dur_factor() + 1 );
+            const int intensity = std::ceil( e.get_duration() / e.get_int_dur_factor() );
+            e.set_intensity( std::max( 1, intensity ) );
         }
         // Bound new effect intensity by [1, max intensity]
         if( e.get_intensity() < 1 ) {
diff --git a/src/effect.cpp b/src/effect.cpp
index a2181aa3dd748..56d792c769ce7 100644
--- a/src/effect.cpp
+++ b/src/effect.cpp
@@ -1083,8 +1083,8 @@ void effect::set_duration( const time_duration &dur, bool alert )
 
     // Force intensity if it is duration based
     if( eff_type->int_dur_factor != 0_turns ) {
-        // + 1 here so that the lowest is intensity 1, not 0
-        set_intensity( duration / eff_type->int_dur_factor + 1, alert );
+        const int intensity = std::ceil( duration / eff_type->int_dur_factor );
+        set_intensity( std::max( 1, intensity ), alert );
     }
 
     add_msg_debug( debugmode::DF_EFFECT, "ID: %s, Duration %s", get_id().c_str(),
diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp
index aa300e3a11693..bb773fe8587ee 100644
--- a/src/iuse_actor.cpp
+++ b/src/iuse_actor.cpp
@@ -3588,19 +3588,19 @@ int heal_actor::finish_using( Character &healer, Character &patient, item &it,
 
     // apply healing over time effects
     if( bandages_power > 0 ) {
-        int bandages_intensity = get_bandaged_level( healer );
+        int bandages_intensity = std::max( 1, get_bandaged_level( healer ) );
         patient.add_effect( effect_bandaged, 1_turns, healed );
         effect &e = patient.get_effect( effect_bandaged, healed );
-        e.set_duration( e.get_int_dur_factor() * ( bandages_intensity + 0.5f ) );
+        e.set_duration( e.get_int_dur_factor() * bandages_intensity );
         patient.set_part_damage_bandaged( healed,
                                           patient.get_part_hp_max( healed ) - patient.get_part_hp_cur( healed ) );
         practice_amount += 2 * bandages_intensity;
     }
     if( disinfectant_power > 0 ) {
-        int disinfectant_intensity = get_disinfected_level( healer );
+        int disinfectant_intensity = std::max( 1, get_disinfected_level( healer ) );
         patient.add_effect( effect_disinfected, 1_turns, healed );
         effect &e = patient.get_effect( effect_disinfected, healed );
-        e.set_duration( e.get_int_dur_factor() * ( disinfectant_intensity + 0.5f ) );
+        e.set_duration( e.get_int_dur_factor() * disinfectant_intensity );
         patient.set_part_damage_disinfected( healed,
                                              patient.get_part_hp_max( healed ) - patient.get_part_hp_cur( healed ) );
         practice_amount += 2 * disinfectant_intensity;
diff --git a/tests/effect_test.cpp b/tests/effect_test.cpp
index aba6c896e741d..d010d3eb6a601 100644
--- a/tests/effect_test.cpp
+++ b/tests/effect_test.cpp
@@ -111,12 +111,12 @@ TEST_CASE( "effect_duration", "[effect][duration]" )
     //
     // "id": "drunk",
     // "name": [ "Tipsy", "Drunk", "Trashed", "Wasted" ],
-    // "max_intensity": 4,
+    // "max_intensity": 3,
     // "apply_message": "You feel lightheaded.",
     // "int_dur_factor": 1000,
     //
     // It has "int_dur_factor": 1000, meaning that its intensity will always be equal to its duration /
-    // 1000 rounded up, and it has "max_intensity": 4 meaning the highest its intensity will go is 4 at
+    // 1000 rounded up, and it has "max_intensity": 3 meaning the highest its intensity will go is 3 at
     // a duration of 3000 or higher.
     SECTION( "set_duration modifies intensity if effect is duration-based" ) {
         effect eff_intense( effect_source::empty(), &effect_intensified.obj(), 1_turns, body_part_bp_null,
@@ -127,17 +127,25 @@ TEST_CASE( "effect_duration", "[effect][duration]" )
         eff_intense.set_duration( 0_seconds );
         CHECK( eff_intense.get_intensity() == 1 );
 
-        // At duration == int_dur_factor, intensity is 2
+        // At duration == int_dur_factor, intensity is 1
         eff_intense.set_duration( 1_minutes );
-        CHECK( eff_intense.get_intensity() == 2 );
+        CHECK( eff_intense.get_intensity() == 1 );
 
-        // At duration == 2 * int_dur_factor, intensity is 3
+        // At duration == 2 * int_dur_factor, intensity is 2
         eff_intense.set_duration( 2_minutes );
+        CHECK( eff_intense.get_intensity() == 2 );
+
+        // At duration == (2m1s) * int_dur_factor, intensity is 3 (rounds up)
+        eff_intense.set_duration( 2_minutes + 1_seconds );
         CHECK( eff_intense.get_intensity() == 3 );
 
         // At duration == 3 * int_dur_factor, intensity is still 3
         eff_intense.set_duration( 3_minutes );
         CHECK( eff_intense.get_intensity() == 3 );
+
+        // At duration == 4 * int_dur_factor, intensity is still 3
+        eff_intense.set_duration( 4_minutes );
+        CHECK( eff_intense.get_intensity() == 3 );
     }
 }